package org.apache.poi.hssf.record.formula.eval;
import org.apache.poi.hssf.record.formula.ConcatPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
private ConcatPtg delegate;
- public ConcatEval(Ptg ptg) {
- this.delegate = (ConcatPtg) ptg;
+ public ConcatEval(ConcatPtg ptg) {
+ delegate = ptg;
}
public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
sb.append(sve.getStringValue());
} else if (ve == BlankEval.INSTANCE) {
// do nothing
- } else { // must be an error eval
+ } else {
throw new RuntimeException("Unexpected value type ("
+ ve.getClass().getName() + ")");
}
-/*
-* 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.
-*/
-/*
- * Created on May 8, 2005
- *
- */
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
package org.apache.poi.hssf.record.formula.eval;
import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.functions.Function;
/**
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*
*/
-public class FuncVarEval extends FunctionEval {
+public final class FuncVarEval extends FunctionEval {
private AbstractFunctionPtg delegate;
- public FuncVarEval(Ptg funcPtg) {
- delegate = (AbstractFunctionPtg) funcPtg;
+ public FuncVarEval(AbstractFunctionPtg funcPtg) {
+ delegate = funcPtg;
}
public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
- Eval retval = null;
Function f = getFunction();
- if (f != null)
- retval = f.evaluate(operands, srcRow, srcCol);
- else
- retval = ErrorEval.FUNCTION_NOT_IMPLEMENTED;
- return retval;
+ if (f == null) {
+ return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
+ }
+ return f.evaluate(operands, srcRow, srcCol);
}
public int getNumberOfOperands() {
final class CellEvaluationFrame {\r
\r
private final FormulaCellCacheEntry _cce;\r
- private final Set _sensitiveInputCells;\r
+ private final Set<CellCacheEntry> _sensitiveInputCells;\r
private FormulaUsedBlankCellSet _usedBlankCellGroup;\r
\r
public CellEvaluationFrame(FormulaCellCacheEntry cce) {\r
_cce = cce;\r
- _sensitiveInputCells = new HashSet();\r
+ _sensitiveInputCells = new HashSet<CellCacheEntry>();\r
}\r
public CellCacheEntry getCCE() {\r
return _cce;\r
public static final CollaboratingWorkbooksEnvironment EMPTY = new CollaboratingWorkbooksEnvironment();
- private final Map _evaluatorsByName;
+ private final Map<String, WorkbookEvaluator> _evaluatorsByName;
private final WorkbookEvaluator[] _evaluators;
private boolean _unhooked;
private CollaboratingWorkbooksEnvironment() {
- _evaluatorsByName = Collections.EMPTY_MAP;
+ _evaluatorsByName = Collections.emptyMap();
_evaluators = new WorkbookEvaluator[0];
}
public static void setup(String[] workbookNames, WorkbookEvaluator[] evaluators) {
}
private CollaboratingWorkbooksEnvironment(String[] workbookNames, WorkbookEvaluator[] evaluators, int nItems) {
- Map m = new HashMap(nItems * 3 / 2);
- IdentityHashMap uniqueEvals = new IdentityHashMap(nItems * 3 / 2);
+ Map<String, WorkbookEvaluator> m = new HashMap<String, WorkbookEvaluator>(nItems * 3 / 2);
+ IdentityHashMap<WorkbookEvaluator, String> uniqueEvals = new IdentityHashMap<WorkbookEvaluator, String>(nItems * 3 / 2);
for(int i=0; i<nItems; i++) {
String wbName = workbookNames[i];
WorkbookEvaluator wbEval = evaluators[i];
}
private void unhookOldEnvironments(WorkbookEvaluator[] evaluators) {
- Set oldEnvs = new HashSet();
+ Set<CollaboratingWorkbooksEnvironment> oldEnvs = new HashSet<CollaboratingWorkbooksEnvironment>();
for(int i=0; i<evaluators.length; i++) {
oldEnvs.add(evaluators[i].getEnvironment());
}
if (_unhooked) {
throw new IllegalStateException("This environment has been unhooked");
}
- WorkbookEvaluator result = (WorkbookEvaluator) _evaluatorsByName.get(workbookName);
+ WorkbookEvaluator result = _evaluatorsByName.get(workbookName);
if (result == null) {
StringBuffer sb = new StringBuffer(256);
sb.append("Could not resolve external workbook name '").append(workbookName).append("'.");
sb.append(" Workbook environment has not been set up.");
} else {
sb.append(" The following workbook names are valid: (");
- Iterator i = _evaluatorsByName.keySet().iterator();
+ Iterator<String> i = _evaluatorsByName.keySet().iterator();
int count=0;
while(i.hasNext()) {
if (count++>0) {
*/
final class EvaluationTracker {
// TODO - consider deleting this class and letting CellEvaluationFrame take care of itself
- private final List _evaluationFrames;
- private final Set _currentlyEvaluatingCells;
+ private final List<CellEvaluationFrame> _evaluationFrames;
+ private final Set<FormulaCellCacheEntry> _currentlyEvaluatingCells;
private final EvaluationCache _cache;
public EvaluationTracker(EvaluationCache cache) {
_cache = cache;
- _evaluationFrames = new ArrayList();
- _currentlyEvaluatingCells = new HashSet();
+ _evaluationFrames = new ArrayList<CellEvaluationFrame>();
+ _currentlyEvaluatingCells = new HashSet<FormulaCellCacheEntry>();
}
/**
if (nFrames < 1) {
throw new IllegalStateException("Call to endEvaluate without matching call to startEvaluate");
}
- CellEvaluationFrame frame = (CellEvaluationFrame) _evaluationFrames.get(nFrames-1);
+ CellEvaluationFrame frame = _evaluationFrames.get(nFrames-1);
frame.updateFormulaResult(result);
}
}
nFrames--;
- CellEvaluationFrame frame = (CellEvaluationFrame) _evaluationFrames.get(nFrames);
+ CellEvaluationFrame frame = _evaluationFrames.get(nFrames);
if (cce != frame.getCCE()) {
throw new IllegalStateException("Wrong cell specified. ");
}
if (prevFrameIndex < 0) {
// Top level frame, there is no 'cell' above this frame that is using the current cell
} else {
- CellEvaluationFrame consumingFrame = (CellEvaluationFrame) _evaluationFrames.get(prevFrameIndex);
+ CellEvaluationFrame consumingFrame = _evaluationFrames.get(prevFrameIndex);
consumingFrame.addSensitiveInputCell(cce);
}
}
if (prevFrameIndex < 0) {
// Top level frame, there is no 'cell' above this frame that is using the current cell
} else {
- CellEvaluationFrame consumingFrame = (CellEvaluationFrame) _evaluationFrames.get(prevFrameIndex);
+ CellEvaluationFrame consumingFrame = _evaluationFrames.get(prevFrameIndex);
if (value == BlankEval.INSTANCE) {
consumingFrame.addUsedBlankCell(bookIndex, sheetIndex, rowIndex, columnIndex);
} else {
if (nPrevUsed < 1) {
return;
}
- Set usedSet;
+ Set<CellCacheEntry> usedSet;
if (nUsed < 1) {
- usedSet = Collections.EMPTY_SET;
+ usedSet = Collections.emptySet();
} else {
- usedSet = new HashSet(nUsed * 3 / 2);
+ usedSet = new HashSet<CellCacheEntry>(nUsed * 3 / 2);
for (int i = 0; i < nUsed; i++) {
usedSet.add(usedCells[i]);
}
if (ptgs == null || ptgs.length == 0) {\r
throw new IllegalArgumentException("ptgs must not be null");\r
}\r
- Stack stack = new Stack();\r
+ Stack<String> stack = new Stack<String>();\r
\r
for (int i=0 ; i < ptgs.length; i++) {\r
Ptg ptg = ptgs[i];\r
continue;\r
}\r
if (ptg instanceof ParenthesisPtg) {\r
- String contents = (String)stack.pop();\r
+ String contents = stack.pop();\r
stack.push ("(" + contents + ")");\r
continue;\r
}\r
// stack.push(). So this is either an internal error or impossible.\r
throw new IllegalStateException("Stack underflow");\r
}\r
- String result = (String) stack.pop();\r
+ String result = stack.pop();\r
if(!stack.isEmpty()) {\r
// Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't\r
// put anything on the stack\r
}
private static final class BlankCellSheetGroup {
- private final List _rectangleGroups;
+ private final List<BlankCellRectangleGroup> _rectangleGroups;
private int _currentRowIndex;
private int _firstColumnIndex;
private int _lastColumnIndex;
private BlankCellRectangleGroup _currentRectangleGroup;
public BlankCellSheetGroup() {
- _rectangleGroups = new ArrayList();
+ _rectangleGroups = new ArrayList<BlankCellRectangleGroup>();
_currentRowIndex = -1;
}
public boolean containsCell(int rowIndex, int columnIndex) {
for (int i=_rectangleGroups.size()-1; i>=0; i--) {
- BlankCellRectangleGroup bcrg = (BlankCellRectangleGroup) _rectangleGroups.get(i);
+ BlankCellRectangleGroup bcrg = _rectangleGroups.get(i);
if (bcrg.containsCell(rowIndex, columnIndex)) {
return true;
}
}
}
- private final Map _sheetGroupsByBookSheet;
+ private final Map<BookSheetKey, BlankCellSheetGroup> _sheetGroupsByBookSheet;
public FormulaUsedBlankCellSet() {
- _sheetGroupsByBookSheet = new HashMap();
+ _sheetGroupsByBookSheet = new HashMap<BookSheetKey, BlankCellSheetGroup>();
}
public void addCell(int bookIndex, int sheetIndex, int rowIndex, int columnIndex) {
private BlankCellSheetGroup getSheetGroup(int bookIndex, int sheetIndex) {
BookSheetKey key = new BookSheetKey(bookIndex, sheetIndex);
- BlankCellSheetGroup result = (BlankCellSheetGroup) _sheetGroupsByBookSheet.get(key);
+ BlankCellSheetGroup result = _sheetGroupsByBookSheet.get(key);
if (result == null) {
result = new BlankCellSheetGroup();
_sheetGroupsByBookSheet.put(key, result);
}
public boolean containsCell(BookSheetKey key, int rowIndex, int columnIndex) {
- BlankCellSheetGroup bcsg = (BlankCellSheetGroup) _sheetGroupsByBookSheet.get(key);
+ BlankCellSheetGroup bcsg = _sheetGroupsByBookSheet.get(key);
if (bcsg == null) {
return false;
}
package org.apache.poi.ss.formula;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
/**
* This class creates <tt>OperationEval</tt> instances to help evaluate <tt>OperationPtg</tt>
* formula tokens.
- *
+ *
* @author Josh Micich
*/
final class OperationEvaluatorFactory {
- private static final Class[] OPERATION_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class };
- // TODO - use singleton instances directly instead of reflection
- private static final Map _constructorsByPtgClass = initialiseConstructorsMap();
- private static final Map _instancesByPtgClass = initialiseInstancesMap();
-
+
+ private static final Map<Class<? extends Ptg>, OperationEval> _instancesByPtgClass = initialiseInstancesMap();
+
private OperationEvaluatorFactory() {
// no instances of this class
}
-
- private static Map initialiseConstructorsMap() {
- Map m = new HashMap(32);
- add(m, ConcatPtg.class, ConcatEval.class);
- add(m, FuncPtg.class, FuncVarEval.class);
- add(m, FuncVarPtg.class, FuncVarEval.class);
- return m;
- }
- private static Map initialiseInstancesMap() {
- Map m = new HashMap(32);
- add(m, EqualPtg.class, EqualEval.instance);
- add(m, GreaterEqualPtg.class, GreaterEqualEval.instance);
- add(m, GreaterThanPtg.class, GreaterThanEval.instance);
- add(m, LessEqualPtg.class, LessEqualEval.instance);
- add(m, LessThanPtg.class, LessThanEval.instance);
- add(m, NotEqualPtg.class, NotEqualEval.instance);
- add(m, AddPtg.class, AddEval.instance);
- add(m, DividePtg.class, DivideEval.instance);
- add(m, MultiplyPtg.class, MultiplyEval.instance);
- add(m, PercentPtg.class, PercentEval.instance);
- add(m, PowerPtg.class, PowerEval.instance);
- add(m, SubtractPtg.class, SubtractEval.instance);
- add(m, UnaryMinusPtg.class, UnaryMinusEval.instance);
- add(m, UnaryPlusPtg.class, UnaryPlusEval.instance);
- add(m, RangePtg.class, RangeEval.instance);
- return m;
- }
+ private static Map<Class<? extends Ptg>, OperationEval> initialiseInstancesMap() {
+ Map<Class<? extends Ptg>, OperationEval> m = new HashMap<Class<? extends Ptg>, OperationEval>(32);
+ m.put(EqualPtg.class, EqualEval.instance);
- private static void add(Map m, Class ptgClass, OperationEval evalInstance) {
- if(!Ptg.class.isAssignableFrom(ptgClass)) {
- throw new IllegalArgumentException("Expected Ptg subclass");
- }
- m.put(ptgClass, evalInstance);
- }
+ m.put(EqualPtg.class, EqualEval.instance);
+ m.put(GreaterEqualPtg.class, GreaterEqualEval.instance);
+ m.put(GreaterThanPtg.class, GreaterThanEval.instance);
+ m.put(LessEqualPtg.class, LessEqualEval.instance);
+ m.put(LessThanPtg.class, LessThanEval.instance);
+ m.put(NotEqualPtg.class, NotEqualEval.instance);
- private static void add(Map m, Class ptgClass, Class evalClass) {
- // perform some validation now, to keep later exception handlers simple
- if(!Ptg.class.isAssignableFrom(ptgClass)) {
- throw new IllegalArgumentException("Expected Ptg subclass");
- }
-
- if(!OperationEval.class.isAssignableFrom(evalClass)) {
- throw new IllegalArgumentException("Expected OperationEval subclass");
- }
- if (!Modifier.isPublic(evalClass.getModifiers())) {
- throw new RuntimeException("Eval class must be public");
- }
- if (Modifier.isAbstract(evalClass.getModifiers())) {
- throw new RuntimeException("Eval class must not be abstract");
- }
-
- Constructor constructor;
- try {
- constructor = evalClass.getDeclaredConstructor(OPERATION_CONSTRUCTOR_CLASS_ARRAY);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException("Missing constructor");
- }
- if (!Modifier.isPublic(constructor.getModifiers())) {
- throw new RuntimeException("Eval constructor must be public");
- }
- m.put(ptgClass, constructor);
+ m.put(AddPtg.class, AddEval.instance);
+ m.put(DividePtg.class, DivideEval.instance);
+ m.put(MultiplyPtg.class, MultiplyEval.instance);
+ m.put(PercentPtg.class, PercentEval.instance);
+ m.put(PowerPtg.class, PowerEval.instance);
+ m.put(SubtractPtg.class, SubtractEval.instance);
+ m.put(UnaryMinusPtg.class, UnaryMinusEval.instance);
+ m.put(UnaryPlusPtg.class, UnaryPlusEval.instance);
+ m.put(RangePtg.class, RangeEval.instance);
+ return m;
}
/**
if(ptg == null) {
throw new IllegalArgumentException("ptg must not be null");
}
- Object result;
-
+ OperationEval result;
+
Class ptgClass = ptg.getClass();
-
+
result = _instancesByPtgClass.get(ptgClass);
if (result != null) {
- return (OperationEval) result;
+ return result;
}
-
- Constructor constructor = (Constructor) _constructorsByPtgClass.get(ptgClass);
- if(constructor == null) {
- if(ptgClass == ExpPtg.class) {
- // ExpPtg is used for array formulas and shared formulas.
- // it is currently unsupported, and may not even get implemented here
- throw new RuntimeException("ExpPtg currently not supported");
- }
- throw new RuntimeException("Unexpected operation ptg class (" + ptgClass.getName() + ")");
+ if (ptgClass == FuncPtg.class) {
+ return new FuncVarEval((FuncPtg)ptg);
}
-
- Object[] initargs = { ptg };
- try {
- result = constructor.newInstance(initargs);
- } catch (IllegalArgumentException e) {
- throw new RuntimeException(e);
- } catch (InstantiationException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- } catch (InvocationTargetException e) {
- throw new RuntimeException(e);
+ if (ptgClass == FuncVarPtg.class) {
+ return new FuncVarEval((FuncVarPtg)ptg);
+ }
+ if (ptgClass == ConcatPtg.class) {
+ return new ConcatEval((ConcatPtg)ptg);
+ }
+ if(ptgClass == ExpPtg.class) {
+ // ExpPtg is used for array formulas and shared formulas.
+ // it is currently unsupported, and may not even get implemented here
+ throw new RuntimeException("ExpPtg currently not supported");
}
- return (OperationEval) result;
+ throw new RuntimeException("Unexpected operation ptg class (" + ptgClass.getName() + ")");
}
}
}
}
- private Map _plainValueEntriesByLoc;
+ private Map<Loc, PlainValueCellCacheEntry> _plainValueEntriesByLoc;
public PlainCellCache() {
- _plainValueEntriesByLoc = new HashMap();
+ _plainValueEntriesByLoc = new HashMap<Loc, PlainValueCellCacheEntry>();
}
public void put(Loc key, PlainValueCellCacheEntry cce) {
_plainValueEntriesByLoc.put(key, cce);
_plainValueEntriesByLoc.clear();
}
public PlainValueCellCacheEntry get(Loc key) {
- return (PlainValueCellCacheEntry) _plainValueEntriesByLoc.get(key);
+ return _plainValueEntriesByLoc.get(key);
}
public void remove(Loc key) {
_plainValueEntriesByLoc.remove(key);