Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/NumberPtg.java Sun Dec 22 21:44:45 2019 @@ -24,9 +24,6 @@ import org.apache.poi.util.LittleEndianO /** * Number Stores a floating point value in a formula value stored in a 8 byte * field using IEEE notation - * - * @author Avik Sengupta - * @author Jason Height (jheight at chariot dot net dot au) */ public final class NumberPtg extends ScalarConstantPtg { public final static int SIZE = 9; @@ -41,7 +38,7 @@ public final class NumberPtg extends Sca * Create a NumberPtg from a string representation of the number Number * format is not checked, it is expected to be validated in the parser that * calls this method. - * + * * @param value String representation of a floating point number */ public NumberPtg(String value) { @@ -68,4 +65,9 @@ public final class NumberPtg extends Sca public String toFormulaString() { return NumberToTextConverter.toText(field_1_value); } + + @Override + public NumberPtg copy() { + return this; + } }
Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/OperandPtg.java Sun Dec 22 21:44:45 2019 @@ -17,10 +17,13 @@ package org.apache.poi.ss.formula.ptg; -/** - * @author Josh Micich - */ -public abstract class OperandPtg extends Ptg implements Cloneable { +public abstract class OperandPtg extends Ptg { + + protected OperandPtg() {} + + protected OperandPtg(OperandPtg other) { + super(other); + } /** * All Operand {@link Ptg}s are classified ('relative', 'value', 'array') @@ -28,11 +31,7 @@ public abstract class OperandPtg extends public final boolean isBaseToken() { return false; } - public final OperandPtg copy() { - try { - return (OperandPtg) clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } + + @Override + public abstract OperandPtg copy(); } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/OperationPtg.java Sun Dec 22 21:44:45 2019 @@ -26,19 +26,21 @@ public abstract class OperationPtg exten public final static int TYPE_BINARY = 1; public final static int TYPE_FUNCTION = 2; + protected OperationPtg() {} + /** * returns a string representation of the operations - * the length of the input array should equal the number returned by + * the length of the input array should equal the number returned by * @see #getNumberOfOperands - * + * */ public abstract String toFormulaString(String[] operands); - + /** * The number of operands expected by the operations */ public abstract int getNumberOfOperands(); - + public byte getDefaultOperandClass() { return Ptg.CLASS_VALUE; } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ParenthesisPtg.java Sun Dec 22 21:44:45 2019 @@ -23,18 +23,13 @@ import org.apache.poi.util.LittleEndianO * While formula tokens are stored in RPN order and thus do not need parenthesis * for precedence reasons, Parenthesis tokens ARE written to ensure that user * entered parenthesis are displayed as-is on reading back - * - * Avik Sengupta <li...@aviksengupta.com> Andrew C. Oliver (acoliver at - * apache dot org) - * - * @author Jason Height (jheight at chariot dot net dot au) */ public final class ParenthesisPtg extends ControlPtg { private final static int SIZE = 1; public final static byte sid = 0x15; - public static final ControlPtg instance = new ParenthesisPtg(); + public static final ParenthesisPtg instance = new ParenthesisPtg(); private ParenthesisPtg() { // enforce singleton @@ -55,4 +50,9 @@ public final class ParenthesisPtg extend public String toFormulaString(String[] operands) { return "(" + operands[0] + ")"; } + + @Override + public ParenthesisPtg copy() { + return instance; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/PercentPtg.java Sun Dec 22 21:44:45 2019 @@ -19,21 +19,19 @@ package org.apache.poi.ss.formula.ptg; /** * Percent PTG. - * - * @author Daniel Noll (daniel at nuix.com.au) */ public final class PercentPtg extends ValueOperatorPtg { public final static int SIZE = 1; public final static byte sid = 0x14; - + private final static String PERCENT = "%"; - public static final ValueOperatorPtg instance = new PercentPtg(); + public static final PercentPtg instance = new PercentPtg(); private PercentPtg() { // enforce singleton } - + protected byte getSid() { return sid; } @@ -41,7 +39,7 @@ public final class PercentPtg extends Va public int getNumberOfOperands() { return 1; } - + public String toFormulaString(String[] operands) { StringBuilder buffer = new StringBuilder(); @@ -49,4 +47,9 @@ public final class PercentPtg extends Va buffer.append(PERCENT); return buffer.toString(); } + + @Override + public PercentPtg copy() { + return instance; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/PowerPtg.java Sun Dec 22 21:44:45 2019 @@ -17,20 +17,15 @@ package org.apache.poi.ss.formula.ptg; -/** - * - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ public final class PowerPtg extends ValueOperatorPtg { public final static byte sid = 0x07; - public static final ValueOperatorPtg instance = new PowerPtg(); + public static final PowerPtg instance = new PowerPtg(); private PowerPtg() { // enforce singleton } - + protected byte getSid() { return sid; } @@ -38,14 +33,19 @@ public final class PowerPtg extends Valu public int getNumberOfOperands() { return 2; // TODO - 2 seems wrong (Jun 2008). Maybe this method is not relevant } - + public String toFormulaString(String[] operands) { StringBuilder buffer = new StringBuilder(); - + buffer.append(operands[ 0 ]); buffer.append("^"); buffer.append(operands[ 1 ]); return buffer.toString(); - } + } + + @Override + public PowerPtg copy() { + return instance; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ptg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ptg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ptg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ptg.java Sun Dec 22 21:44:45 2019 @@ -20,6 +20,7 @@ package org.apache.poi.ss.formula.ptg; import java.util.ArrayList; import java.util.List; +import org.apache.poi.common.Duplicatable; import org.apache.poi.util.LittleEndianByteArrayOutputStream; import org.apache.poi.util.LittleEndianInput; import org.apache.poi.util.LittleEndianOutput; @@ -36,9 +37,21 @@ import org.apache.poi.util.LittleEndianO * <em>Reverse-Polish Notation</em> order. The RPN ordering also simplifies formula * evaluation logic, so POI mostly accesses <tt>Ptg</tt>s in the same way. */ -public abstract class Ptg { +public abstract class Ptg implements Duplicatable { public static final Ptg[] EMPTY_PTG_ARRAY = { }; + public static final byte CLASS_REF = 0x00; + public static final byte CLASS_VALUE = 0x20; + public static final byte CLASS_ARRAY = 0x40; + + private byte ptgClass = CLASS_REF; //base ptg + + protected Ptg() {} + + protected Ptg(Ptg other) { + ptgClass = other.ptgClass; + } + /** * Reads <tt>size</tt> bytes of the input stream, to create an array of <tt>Ptg</tt>s. * Extra data (beyond <tt>size</tt>) may be read if and <tt>ArrayPtg</tt>s are present. @@ -199,7 +212,7 @@ public abstract class Ptg { */ public static int serializePtgs(Ptg[] ptgs, byte[] array, int offset) { LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(array, offset); // NOSONAR - + List<Ptg> arrayPtgs = null; for (Ptg ptg : ptgs) { @@ -241,12 +254,6 @@ public abstract class Ptg { return this.getClass().toString(); } - public static final byte CLASS_REF = 0x00; - public static final byte CLASS_VALUE = 0x20; - public static final byte CLASS_ARRAY = 0x40; - - private byte ptgClass = CLASS_REF; //base ptg - public final void setClass(byte thePtgClass) { if (isBaseToken()) { throw new RuntimeException("setClass should not be called on a base token"); @@ -311,4 +318,7 @@ public abstract class Ptg { } return false; } + + @Override + public abstract Ptg copy(); } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RangePtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RangePtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RangePtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RangePtg.java Sun Dec 22 21:44:45 2019 @@ -20,14 +20,11 @@ package org.apache.poi.ss.formula.ptg; import org.apache.poi.util.LittleEndianOutput; -/** - * @author Daniel Noll (daniel at nuix dot com dot au) - */ public final class RangePtg extends OperationPtg { public final static int SIZE = 1; public final static byte sid = 0x11; - public static final OperationPtg instance = new RangePtg(); + public static final RangePtg instance = new RangePtg(); private RangePtg() { // enforce singleton @@ -68,4 +65,8 @@ public final class RangePtg extends Ope return 2; } + @Override + public RangePtg copy() { + return instance; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref2DPtgBase.java Sun Dec 22 21:44:45 2019 @@ -21,13 +21,9 @@ import org.apache.poi.ss.util.CellRefere import org.apache.poi.util.LittleEndianInput; import org.apache.poi.util.LittleEndianOutput; -/** - * @author Josh Micich - */ abstract class Ref2DPtgBase extends RefPtgBase { private final static int SIZE = 5; - protected Ref2DPtgBase(int row, int column, boolean isRowRelative, boolean isColumnRelative) { setRow(row); setColumn(column); @@ -35,6 +31,11 @@ abstract class Ref2DPtgBase extends RefP setColRelative(isColumnRelative); } + protected Ref2DPtgBase(Ref2DPtgBase other) { + super(other); + } + + protected Ref2DPtgBase(LittleEndianInput in) { readCoordinates(in); } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPtg.java Sun Dec 22 21:44:45 2019 @@ -25,20 +25,23 @@ import org.apache.poi.util.LittleEndianI import org.apache.poi.util.LittleEndianOutput; /** - * <p>Title: Reference 3D Ptg</p> - * <p>Description: Defined a cell in extern sheet.</p> - * <p>REFERENCE: </p> - * - * <p>This is HSSF only, as it matches the HSSF file format way of - * referring to the sheet by an extern index. The XSSF equivalent - * is {@link Ref3DPxg} + * Reference 3D Ptg<p> + * Defined a cell in extern sheet.<p> + * + * This is HSSF only, as it matches the HSSF file format way of + * referring to the sheet by an extern index. The XSSF equivalent + * is {@link Ref3DPxg} */ public final class Ref3DPtg extends RefPtgBase implements WorkbookDependentFormula, ExternSheetReferenceToken { public final static byte sid = 0x3a; private final static int SIZE = 7; // 6 + 1 for Ptg - private int field_1_index_extern_sheet; + private int field_1_index_extern_sheet; + public Ref3DPtg(Ref3DPtg other) { + super(other); + field_1_index_extern_sheet = other.field_1_index_extern_sheet; + } public Ref3DPtg(LittleEndianInput in) { field_1_index_extern_sheet = in.readShort(); @@ -95,4 +98,9 @@ public final class Ref3DPtg extends RefP public String toFormulaString() { throw new RuntimeException("3D references need a workbook to determine formula text"); } + + @Override + public Ref3DPtg copy() { + return new Ref3DPtg(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/Ref3DPxg.java Sun Dec 22 21:44:45 2019 @@ -24,25 +24,31 @@ import org.apache.poi.ss.util.CellRefere import org.apache.poi.util.LittleEndianOutput; /** - * <p>Title: XSSF 3D Reference</p> - * <p>Description: Defines a cell in an external or different sheet.</p> - * <p>REFERENCE: </p> - * - * <p>This is XSSF only, as it stores the sheet / book references - * in String form. The HSSF equivalent using indexes is {@link Ref3DPtg}</p> + * XSSF 3D Reference<p> + * Defines a cell in an external or different sheet.<p> + * + * This is XSSF only, as it stores the sheet / book references + * in String form. The HSSF equivalent using indexes is {@link Ref3DPtg} */ public final class Ref3DPxg extends RefPtgBase implements Pxg3D { private int externalWorkbookNumber = -1; private String firstSheetName; private String lastSheetName; + public Ref3DPxg(Ref3DPxg other) { + super(other); + externalWorkbookNumber = other.externalWorkbookNumber; + firstSheetName = other.firstSheetName; + lastSheetName = other.lastSheetName; + } + public Ref3DPxg(int externalWorkbookNumber, SheetIdentifier sheetName, String cellref) { this(externalWorkbookNumber, sheetName, new CellReference(cellref)); } public Ref3DPxg(int externalWorkbookNumber, SheetIdentifier sheetName, CellReference c) { super(c); this.externalWorkbookNumber = externalWorkbookNumber; - + this.firstSheetName = sheetName.getSheetIdentifier().getName(); if (sheetName instanceof SheetRangeIdentifier) { this.lastSheetName = ((SheetRangeIdentifier)sheetName).getLastSheetIdentifier().getName(); @@ -50,7 +56,7 @@ public final class Ref3DPxg extends RefP this.lastSheetName = null; } } - + public Ref3DPxg(SheetIdentifier sheetName, String cellref) { this(sheetName, new CellReference(cellref)); } @@ -77,7 +83,7 @@ public final class Ref3DPxg extends RefP sb.append("]"); return sb.toString(); } - + public int getExternalWorkbookNumber() { return externalWorkbookNumber; } @@ -87,14 +93,14 @@ public final class Ref3DPxg extends RefP public String getLastSheetName() { return lastSheetName; } - + public void setSheetName(String sheetName) { this.firstSheetName = sheetName; } public void setLastSheetName(String sheetName) { this.lastSheetName = sheetName; } - + public String format2DRefAsString() { return formatReferenceAsString(); } @@ -107,11 +113,16 @@ public final class Ref3DPxg extends RefP sb.append(formatReferenceAsString()); return sb.toString(); } - + public int getSize() { return 1; } public void write(LittleEndianOutput out) { throw new IllegalStateException("XSSF-only Ptg, should not be serialised"); } + + @Override + public Ref3DPxg copy() { + return new Ref3DPxg(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefErrorPtg.java Sun Dec 22 21:44:45 2019 @@ -23,7 +23,6 @@ import org.apache.poi.util.LittleEndianO /** * RefError - handles deleted cell reference - * @author Jason Height (jheight at chariot dot net dot au) */ public final class RefErrorPtg extends OperandPtg { @@ -34,6 +33,12 @@ public final class RefErrorPtg extends O public RefErrorPtg() { field_1_reserved = 0; } + + public RefErrorPtg(RefErrorPtg other) { + super(other); + field_1_reserved = other.field_1_reserved; + } + public RefErrorPtg(LittleEndianInput in) { field_1_reserved = in.readInt(); } @@ -55,8 +60,13 @@ public final class RefErrorPtg extends O public String toFormulaString() { return FormulaError.REF.getString(); } - + public byte getDefaultOperandClass() { return Ptg.CLASS_REF; } + + @Override + public RefErrorPtg copy() { + return new RefErrorPtg(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefNPtg.java Sun Dec 22 21:44:45 2019 @@ -20,10 +20,6 @@ package org.apache.poi.ss.formula.ptg; import org.apache.poi.ss.util.CellReference; import org.apache.poi.util.LittleEndianInput; -/** - * RefNPtg - * @author Jason Height (jheight at apache dot com) - */ public final class RefNPtg extends Ref2DPtgBase { public final static byte sid = 0x2C; @@ -31,6 +27,10 @@ public final class RefNPtg extends Ref2D super(in); } + public RefNPtg(RefNPtg other) { + super(other); + } + protected byte getSid() { return sid; } @@ -44,13 +44,18 @@ public final class RefNPtg extends Ref2D } else { builder.append(getRow()+1); } - + if(isColRelative()) { builder.append(" ColOffset: ").append(getColumn()); } else { builder.append(CellReference.convertNumToColString(getColumn())); } - + return builder.toString(); } + + @Override + public RefNPtg copy() { + return new RefNPtg(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtg.java Sun Dec 22 21:44:45 2019 @@ -22,8 +22,6 @@ import org.apache.poi.util.LittleEndianI /** * ReferencePtg - handles references (such as A1, A2, IA4) - * @author Andrew C. Oliver (acoli...@apache.org) - * @author Jason Height (jheight at chariot dot net dot au) */ public final class RefPtg extends Ref2DPtgBase { public final static byte sid = 0x24; @@ -36,6 +34,10 @@ public final class RefPtg extends Ref2DP super(new CellReference(cellref)); } + public RefPtg(RefPtg other) { + super(other); + } + public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) { super(row, column, isRowRelative, isColumnRelative); } @@ -51,4 +53,9 @@ public final class RefPtg extends Ref2DP protected byte getSid() { return sid; } + + @Override + public RefPtg copy() { + return new RefPtg(this); + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/RefPtgBase.java Sun Dec 22 21:44:45 2019 @@ -25,12 +25,21 @@ import org.apache.poi.util.LittleEndianO /** * ReferencePtgBase - handles references (such as A1, A2, IA4) - * - * @author Andrew C. Oliver (acoli...@apache.org) - * @author Jason Height (jheight at chariot dot net dot au) */ public abstract class RefPtgBase extends OperandPtg { + /** + * YK: subclasses of RefPtgBase are used by the FormulaParser and FormulaEvaluator accross HSSF and XSSF. + * The bit mask should accommodate the maximum number of avaiable columns, i.e. 0x3FFF. + * + * @see org.apache.poi.ss.SpreadsheetVersion + */ + private static final BitField column = BitFieldFactory.getInstance(0x3FFF); + + private static final BitField rowRelative = BitFieldFactory.getInstance(0x8000); + private static final BitField colRelative = BitFieldFactory.getInstance(0x4000); + + /** The row index - zero based unsigned 16 bit value */ private int field_1_row; /** @@ -38,19 +47,13 @@ public abstract class RefPtgBase extends * 16 - isRowRelative - bit 15 - isColumnRelative */ private int field_2_col; - private static final BitField rowRelative = BitFieldFactory.getInstance(0x8000); - private static final BitField colRelative = BitFieldFactory.getInstance(0x4000); - /** - * YK: subclasses of RefPtgBase are used by the FormulaParser and FormulaEvaluator accross HSSF and XSSF. - * The bit mask should accommodate the maximum number of avaiable columns, i.e. 0x3FFF. - * - * @see org.apache.poi.ss.SpreadsheetVersion - */ - private static final BitField column = BitFieldFactory.getInstance(0x3FFF); + protected RefPtgBase() {} - protected RefPtgBase() { - // Required for clone methods + protected RefPtgBase(RefPtgBase other) { + super(other); + field_1_row = other.field_1_row; + field_2_col = other.field_2_col; } protected RefPtgBase(CellReference c) { Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ScalarConstantPtg.java Sun Dec 22 21:44:45 2019 @@ -19,9 +19,7 @@ package org.apache.poi.ss.formula.ptg; /** - * Common superclass of all {@link Ptg}s that represent simple constant values. - * - * @author Josh Micich + * Common superclass of all {@link Ptg Ptgs} that represent simple constant values. */ public abstract class ScalarConstantPtg extends Ptg { public final boolean isBaseToken() { @@ -39,4 +37,6 @@ public abstract class ScalarConstantPtg sb.append("]"); return sb.toString(); } + + } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/StringPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/StringPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/StringPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/StringPtg.java Sun Dec 22 21:44:45 2019 @@ -24,10 +24,6 @@ import org.apache.poi.util.StringUtil; /** * String Stores a String value in a formula value stored in the format * <length 2 bytes>char[] - * - * @author Werner Froidevaux - * @author Jason Height (jheight at chariot dot net dot au) - * @author Bernard Chesnoy */ public final class StringPtg extends ScalarConstantPtg { public final static byte sid = 0x17; @@ -56,7 +52,7 @@ public final class StringPtg extends Sca * Create a StringPtg from a string representation of the number Number * format is not checked, it is expected to be validated in the parser that * calls this method. - * + * * @param value : * String representation of a floating point number */ @@ -105,4 +101,9 @@ public final class StringPtg extends Sca sb.append(FORMULA_DELIMITER); return sb.toString(); } + + @Override + public StringPtg copy() { + return this; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/SubtractPtg.java Sun Dec 22 21:44:45 2019 @@ -17,20 +17,15 @@ package org.apache.poi.ss.formula.ptg; -/** - * - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ public final class SubtractPtg extends ValueOperatorPtg { public final static byte sid = 0x04; - public static final ValueOperatorPtg instance = new SubtractPtg(); + public static final SubtractPtg instance = new SubtractPtg(); private SubtractPtg() { // enforce singleton } - + protected byte getSid() { return sid; } @@ -38,7 +33,7 @@ public final class SubtractPtg extends V public int getNumberOfOperands() { return 2; } - + public String toFormulaString(String[] operands) { StringBuilder buffer = new StringBuilder(); @@ -47,4 +42,9 @@ public final class SubtractPtg extends V buffer.append(operands[ 1 ]); return buffer.toString(); } + + @Override + public SubtractPtg copy() { + return instance; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/TblPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/TblPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/TblPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/TblPtg.java Sun Dec 22 21:44:45 2019 @@ -37,6 +37,7 @@ import org.apache.poi.util.LittleEndianO public final class TblPtg extends ControlPtg { private final static int SIZE = 5; public final static short sid = 0x02; + /** The row number of the upper left corner */ private final int field_1_first_row; /** The column number of the upper left corner */ @@ -77,4 +78,10 @@ public final class TblPtg extends Contro buffer.append("top left col = ").append(getColumn()).append("\n"); return buffer.toString(); } + + @Override + public TblPtg copy() { + // immutable + return this; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryMinusPtg.java Sun Dec 22 21:44:45 2019 @@ -18,21 +18,19 @@ package org.apache.poi.ss.formula.ptg; /** - * Unary Plus operator - * does not have any effect on the operand - * @author Avik Sengupta + * Unary Plus operator - does not have any effect on the operand */ public final class UnaryMinusPtg extends ValueOperatorPtg { public final static byte sid = 0x13; - + private final static String MINUS = "-"; - public static final ValueOperatorPtg instance = new UnaryMinusPtg(); + public static final UnaryMinusPtg instance = new UnaryMinusPtg(); private UnaryMinusPtg() { // enforce singleton } - + protected byte getSid() { return sid; } @@ -40,12 +38,17 @@ public final class UnaryMinusPtg extends public int getNumberOfOperands() { return 1; } - - /** implementation of method from OperationsPtg*/ + + /** implementation of method from OperationsPtg*/ public String toFormulaString(String[] operands) { StringBuilder buffer = new StringBuilder(); buffer.append(MINUS); buffer.append(operands[ 0]); return buffer.toString(); } + + @Override + public UnaryMinusPtg copy() { + return instance; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnaryPlusPtg.java Sun Dec 22 21:44:45 2019 @@ -18,21 +18,19 @@ package org.apache.poi.ss.formula.ptg; /** - * Unary Plus operator - * does not have any effect on the operand - * @author Avik Sengupta + * Unary Plus operator - does not have any effect on the operand */ public final class UnaryPlusPtg extends ValueOperatorPtg { public final static byte sid = 0x12; - + private final static String ADD = "+"; - public static final ValueOperatorPtg instance = new UnaryPlusPtg(); + public static final UnaryPlusPtg instance = new UnaryPlusPtg(); private UnaryPlusPtg() { // enforce singleton } - + protected byte getSid() { return sid; } @@ -40,12 +38,17 @@ public final class UnaryPlusPtg extends public int getNumberOfOperands() { return 1; } - - /** implementation of method from OperationsPtg*/ + + /** implementation of method from OperationsPtg*/ public String toFormulaString(String[] operands) { StringBuilder buffer = new StringBuilder(); buffer.append(ADD); buffer.append(operands[ 0]); return buffer.toString(); } + + @Override + public UnaryPlusPtg copy() { + return instance; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnionPtg.java Sun Dec 22 21:44:45 2019 @@ -26,7 +26,7 @@ import org.apache.poi.util.LittleEndianO public final class UnionPtg extends OperationPtg { public final static byte sid = 0x10; - public static final OperationPtg instance = new UnionPtg(); + public static final UnionPtg instance = new UnionPtg(); private UnionPtg() { // enforce singleton @@ -67,4 +67,8 @@ public final class UnionPtg extends Oper return 2; } + @Override + public UnionPtg copy() { + return instance; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/UnknownPtg.java Sun Dec 22 21:44:45 2019 @@ -18,10 +18,6 @@ package org.apache.poi.ss.formula.ptg; import org.apache.poi.util.LittleEndianOutput; -/** - * @author andy - * @author Jason Height (jheight at chariot dot net dot au) - */ public class UnknownPtg extends Ptg { private short size = 1; private final int _sid; @@ -47,4 +43,9 @@ public class UnknownPtg extends Ptg { public byte getDefaultOperandClass() { return Ptg.CLASS_VALUE; } + + @Override + public UnknownPtg copy() { + return this; + } } Modified: poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/formula/ptg/ValueOperatorPtg.java Sun Dec 22 21:44:45 2019 @@ -23,11 +23,11 @@ import org.apache.poi.util.LittleEndianO * Common superclass of all value operators. Subclasses include all unary and * binary operators except for the reference operators (IntersectionPtg, * RangePtg, UnionPtg) - * - * @author Josh Micich */ public abstract class ValueOperatorPtg extends OperationPtg { + protected ValueOperatorPtg() {} + /** * All Operator <tt>Ptg</tt>s are base tokens (i.e. are not RVA classified) */ Modified: poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddress.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddress.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddress.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddress.java Sun Dec 22 21:44:45 2019 @@ -24,8 +24,8 @@ import org.apache.poi.util.LittleEndianO /** * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p> - * - * <p>In the Microsoft documentation, this is also known as a + * + * <p>In the Microsoft documentation, this is also known as a * Ref8U - see page 831 of version 1.0 of the documentation. * * Note - {@link SelectionRecord} uses the BIFF5 version of this structure @@ -36,7 +36,7 @@ public class CellRangeAddress extends Ce /** * Creates new cell range. Indexes are zero-based. - * + * * @param firstRow Index of first row * @param lastRow Index of last row (inclusive), must be equal to or larger than {@code firstRow} * @param firstCol Index of first column @@ -44,7 +44,7 @@ public class CellRangeAddress extends Ce */ public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) { super(firstRow, lastRow, firstCol, lastCol); - + if (lastRow < firstRow || lastCol < firstCol) { throw new IllegalArgumentException("Invalid cell range, having lastRow < firstRow || lastCol < firstCol, " + "had rows " + lastRow + " >= " + firstRow + " or cells " + lastCol + " >= " + firstCol); @@ -70,6 +70,7 @@ public class CellRangeAddress extends Ce return in.readUShort(); } + @Override public CellRangeAddress copy() { return new CellRangeAddress(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn()); } @@ -103,7 +104,7 @@ public class CellRangeAddress extends Ce //for a single-cell reference return A1 instead of A1:A1 //for full-column ranges or full-row ranges return A:A instead of A, - //and 1:1 instead of 1 + //and 1:1 instead of 1 if(!cellRefFrom.equals(cellRefTo) || isFullColumnRange() || isFullRowRange()){ sb.append(':'); @@ -114,10 +115,10 @@ public class CellRangeAddress extends Ce /** * Creates a CellRangeAddress from a cell range reference string. - * - * @param ref usually a standard area ref (e.g. "B1:D8"). May be a single - * cell ref (e.g. "B5") in which case the result is a 1 x 1 cell - * range. May also be a whole row range (e.g. "3:5"), or a whole + * + * @param ref usually a standard area ref (e.g. "B1:D8"). May be a single + * cell ref (e.g. "B5") in which case the result is a 1 x 1 cell + * range. May also be a whole row range (e.g. "3:5"), or a whole * column range (e.g. "C:F") */ public static CellRangeAddress valueOf(String ref) { Modified: poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressBase.java Sun Dec 22 21:44:45 2019 @@ -17,14 +17,12 @@ package org.apache.poi.ss.util; -import java.util.ArrayList; -import java.util.Collections; import java.util.EnumSet; import java.util.Iterator; -import java.util.List; import java.util.NoSuchElementException; import java.util.Set; +import org.apache.poi.common.Duplicatable; import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.Cell; @@ -34,13 +32,13 @@ import org.apache.poi.ss.usermodel.Cell; * * Common superclass of 8-bit and 16-bit versions */ -public abstract class CellRangeAddressBase implements Iterable<CellAddress> { +public abstract class CellRangeAddressBase implements Iterable<CellAddress>, Duplicatable { /** * Indicates a cell or range is in the given relative position in a range. * More than one of these may apply at once. */ - public static enum CellPosition { + public enum CellPosition { /** range starting rows are equal */ TOP, /** range ending rows are equal */ @@ -138,7 +136,7 @@ public abstract class CellRangeAddressBa } /** - * Determines if the given coordinates lie within the bounds + * Determines if the given coordinates lie within the bounds * of this range. * * @param rowInd The row, 0-based. @@ -150,11 +148,11 @@ public abstract class CellRangeAddressBa return _firstRow <= rowInd && rowInd <= _lastRow && //containsRow _firstCol <= colInd && colInd <= _lastCol; //containsColumn } - + /** - * Determines if the given {@link CellReference} lies within the bounds - * of this range. - * <p>NOTE: It is up to the caller to ensure the reference is + * Determines if the given {@link CellReference} lies within the bounds + * of this range. + * <p>NOTE: It is up to the caller to ensure the reference is * for the correct sheet, since this instance doesn't have a sheet reference. * * @param ref the CellReference to check @@ -164,11 +162,11 @@ public abstract class CellRangeAddressBa public boolean isInRange(CellReference ref) { return isInRange(ref.getRow(), ref.getCol()); } - + /** - * Determines if the given {@link CellAddress} lies within the bounds - * of this range. - * <p>NOTE: It is up to the caller to ensure the reference is + * Determines if the given {@link CellAddress} lies within the bounds + * of this range. + * <p>NOTE: It is up to the caller to ensure the reference is * for the correct sheet, since this instance doesn't have a sheet reference. * * @param ref the CellAddress to check @@ -178,11 +176,11 @@ public abstract class CellRangeAddressBa public boolean isInRange(CellAddress ref) { return isInRange(ref.getRow(), ref.getColumn()); } - + /** - * Determines if the given {@link Cell} lies within the bounds - * of this range. - * <p>NOTE: It is up to the caller to ensure the reference is + * Determines if the given {@link Cell} lies within the bounds + * of this range. + * <p>NOTE: It is up to the caller to ensure the reference is * for the correct sheet, since this instance doesn't have a sheet reference. * * @param cell the Cell to check @@ -192,7 +190,7 @@ public abstract class CellRangeAddressBa public boolean isInRange(Cell cell) { return isInRange(cell.getRowIndex(), cell.getColumnIndex()); } - + /** * Check if the row is in the specified cell range * @@ -202,7 +200,7 @@ public abstract class CellRangeAddressBa public boolean containsRow(int rowInd) { return _firstRow <= rowInd && rowInd <= _lastRow; } - + /** * Check if the column is in the specified cell range * @@ -212,7 +210,7 @@ public abstract class CellRangeAddressBa public boolean containsColumn(int colInd) { return _firstCol <= colInd && colInd <= _lastCol; } - + /** * Determines whether or not this CellRangeAddress and the specified CellRangeAddress intersect. * @@ -226,7 +224,7 @@ public abstract class CellRangeAddressBa other._firstRow <= this._lastRow && other._firstCol <= this._lastCol; } - + /** * Useful for logic like table/range styling, where some elements apply based on relative position in a range. * @param rowInd @@ -245,10 +243,10 @@ public abstract class CellRangeAddressBa if (rowInd == getLastRow()) positions.add(CellPosition.BOTTOM); if (colInd == getFirstColumn()) positions.add(CellPosition.LEFT); if (colInd == getLastColumn()) positions.add(CellPosition.RIGHT); - + return positions; } - + /** * @param firstCol column number for the upper left hand corner */ @@ -291,37 +289,37 @@ public abstract class CellRangeAddressBa public Iterator<CellAddress> iterator() { return new RowMajorCellAddressIterator(this); } - + /** * Iterates over the cell addresses in a cell range in row major order - * + * * The iterator is unaffected by changes to the CellRangeAddressBase instance * after the iterator is created. */ private static class RowMajorCellAddressIterator implements Iterator<CellAddress> { private final int firstRow, firstCol, lastRow, lastCol; private int r, c; - + public RowMajorCellAddressIterator(CellRangeAddressBase ref) { r = firstRow = ref.getFirstRow(); c = firstCol = ref.getFirstColumn(); lastRow = ref.getLastRow(); lastCol = ref.getLastColumn(); - + // whole row and whole column ranges currently not supported if (firstRow < 0) throw new IllegalStateException("First row cannot be negative."); if (firstCol < 0) throw new IllegalStateException("First column cannot be negative."); - + // avoid infinite iteration if (firstRow > lastRow) throw new IllegalStateException("First row cannot be greater than last row."); if (firstCol > lastCol) throw new IllegalStateException("First column cannot be greater than last column."); } - + @Override public boolean hasNext() { return r <= lastRow && c <= lastCol; } - + @Override public CellAddress next() { if (hasNext()) { @@ -346,7 +344,7 @@ public abstract class CellRangeAddressBa CellAddress crB = new CellAddress(_lastRow, _lastCol); return getClass().getName() + " [" + crA.formatAsString() + ":" + crB.formatAsString() +"]"; } - + // In case _firstRow > _lastRow or _firstCol > _lastCol protected int getMinRow() { return Math.min(_firstRow, _lastRow); @@ -360,7 +358,7 @@ public abstract class CellRangeAddressBa protected int getMaxColumn() { return Math.max(_firstCol, _lastCol); } - + @Override public boolean equals(Object other) { if (other instanceof CellRangeAddressBase) { @@ -372,7 +370,7 @@ public abstract class CellRangeAddressBa } return false; } - + @Override public int hashCode() { return (getMinColumn() + Modified: poi/trunk/src/java/org/apache/poi/ss/util/SSCellRange.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/util/SSCellRange.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/ss/util/SSCellRange.java (original) +++ poi/trunk/src/java/org/apache/poi/ss/util/SSCellRange.java Sun Dec 22 21:44:45 2019 @@ -20,7 +20,7 @@ package org.apache.poi.ss.util; import java.lang.reflect.Array; import java.util.Iterator; import java.util.List; -import java.util.NoSuchElementException; +import java.util.stream.Stream; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellRange; @@ -28,8 +28,6 @@ import org.apache.poi.util.Internal; /** * For POI internal use only - * - * @author Josh Micich */ @Internal public final class SSCellRange<K extends Cell> implements CellRange<K> { @@ -108,30 +106,8 @@ public final class SSCellRange<K extends } return result; } - public Iterator<K> iterator() { - return new ArrayIterator<>(_flattenedArray); - } - private static final class ArrayIterator<D> implements Iterator<D> { - - private final D[] _array; - private int _index; - public ArrayIterator(D[] array) { - _array = array.clone(); - _index = 0; - } - public boolean hasNext() { - return _index < _array.length; - } - public D next() { - if (_index >= _array.length) { - throw new NoSuchElementException(String.valueOf(_index)); - } - return _array[_index++]; - } - - public void remove() { - throw new UnsupportedOperationException("Cannot remove cells from this CellRange."); - } + public Iterator<K> iterator() { + return Stream.of(_flattenedArray).iterator(); } } Modified: poi/trunk/src/java/org/apache/poi/util/IntMapper.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/util/IntMapper.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/util/IntMapper.java (original) +++ poi/trunk/src/java/org/apache/poi/util/IntMapper.java Sun Dec 22 21:44:45 2019 @@ -19,76 +19,79 @@ package org.apache.poi.util; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.poi.common.Duplicatable; /** * A List of objects that are indexed AND keyed by an int; also allows for getting * the index of a value in the list - * - * <p>I am happy is someone wants to re-implement this without using the + * <p> + * I am happy is someone wants to re-implement this without using the * internal list and hashmap. If so could you please make sure that * you can add elements half way into the list and have the value-key mappings - * update</p> - * - * - * @author Jason Height + * update */ -public class IntMapper<T> -{ - private List<T> elements; - private Map<T,Integer> valueKeyMap; +public class IntMapper<T> implements Duplicatable { + private final List<T> elements; + private final Map<T, Integer> valueKeyMap; - private static final int _default_size = 10; + private static final int _default_size = 10; /** * create an IntMapper of default size */ - - public IntMapper() - { + public IntMapper() { this(_default_size); } - public IntMapper(final int initialCapacity) - { + public IntMapper(final int initialCapacity) { elements = new ArrayList<>(initialCapacity); valueKeyMap = new HashMap<>(initialCapacity); } + public IntMapper(IntMapper<T> other) { + elements = new ArrayList<>(other.elements); + valueKeyMap = new HashMap<>(other.valueKeyMap); + } + /** * Appends the specified element to the end of this list * * @param value element to be appended to this list. - * * @return true (as per the general contract of the Collection.add - * method). + * method). */ - public boolean add(final T value) - { - int index = elements.size(); - elements.add(value); - valueKeyMap.put(value, index); - return true; + public boolean add(final T value) { + int index = elements.size(); + elements.add(value); + valueKeyMap.put(value, index); + return true; } public int size() { - return elements.size(); + return elements.size(); } public T get(int index) { - return elements.get(index); + return elements.get(index); } public int getIndex(T o) { - Integer i = valueKeyMap.get(o); - if (i == null) - return -1; - return i.intValue(); + return valueKeyMap.getOrDefault(o, -1); } public Iterator<T> iterator() { - return elements.iterator(); + return elements.iterator(); } -} // end public class IntMapper + @Override + public IntMapper<T> copy() { + return new IntMapper<>(this); + } +} \ No newline at end of file Modified: poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java Sun Dec 22 21:44:45 2019 @@ -25,6 +25,7 @@ import static org.apache.poi.poifs.crypt import java.io.IOException; import java.io.InputStream; +import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.MessageDigest; @@ -56,43 +57,34 @@ import org.apache.poi.util.LittleEndian; /** * Decryptor implementation for Agile Encryption */ -public class AgileDecryptor extends Decryptor implements Cloneable { +public class AgileDecryptor extends Decryptor { + static final byte[] kVerifierInputBlock = longToBytes(0xfea7d2763b4b9e79L); + static final byte[] kHashedVerifierBlock = longToBytes(0xd7aa0f6d3061344eL); + static final byte[] kCryptoKeyBlock = longToBytes(0x146e0be7abacd0d6L); + static final byte[] kIntegrityKeyBlock = longToBytes(0x5fb2ad010cb9e1f6L); + static final byte[] kIntegrityValueBlock = longToBytes(0xa0677f02b22c8433L); + private long _length = -1; - /* package */ static final byte[] kVerifierInputBlock; - /* package */ static final byte[] kHashedVerifierBlock; - /* package */ static final byte[] kCryptoKeyBlock; - /* package */ static final byte[] kIntegrityKeyBlock; - /* package */ static final byte[] kIntegrityValueBlock; - - static { - kVerifierInputBlock = - new byte[] { (byte)0xfe, (byte)0xa7, (byte)0xd2, (byte)0x76, - (byte)0x3b, (byte)0x4b, (byte)0x9e, (byte)0x79 }; - kHashedVerifierBlock = - new byte[] { (byte)0xd7, (byte)0xaa, (byte)0x0f, (byte)0x6d, - (byte)0x30, (byte)0x61, (byte)0x34, (byte)0x4e }; - kCryptoKeyBlock = - new byte[] { (byte)0x14, (byte)0x6e, (byte)0x0b, (byte)0xe7, - (byte)0xab, (byte)0xac, (byte)0xd0, (byte)0xd6 }; - kIntegrityKeyBlock = - new byte[] { (byte)0x5f, (byte)0xb2, (byte)0xad, (byte)0x01, - (byte)0x0c, (byte)0xb9, (byte)0xe1, (byte)0xf6 }; - kIntegrityValueBlock = - new byte[] { (byte)0xa0, (byte)0x67, (byte)0x7f, (byte)0x02, - (byte)0xb2, (byte)0x2c, (byte)0x84, (byte)0x33 }; + protected AgileDecryptor() { } - protected AgileDecryptor() { + protected AgileDecryptor(AgileDecryptor other) { + super(other); + _length = other._length; + } + + private static byte[] longToBytes(long l) { + return ByteBuffer.allocate(Long.BYTES).putLong(l).array(); } - + /** * set decryption password */ @Override public boolean verifyPassword(String password) throws GeneralSecurityException { AgileEncryptionVerifier ver = (AgileEncryptionVerifier)getEncryptionInfo().getVerifier(); - AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); + AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); int blockSize = header.getBlockSize(); @@ -130,7 +122,7 @@ public class AgileDecryptor extends Decr */ byte[] verifierHashDec = hashInput(ver, pwHash, kHashedVerifierBlock, ver.getEncryptedVerifierHash(), Cipher.DECRYPT_MODE); verifierHashDec = getBlock0(verifierHashDec, ver.getHashAlgorithm().hashSize); - + /** * encryptedKeyValue: This attribute MUST be generated by using the following steps: * 1. Generate a random array of bytes that is the same size as specified by the @@ -180,7 +172,7 @@ public class AgileDecryptor extends Decr cipher = getCipher(secretKey, cipherAlgo, ver.getChainingMode(), vec, Cipher.DECRYPT_MODE); byte[] hmacValue = cipher.doFinal(header.getEncryptedHmacValue()); hmacValue = getBlock0(hmacValue, header.getHashAlgorithm().hashSize); - + if (Arrays.equals(verifierHashDec, verifierHash)) { setSecretKey(secretKey); setIntegrityHmacKey(hmacKey); @@ -194,7 +186,7 @@ public class AgileDecryptor extends Decr /** * instead of a password, it's also possible to decrypt via certificate. * Warning: this code is experimental and hasn't been validated - * + * * @see <a href="http://social.msdn.microsoft.com/Forums/en-US/cc9092bb-0c82-4b5b-ae21-abf643bdb37c/agile-encryption-with-certificates">Agile encryption with certificates</a> * * @param keyPair @@ -208,7 +200,7 @@ public class AgileDecryptor extends Decr HashAlgorithm hashAlgo = header.getHashAlgorithm(); CipherAlgorithm cipherAlgo = header.getCipherAlgorithm(); int blockSize = header.getBlockSize(); - + AgileCertificateEntry ace = null; for (AgileCertificateEntry aceEntry : ver.getCertificates()) { if (x509.equals(aceEntry.x509)) { @@ -219,12 +211,12 @@ public class AgileDecryptor extends Decr if (ace == null) { return false; } - + Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); byte[] keyspec = cipher.doFinal(ace.encryptedKey); SecretKeySpec secretKey = new SecretKeySpec(keyspec, ver.getCipherAlgorithm().jceId); - + Mac x509Hmac = CryptoFunctions.getMac(hashAlgo); x509Hmac.init(secretKey); byte[] certVerifier = x509Hmac.doFinal(ace.x509.getEncoded()); @@ -238,8 +230,8 @@ public class AgileDecryptor extends Decr cipher = getCipher(secretKey, cipherAlgo, header.getChainingMode(), vec, Cipher.DECRYPT_MODE); byte[] hmacValue = cipher.doFinal(header.getEncryptedHmacValue()); hmacValue = getBlock0(hmacValue, hashAlgo.hashSize); - - + + if (Arrays.equals(ace.certVerifier, certVerifier)) { setSecretKey(secretKey); setIntegrityHmacKey(hmacKey); @@ -268,7 +260,7 @@ public class AgileDecryptor extends Decr byte[] iv = generateIv(hashAlgo, ver.getSalt(), null, blockSize); Cipher cipher = getCipher(skey, cipherAlgo, chainMode, iv, cipherMode); byte[] hashFinal; - + try { inputKey = getBlock0(inputKey, getNextBlockSize(inputKey.length, blockSize)); hashFinal = cipher.doFinal(inputKey); @@ -314,13 +306,13 @@ public class AgileDecryptor extends Decr } existing.init(encryptionMode, skey, aps); - + return existing; } /** * 2.3.4.15 Data Encryption (Agile Encryption) - * + * * The EncryptedPackage stream (1) MUST be encrypted in 4096-byte segments to facilitate nearly * random access while allowing CBC modes to be used in the encryption process. * The initialization vector for the encryption process MUST be obtained by using the zero-based @@ -341,16 +333,16 @@ public class AgileDecryptor extends Decr // TODO: calculate integrity hmac while reading the stream // for a post-validation of the data - + @Override protected Cipher initCipherForBlock(Cipher cipher, int block) throws GeneralSecurityException { return AgileDecryptor.initCipherForBlock(cipher, block, false, getEncryptionInfo(), getSecretKey(), Cipher.DECRYPT_MODE); } } - + @Override - public AgileDecryptor clone() throws CloneNotSupportedException { - return (AgileDecryptor)super.clone(); + public AgileDecryptor copy() { + return new AgileDecryptor(this); } } Modified: poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java Sun Dec 22 21:44:45 2019 @@ -30,14 +30,20 @@ import org.apache.poi.poifs.crypt.Encryp import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.util.GenericRecordUtil; -public class AgileEncryptionHeader extends EncryptionHeader implements Cloneable { +public class AgileEncryptionHeader extends EncryptionHeader { private byte[] encryptedHmacKey; private byte[] encryptedHmacValue; - + public AgileEncryptionHeader(String descriptor) { this(AgileEncryptionInfoBuilder.parseDescriptor(descriptor)); } - + + public AgileEncryptionHeader(AgileEncryptionHeader other) { + super(other); + encryptedHmacKey = (other.encryptedHmacKey == null) ? null : other.encryptedHmacKey.clone(); + encryptedHmacValue = (other.encryptedHmacValue == null) ? null : other.encryptedHmacValue.clone(); + } + protected AgileEncryptionHeader(EncryptionDocument ed) { CTKeyData keyData; try { @@ -50,7 +56,7 @@ public class AgileEncryptionHeader exten } int keyBits = (int)keyData.getKeyBits(); - + CipherAlgorithm ca = CipherAlgorithm.fromXmlId(keyData.getCipherAlgorithm().toString(), keyBits); setCipherAlgorithm(ca); setCipherProvider(ca.provider); @@ -71,14 +77,14 @@ public class AgileEncryptionHeader exten default: throw new EncryptedDocumentException("Unsupported chaining mode - "+ keyData.getCipherChaining()); } - + int hashSize = keyData.getHashSize(); - + HashAlgorithm ha = HashAlgorithm.fromEcmaId(keyData.getHashAlgorithm().toString()); setHashAlgorithm(ha); if (getHashAlgorithm().hashSize != hashSize) { - throw new EncryptedDocumentException("Unsupported hash algorithm: " + + throw new EncryptedDocumentException("Unsupported hash algorithm: " + keyData.getHashAlgorithm() + " @ " + hashSize + " bytes"); } @@ -87,13 +93,13 @@ public class AgileEncryptionHeader exten if (getKeySalt().length != saltLength) { throw new EncryptedDocumentException("Invalid salt length"); } - + CTDataIntegrity di = ed.getEncryption().getDataIntegrity(); setEncryptedHmacKey(di.getEncryptedHmacKey()); setEncryptedHmacValue(di.getEncryptedHmacValue()); } - - + + public AgileEncryptionHeader(CipherAlgorithm algorithm, HashAlgorithm hashAlgorithm, int keyBits, int blockSize, ChainingMode chainingMode) { setCipherAlgorithm(algorithm); setHashAlgorithm(hashAlgorithm); @@ -128,14 +134,6 @@ public class AgileEncryptionHeader exten } @Override - public AgileEncryptionHeader clone() throws CloneNotSupportedException { - AgileEncryptionHeader other = (AgileEncryptionHeader)super.clone(); - other.encryptedHmacKey = (encryptedHmacKey == null) ? null : encryptedHmacKey.clone(); - other.encryptedHmacValue = (encryptedHmacValue == null) ? null : encryptedHmacValue.clone(); - return other; - } - - @Override public Map<String, Supplier<?>> getGenericProperties() { return GenericRecordUtil.getGenericProperties( "base", super::getGenericProperties, @@ -143,4 +141,9 @@ public class AgileEncryptionHeader exten "encryptedHmacValue", this::getEncryptedHmacValue ); } + + @Override + public AgileEncryptionHeader copy() { + return new AgileEncryptionHeader(this); + } } Modified: poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java Sun Dec 22 21:44:45 2019 @@ -24,37 +24,44 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import org.apache.poi.EncryptedDocumentException; -import org.apache.poi.poifs.crypt.ChainingMode; -import org.apache.poi.poifs.crypt.CipherAlgorithm; -import org.apache.poi.poifs.crypt.EncryptionVerifier; -import org.apache.poi.poifs.crypt.HashAlgorithm; - import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptor; import com.microsoft.schemas.office.x2006.encryption.EncryptionDocument; import com.microsoft.schemas.office.x2006.encryption.STCipherChaining; import com.microsoft.schemas.office.x2006.keyEncryptor.certificate.CTCertificateKeyEncryptor; import com.microsoft.schemas.office.x2006.keyEncryptor.password.CTPasswordKeyEncryptor; +import org.apache.poi.EncryptedDocumentException; +import org.apache.poi.poifs.crypt.ChainingMode; +import org.apache.poi.poifs.crypt.CipherAlgorithm; +import org.apache.poi.poifs.crypt.EncryptionVerifier; +import org.apache.poi.poifs.crypt.HashAlgorithm; /** - * Used when checking if a key is valid for a document + * Used when checking if a key is valid for a document */ -public class AgileEncryptionVerifier extends EncryptionVerifier implements Cloneable { +public class AgileEncryptionVerifier extends EncryptionVerifier { public static class AgileCertificateEntry { X509Certificate x509; byte[] encryptedKey; byte[] certVerifier; + + public AgileCertificateEntry() {} + + public AgileCertificateEntry(AgileCertificateEntry other) { + x509 = other.x509; + encryptedKey = (other.encryptedKey == null) ? null : other.encryptedKey.clone(); + certVerifier = (other.certVerifier == null) ? null : other.certVerifier.clone(); + } } - - private List<AgileCertificateEntry> certList = new ArrayList<>(); + + private final List<AgileCertificateEntry> certList = new ArrayList<>(); private int keyBits = -1; private int blockSize = -1; public AgileEncryptionVerifier(String descriptor) { this(AgileEncryptionInfoBuilder.parseDescriptor(descriptor)); } - + protected AgileEncryptionVerifier(EncryptionDocument ed) { Iterator<CTKeyEncryptor> encList = ed.getEncryption().getKeyEncryptors().getKeyEncryptorList().iterator(); CTPasswordKeyEncryptor keyData; @@ -66,37 +73,37 @@ public class AgileEncryptionVerifier ext } catch (Exception e) { throw new EncryptedDocumentException("Unable to parse keyData", e); } - + int kb = (int)keyData.getKeyBits(); CipherAlgorithm ca = CipherAlgorithm.fromXmlId(keyData.getCipherAlgorithm().toString(), kb); setCipherAlgorithm(ca); setKeySize(kb); - + int blockSize = keyData.getBlockSize(); setBlockSize(blockSize); - + int hashSize = keyData.getHashSize(); HashAlgorithm ha = HashAlgorithm.fromEcmaId(keyData.getHashAlgorithm().toString()); setHashAlgorithm(ha); if (getHashAlgorithm().hashSize != hashSize) { - throw new EncryptedDocumentException("Unsupported hash algorithm: " + + throw new EncryptedDocumentException("Unsupported hash algorithm: " + keyData.getHashAlgorithm() + " @ " + hashSize + " bytes"); } setSpinCount(keyData.getSpinCount()); setEncryptedVerifier(keyData.getEncryptedVerifierHashInput()); setSalt(keyData.getSaltValue()); - setEncryptedKey(keyData.getEncryptedKeyValue()); + setEncryptedKey(keyData.getEncryptedKeyValue()); setEncryptedVerifierHash(keyData.getEncryptedVerifierHashValue()); int saltSize = keyData.getSaltSize(); if (saltSize != getSalt().length) { throw new EncryptedDocumentException("Invalid salt size"); } - + switch (keyData.getCipherChaining().intValue()) { case STCipherChaining.INT_CHAINING_MODE_CBC: setChainingMode(ChainingMode.cbc); @@ -107,11 +114,11 @@ public class AgileEncryptionVerifier ext default: throw new EncryptedDocumentException("Unsupported chaining mode - "+ keyData.getCipherChaining()); } - + if (!encList.hasNext()) { return; } - + try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); while (encList.hasNext()) { @@ -126,7 +133,7 @@ public class AgileEncryptionVerifier ext throw new EncryptedDocumentException("can't parse X509 certificate", e); } } - + public AgileEncryptionVerifier(CipherAlgorithm cipherAlgorithm, HashAlgorithm hashAlgorithm, int keyBits, int blockSize, ChainingMode chainingMode) { setCipherAlgorithm(cipherAlgorithm); setHashAlgorithm(hashAlgorithm); @@ -135,7 +142,14 @@ public class AgileEncryptionVerifier ext setBlockSize(blockSize); setSpinCount(100000); // TODO: use parameter } - + + public AgileEncryptionVerifier(AgileEncryptionVerifier other) { + super(other); + keyBits = other.keyBits; + blockSize = other.blockSize; + other.certList.stream().map(AgileCertificateEntry::new).forEach(certList::add); + } + @Override protected void setSalt(byte[] salt) { if (salt == null || salt.length != getCipherAlgorithm().blockSize) { @@ -143,7 +157,7 @@ public class AgileEncryptionVerifier ext } super.setSalt(salt); } - + // make method visible for this package @Override protected void setEncryptedVerifier(byte[] encryptedVerifier) { @@ -161,26 +175,23 @@ public class AgileEncryptionVerifier ext protected void setEncryptedKey(byte[] encryptedKey) { super.setEncryptedKey(encryptedKey); } - + public void addCertificate(X509Certificate x509) { AgileCertificateEntry ace = new AgileCertificateEntry(); ace.x509 = x509; certList.add(ace); } - + public List<AgileCertificateEntry> getCertificates() { return certList; } @Override - public AgileEncryptionVerifier clone() throws CloneNotSupportedException { - AgileEncryptionVerifier other = (AgileEncryptionVerifier)super.clone(); - // TODO: deep copy of certList - other.certList = new ArrayList<>(certList); - return other; + public AgileEncryptionVerifier copy() { + return new AgileEncryptionVerifier(this); } - - + + /** * The keysize (in bits) of the verifier data. This usually equals the keysize of the header, * but only on a few exceptions, like files generated by Office for Mac, can be @@ -192,7 +203,7 @@ public class AgileEncryptionVerifier ext return keyBits; } - + /** * The blockSize (in bytes) of the verifier data. * This usually equals the blocksize of the header. @@ -202,7 +213,7 @@ public class AgileEncryptionVerifier ext public int getBlockSize() { return blockSize; } - + /** * Sets the keysize (in bits) of the verifier * @@ -218,7 +229,7 @@ public class AgileEncryptionVerifier ext throw new EncryptedDocumentException("KeySize "+keyBits+" not allowed for cipher "+getCipherAlgorithm()); } - + /** * Sets the blockSize (in bytes) of the verifier * Modified: poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java Sun Dec 22 21:44:45 2019 @@ -49,6 +49,17 @@ import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; +import com.microsoft.schemas.office.x2006.encryption.CTDataIntegrity; +import com.microsoft.schemas.office.x2006.encryption.CTEncryption; +import com.microsoft.schemas.office.x2006.encryption.CTKeyData; +import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptor; +import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptors; +import com.microsoft.schemas.office.x2006.encryption.EncryptionDocument; +import com.microsoft.schemas.office.x2006.encryption.STCipherAlgorithm; +import com.microsoft.schemas.office.x2006.encryption.STCipherChaining; +import com.microsoft.schemas.office.x2006.encryption.STHashAlgorithm; +import com.microsoft.schemas.office.x2006.keyEncryptor.certificate.CTCertificateKeyEncryptor; +import com.microsoft.schemas.office.x2006.keyEncryptor.password.CTPasswordKeyEncryptor; import org.apache.poi.EncryptedDocumentException; import org.apache.poi.poifs.crypt.ChunkedCipherOutputStream; import org.apache.poi.poifs.crypt.CryptoFunctions; @@ -65,28 +76,21 @@ import org.apache.poi.util.LittleEndianB import org.apache.poi.util.LittleEndianConsts; import org.apache.xmlbeans.XmlOptions; -import com.microsoft.schemas.office.x2006.encryption.CTDataIntegrity; -import com.microsoft.schemas.office.x2006.encryption.CTEncryption; -import com.microsoft.schemas.office.x2006.encryption.CTKeyData; -import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptor; -import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptors; -import com.microsoft.schemas.office.x2006.encryption.EncryptionDocument; -import com.microsoft.schemas.office.x2006.encryption.STCipherAlgorithm; -import com.microsoft.schemas.office.x2006.encryption.STCipherChaining; -import com.microsoft.schemas.office.x2006.encryption.STHashAlgorithm; -import com.microsoft.schemas.office.x2006.keyEncryptor.certificate.CTCertificateKeyEncryptor; -import com.microsoft.schemas.office.x2006.keyEncryptor.password.CTPasswordKeyEncryptor; - -public class AgileEncryptor extends Encryptor implements Cloneable { +public class AgileEncryptor extends Encryptor { //arbitrarily selected; may need to increase private static final int MAX_RECORD_LENGTH = 1_000_000; private byte[] integritySalt; private byte[] pwHash; - - protected AgileEncryptor() { - } + + protected AgileEncryptor() {} + + protected AgileEncryptor(AgileEncryptor other) { + super(other); + integritySalt = (other.integritySalt == null) ? null : other.integritySalt.clone(); + pwHash = (other.pwHash == null) ? null : other.pwHash.clone(); + } @Override public void confirmPassword(String password) { @@ -96,7 +100,7 @@ public class AgileEncryptor extends Encr int blockSize = header.getBlockSize(); int keySize = header.getKeySize()/8; int hashSize = header.getHashAlgorithm().hashSize; - + byte[] newVerifierSalt = IOUtils.safelyAllocate(blockSize, MAX_RECORD_LENGTH) , newVerifier = IOUtils.safelyAllocate(blockSize, MAX_RECORD_LENGTH) , newKeySalt = IOUtils.safelyAllocate(blockSize, MAX_RECORD_LENGTH) @@ -107,10 +111,10 @@ public class AgileEncryptor extends Encr r.nextBytes(newKeySalt); // blocksize r.nextBytes(newKeySpec); // keysize r.nextBytes(newIntegritySalt); // hashsize - + confirmPassword(password, newKeySpec, newKeySalt, newVerifierSalt, newVerifier, newIntegritySalt); } - + @Override public void confirmPassword(String password, byte[] keySpec, byte[] keySalt, byte[] verifier, byte[] verifierSalt, byte[] integritySalt) { AgileEncryptionVerifier ver = (AgileEncryptionVerifier)getEncryptionInfo().getVerifier(); @@ -120,9 +124,9 @@ public class AgileEncryptor extends Encr header.setKeySalt(keySalt); int blockSize = header.getBlockSize(); - + pwHash = hashPassword(password, ver.getHashAlgorithm(), verifierSalt, ver.getSpinCount()); - + /** * encryptedVerifierHashInput: This attribute MUST be generated by using the following steps: * 1. Generate a random array of bytes with the number of bytes used specified by the saltSize @@ -138,7 +142,7 @@ public class AgileEncryptor extends Encr */ byte[] encryptedVerifier = hashInput(ver, pwHash, kVerifierInputBlock, verifier, Cipher.ENCRYPT_MODE); ver.setEncryptedVerifier(encryptedVerifier); - + /** * encryptedVerifierHashValue: This attribute MUST be generated by using the following steps: @@ -156,7 +160,7 @@ public class AgileEncryptor extends Encr byte[] hashedVerifier = hashMD.digest(verifier); byte[] encryptedVerifierHash = hashInput(ver, pwHash, kHashedVerifierBlock, hashedVerifier, Cipher.ENCRYPT_MODE); ver.setEncryptedVerifierHash(encryptedVerifierHash); - + /** * encryptedKeyValue: This attribute MUST be generated by using the following steps: * 1. Generate a random array of bytes that is the same size as specified by the @@ -172,13 +176,13 @@ public class AgileEncryptor extends Encr */ byte[] encryptedKey = hashInput(ver, pwHash, kCryptoKeyBlock, keySpec, Cipher.ENCRYPT_MODE); ver.setEncryptedKey(encryptedKey); - + SecretKey secretKey = new SecretKeySpec(keySpec, header.getCipherAlgorithm().jceId); setSecretKey(secretKey); - + /* * 2.3.4.14 DataIntegrity Generation (Agile Encryption) - * + * * The DataIntegrity element contained within an Encryption element MUST be generated by using * the following steps: * 1. Obtain the intermediate key by decrypting the encryptedKeyValue from a KeyEncryptor @@ -198,7 +202,7 @@ public class AgileEncryptor extends Encr * used as the message. * 6. Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes: * 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33. - * 7. Assign the encryptedHmacValue attribute to the base64-encoded form of the result of step 6. + * 7. Assign the encryptedHmacValue attribute to the base64-encoded form of the result of step 6. */ this.integritySalt = integritySalt.clone(); @@ -221,7 +225,7 @@ public class AgileEncryptor extends Encr throw new EncryptedDocumentException(e); } } - + @Override public OutputStream getDataStream(DirectoryNode dir) throws IOException, GeneralSecurityException { @@ -230,11 +234,11 @@ public class AgileEncryptor extends Encr } /** - * Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message), - * which the DataIntegrity element will verify by using the Salt generated in step 2 as the key. - * Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be + * Generate an HMAC, as specified in [RFC2104], of the encrypted form of the data (message), + * which the DataIntegrity element will verify by using the Salt generated in step 2 as the key. + * Note that the entire EncryptedPackage stream (1), including the StreamSize field, MUST be * used as the message. - * + * * Encrypt the HMAC as in step 3 by using a blockKey byte array consisting of the following bytes: * 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, and 0x33. **/ @@ -266,22 +270,22 @@ public class AgileEncryptor extends Encr byte[] iv = CryptoFunctions.generateIv(header.getHashAlgorithm(), header.getKeySalt(), kIntegrityValueBlock, blockSize); Cipher cipher = CryptoFunctions.getCipher(getSecretKey(), header.getCipherAlgorithm(), header.getChainingMode(), iv, Cipher.ENCRYPT_MODE); byte[] encryptedHmacValue = cipher.doFinal(hmacValueFilled); - + header.setEncryptedHmacValue(encryptedHmacValue); } - - private final CTKeyEncryptor.Uri.Enum passwordUri = + + private final CTKeyEncryptor.Uri.Enum passwordUri = CTKeyEncryptor.Uri.HTTP_SCHEMAS_MICROSOFT_COM_OFFICE_2006_KEY_ENCRYPTOR_PASSWORD; - private final CTKeyEncryptor.Uri.Enum certificateUri = + private final CTKeyEncryptor.Uri.Enum certificateUri = CTKeyEncryptor.Uri.HTTP_SCHEMAS_MICROSOFT_COM_OFFICE_2006_KEY_ENCRYPTOR_CERTIFICATE; - + protected EncryptionDocument createEncryptionDocument() { AgileEncryptionVerifier ver = (AgileEncryptionVerifier)getEncryptionInfo().getVerifier(); - AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); - + AgileEncryptionHeader header = (AgileEncryptionHeader)getEncryptionInfo().getHeader(); + EncryptionDocument ed = EncryptionDocument.Factory.newInstance(); CTEncryption edRoot = ed.addNewEncryption(); - + CTKeyData keyData = edRoot.addNewKeyData(); CTKeyEncryptors keyEncList = edRoot.addNewKeyEncryptors(); CTKeyEncryptor keyEnc = keyEncList.addNewKeyEncryptor(); @@ -289,10 +293,10 @@ public class AgileEncryptor extends Encr CTPasswordKeyEncryptor keyPass = keyEnc.addNewEncryptedPasswordKey(); keyPass.setSpinCount(ver.getSpinCount()); - + keyData.setSaltSize(header.getBlockSize()); keyPass.setSaltSize(ver.getBlockSize()); - + keyData.setBlockSize(header.getBlockSize()); keyPass.setBlockSize(ver.getBlockSize()); @@ -312,9 +316,9 @@ public class AgileEncryptor extends Encr } keyData.setCipherAlgorithm(xmlCipherAlgo); keyPass.setCipherAlgorithm(xmlCipherAlgo); - + switch (header.getChainingMode()) { - case cbc: + case cbc: keyData.setCipherChaining(STCipherChaining.CHAINING_MODE_CBC); keyPass.setCipherChaining(STCipherChaining.CHAINING_MODE_CBC); break; @@ -325,7 +329,7 @@ public class AgileEncryptor extends Encr default: throw new EncryptedDocumentException("ChainingMode "+header.getChainingMode()+" not supported."); } - + keyData.setHashAlgorithm(mapHashAlgorithm(header.getHashAlgorithm())); keyPass.setHashAlgorithm(mapHashAlgorithm(ver.getHashAlgorithm())); @@ -334,11 +338,11 @@ public class AgileEncryptor extends Encr keyPass.setEncryptedVerifierHashInput(ver.getEncryptedVerifier()); keyPass.setEncryptedVerifierHashValue(ver.getEncryptedVerifierHash()); keyPass.setEncryptedKeyValue(ver.getEncryptedKey()); - + CTDataIntegrity hmacData = edRoot.addNewDataIntegrity(); hmacData.setEncryptedHmacKey(header.getEncryptedHmacKey()); hmacData.setEncryptedHmacValue(header.getEncryptedHmacValue()); - + for (AgileCertificateEntry ace : ver.getCertificates()) { keyEnc = keyEncList.addNewKeyEncryptor(); keyEnc.setUri(certificateUri); @@ -351,7 +355,7 @@ public class AgileEncryptor extends Encr certData.setEncryptedKeyValue(ace.encryptedKey); certData.setCertVerifier(ace.certVerifier); } - + return ed; } @@ -362,7 +366,7 @@ public class AgileEncryptor extends Encr } return xmlHashAlgo; } - + protected void marshallEncryptionDocument(EncryptionDocument ed, LittleEndianByteArrayOutputStream os) { XmlOptions xo = new XmlOptions(); xo.setCharacterEncoding("UTF-8"); @@ -396,7 +400,7 @@ public class AgileEncryptor extends Encr EncryptionRecord er = new EncryptionRecord(){ @Override public void write(LittleEndianByteArrayOutputStream bos) { - // EncryptionVersionInfo (4 bytes): A Version structure (section 2.1.4), where + // EncryptionVersionInfo (4 bytes): A Version structure (section 2.1.4), where // Version.vMajor MUST be 0x0004 and Version.vMinor MUST be 0x0004 bos.writeShort(info.getVersionMajor()); bos.writeShort(info.getVersionMinor()); @@ -407,14 +411,14 @@ public class AgileEncryptor extends Encr marshallEncryptionDocument(ed, bos); } }; - + createEncryptionEntry(dir, "EncryptionInfo", er); } - - + + /** * 2.3.4.15 Data Encryption (Agile Encryption) - * + * * The EncryptedPackage stream (1) MUST be encrypted in 4096-byte segments to facilitate nearly * random access while allowing CBC modes to be used in the encryption process. * The initialization vector for the encryption process MUST be obtained by using the zero-based @@ -431,7 +435,7 @@ public class AgileEncryptor extends Encr public AgileCipherOutputStream(DirectoryNode dir) throws IOException, GeneralSecurityException { super(dir, 4096); } - + @Override protected Cipher initCipherForBlock(Cipher existing, int block, boolean lastChunk) throws GeneralSecurityException { @@ -442,9 +446,9 @@ public class AgileEncryptor extends Encr protected void calculateChecksum(File fileOut, int oleStreamSize) throws GeneralSecurityException, IOException { // integrityHMAC needs to be updated before the encryption document is created - updateIntegrityHMAC(fileOut, oleStreamSize); + updateIntegrityHMAC(fileOut, oleStreamSize); } - + @Override protected void createEncryptionInfoEntry(DirectoryNode dir, File tmpFile) throws IOException, GeneralSecurityException { @@ -453,10 +457,7 @@ public class AgileEncryptor extends Encr } @Override - public AgileEncryptor clone() throws CloneNotSupportedException { - AgileEncryptor other = (AgileEncryptor)super.clone(); - other.integritySalt = (integritySalt == null) ? null : integritySalt.clone(); - other.pwHash = (pwHash == null) ? null : pwHash.clone(); - return other; + public AgileEncryptor copy() { + return new AgileEncryptor(this); } } Modified: poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java?rev=1871911&r1=1871910&r2=1871911&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java Sun Dec 22 21:44:45 2019 @@ -19,6 +19,7 @@ package org.apache.poi.xssf.usermodel; import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; +import org.apache.poi.common.Duplicatable; import org.apache.poi.ooxml.POIXMLException; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.CellStyle; @@ -29,6 +30,7 @@ import org.apache.poi.ss.usermodel.Index import org.apache.poi.ss.usermodel.ReadingOrder; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.util.Internal; +import org.apache.poi.util.Removal; import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.model.ThemesTable; import org.apache.poi.xssf.usermodel.extensions.XSSFCellAlignment; @@ -56,7 +58,7 @@ import org.openxmlformats.schemas.spread * @see org.apache.poi.xssf.usermodel.XSSFWorkbook#getCellStyleAt(int) * @see org.apache.poi.xssf.usermodel.XSSFCell#setCellStyle(org.apache.poi.ss.usermodel.CellStyle) */ -public class XSSFCellStyle implements CellStyle { +public class XSSFCellStyle implements CellStyle, Duplicatable { private int _cellXfId; private final StylesTable _stylesSource; @@ -1303,6 +1305,14 @@ public class XSSFCellStyle implements Ce return _cellXf.toString().equals(cf.getCoreXf().toString()); } + @Override + @SuppressWarnings("squid:S2975") + @Deprecated + @Removal(version = "5.0.0") + public XSSFCellStyle clone() { + return copy(); + } + /** * Make a copy of this style. The underlying CTXf bean is cloned, * the references to fills and borders remain. @@ -1310,7 +1320,7 @@ public class XSSFCellStyle implements Ce * @return a copy of this style */ @Override - public Object clone(){ + public XSSFCellStyle copy(){ CTXf xf = (CTXf)_cellXf.copy(); int xfSize = _stylesSource._getStyleXfsSize(); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@poi.apache.org For additional commands, e-mail: commits-h...@poi.apache.org