/******************************************************************************* * * Copyright 2010 Alexandru Craciun, and individual contributors as indicated * by the @authors tag. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. ******************************************************************************/ package org.netxilia.api.impl.model; import java.util.ArrayList; import java.util.List; import org.netxilia.api.command.IMoreCellCommands; import org.netxilia.api.exception.NetxiliaBusinessException; import org.netxilia.api.exception.NotFoundException; import org.netxilia.api.exception.StorageException; import org.netxilia.api.formula.CyclicDependenciesException; import org.netxilia.api.formula.FormulaParsingException; import org.netxilia.api.formula.IFormulaContext; import org.netxilia.api.impl.dependencies.SheetAliasDependencyManager; import org.netxilia.api.impl.dependencies.SheetDependencyManager; import org.netxilia.api.impl.dependencies.WorkbookAliasDependencyManager; import org.netxilia.api.impl.dependencies.WorkbookDependencyManager; import org.netxilia.api.model.CellData; import org.netxilia.api.reference.AreaReference; import org.netxilia.api.reference.CellReference; import org.netxilia.api.user.AclPrivilegedMode; import org.netxilia.api.utils.Matrix; import org.netxilia.spi.formula.IFormulaParser; /** * Go through all the cells of a sheet at load time to retrieve the dependencies and to recalculate non-cacheable * formulas. * * @author <a href='mailto:ax.craciun@gmail.com'>Alexandru Craciun</a> * */ public class SheetInitializationProcess { private static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(SheetInitializationProcess.class); private final SheetActor sheet; private final IFormulaParser formulaParser; private final WorkbookDependencyManager dependencyManager; private final WorkbookAliasDependencyManager aliasDependencyManager; private final IMoreCellCommands moreCellCommands; public SheetInitializationProcess(SheetActor sheet, IFormulaParser parser, WorkbookDependencyManager dependencyManager, WorkbookAliasDependencyManager aliasDependencyManager, IMoreCellCommands moreCellCommands) { this.sheet = sheet; this.formulaParser = parser; this.dependencyManager = dependencyManager; this.aliasDependencyManager = aliasDependencyManager; this.moreCellCommands = moreCellCommands; start(); } private void start() { // load the cells in the same thread Matrix<CellData> cells = sheet.getCells(AreaReference.ALL); boolean privilegeWasSet = AclPrivilegedMode.set(); try { SheetDependencyManager sheetMgr = null; SheetAliasDependencyManager sheetAliasMgr = null; try { sheetMgr = dependencyManager.getManagerForSheet(sheet.getName()); sheetAliasMgr = aliasDependencyManager.getManagerForSheet(sheet.getName()); } catch (StorageException e) { log.error("Could not register depedency manager for sheet: " + sheet.getName() + ":" + e, e); return; } catch (NotFoundException e) { log.error("Could not register depedency manager for sheet: " + sheet.getName() + ":" + e, e); return; } List<CellReference> refreshCells = new ArrayList<CellReference>(); for (CellData cell : cells) { if (cell.getFormula() != null) { try { IFormulaContext context = new SheetActorFormulaContext(sheet, cell.getReference()); sheetMgr.setDependencies(cell.getFormula(), context); sheetAliasMgr.setAliasDependencies(cell.getFormula(), context); if (!formulaParser.isCacheable(cell.getFormula())) { refreshCells.add(cell.getReference()); } } catch (FormulaParsingException e) { log.error("Cannot refresh cell " + cell + ":" + e, e); } catch (CyclicDependenciesException e) { log.error("Cannot refresh cell " + cell + ":" + e, e); } catch (StorageException e) { log.error("Cannot refresh cell " + cell + ":" + e, e); } } } try { if (!refreshCells.isEmpty()) { sheet.sendCommandNoUndo(moreCellCommands.refresh(refreshCells, false)); } } catch (NotFoundException e) { log.error("Cannot refresh cells " + refreshCells + ":" + e, e); } catch (CyclicDependenciesException e) { log.error("Cannot refresh cells " + refreshCells + ":" + e, e); } catch (NetxiliaBusinessException e) { log.error("Cannot refresh cells " + refreshCells + ":" + e, e); } } finally { if (!privilegeWasSet) { AclPrivilegedMode.clear(); } } } }