Author: echatellier Date: 2012-08-31 18:11:36 +0200 (Fri, 31 Aug 2012) New Revision: 3752 Url: http://forge.codelutin.com/repositories/revision/isis-fish/3752 Log: Extract common interface for ResultStorage Added: trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultDatabaseStorage.java Modified: trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultMappedStorage.java trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultStorage.java trunk/src/main/java/fr/ifremer/isisfish/datastore/SimulationStorage.java Copied: trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultDatabaseStorage.java (from rev 3750, trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultStorage.java) =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultDatabaseStorage.java (rev 0) +++ trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultDatabaseStorage.java 2012-08-31 16:11:36 UTC (rev 3752) @@ -0,0 +1,811 @@ +/* + * #%L + * IsisFish + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2002 - 2011 Ifremer, Code Lutin, Cédric Pineau, Benjamin Poussin, Chatellier Eric + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-2.0.html>. + * #L% + */ + +package fr.ifremer.isisfish.datastore; + +import static org.nuiton.i18n.I18n._; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.collections.map.ReferenceMap; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.math.matrix.MatrixFactory; +import org.nuiton.math.matrix.MatrixIterator; +import org.nuiton.math.matrix.MatrixND; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaException; +import org.nuiton.util.ArrayUtil; +import org.nuiton.util.HashList; + +import fr.ifremer.isisfish.IsisFishDAOHelper; +import fr.ifremer.isisfish.IsisFishException; +import fr.ifremer.isisfish.entities.ActiveRule; +import fr.ifremer.isisfish.entities.ActiveRuleDAO; +import fr.ifremer.isisfish.entities.Population; +import fr.ifremer.isisfish.entities.Result; +import fr.ifremer.isisfish.entities.ResultDAO; +import fr.ifremer.isisfish.export.Export; +import fr.ifremer.isisfish.export.SensitivityExport; +import fr.ifremer.isisfish.rule.Rule; +import fr.ifremer.isisfish.simulator.SimulationContext; +import fr.ifremer.isisfish.simulator.SimulationException; +import fr.ifremer.isisfish.simulator.SimulationPlan; +import fr.ifremer.isisfish.simulator.SimulationResultGetter; +import fr.ifremer.isisfish.types.TimeStep; +import fr.ifremer.isisfish.types.Month; + +/** + * Cette classe permet de conserver des résultats de simulation. Elle permet + * ensuite de les récupérer. + * + * Created: 29 sept. 2004 + * + * @author Benjamin Poussin <poussin@codelutin.com> + * @version $Revision$ + * + * Mise a jour: $Date$ + * par : $Author$ + */ +public class ResultDatabaseStorage implements SimulationResultGetter, ResultStorage { // ResultDatabaseStorage + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ResultDatabaseStorage.class); + + protected SimulationStorage simulation = null; + // transient protected HashMap<String, MatrixND> globalMatrix = new HashMap<String, MatrixND>(); + transient protected ReferenceMap cacheContext = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.WEAK); + + /** cache to maintains some result. key: String(date + ':' + name), value: matrix + * TODO: cache will be more efficient if it keep at min the number of result by year */ + transient protected ReferenceMap cache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT); + /** contains all available result as string: String(date + ':' + name) */ + transient protected Set<String> availableResult = null; + /** result enabled */ + transient protected Set<String> enabledResult = null; + + /** + * Les ResultStorage ne doivent pas etre instancier directement, mais + * recuperer a partir d'un + * {@link fr.ifremer.isisfish.datastore.SimulationStorage#getResultStorage()} + * + * @param simulation storage to get result + */ + public ResultDatabaseStorage(SimulationStorage simulation) { + this.simulation = simulation; + } + + protected void putInCache(TimeStep step, String name, MatrixND mat, TopiaContext context) { + String key = step.getStep() + ":" + name; + putInCache(key, mat, context); + } + + protected void putInCache(String name, MatrixND mat, TopiaContext context) { + if (mat != null) { + cache.put(name, mat); + cacheContext.put(name, context); + } + } + + /** + * Result can be removed from cache when computed result (from multiple step) + * become invalidated by new step result. + * + * @param name result name to remove + */ + protected void removeInCache(String name) { + cache.remove(name); + cacheContext.remove(name); + } + + protected MatrixND getInCache(TimeStep step, String name) { + // do not use toString for step (depend on i18n) + String key = step.getStep() + ":" + name; + MatrixND result = getInCache(key); + return result; + } + + protected MatrixND getInCache(String name) { + MatrixND result = null; + TopiaContext context = (TopiaContext) cacheContext.get(name); + if (context != null && !context.isClosed()) { + // on verifie que le context existe encore car on peut vouloir + // naviguer dans les semantics + result = (MatrixND) cache.get(name); + } + return result; + } + + /** + * Retourne le nom de tous les resultats disponibles le nom est constitué + * de la date et du nom du resultat. + * + * @return available results + */ + protected Set<String> getAvailableResult() { + if (availableResult == null) { + availableResult = new HashSet<String>(); + try { + TopiaContext tx = null; + boolean mustClose = false; + + if (simulation == SimulationContext.get().getSimulationStorage()) { + tx = SimulationContext.get().getDbResult(); + } + + if (tx == null) { + // not in simulation, create transaction + tx = simulation.getStorage().beginTransaction(); + mustClose = true; + } + + List<String> result = (List<String>) tx.findAll("Select " + Result.PROPERTY_RESULT_STEP + "||':'||name from fr.ifremer.isisfish.entities.Result"); + if (mustClose) { + tx.closeContext(); + } + availableResult.addAll(result); + } catch (Exception eee) { + if (log.isWarnEnabled()) { + log.warn("Can't get result available", eee); + } + } + } + return availableResult; + } + + /** + * Verifie si un resultat est disponible pour une date donnée. + * + * @param step + * @param name + * @return {@code true} if result is available + */ + protected boolean isAvailableResult(TimeStep step, String name) { + String key = step.getStep() + ":" + name; + boolean result = getAvailableResult().contains(key); + return result; + } + + /** + * Ajoute un resultat comme etant disponible pour une date donnée. + * + * @param step + * @param name + */ + protected void addAvailableResult(TimeStep step, String name) { + String key = step.getStep() + ":" + name; + getAvailableResult().add(key); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#isEnabled(java.lang.String) + */ + @Override + public boolean isEnabled(String name) { + name = name.trim(); + if (enabledResult == null) { + enabledResult = new HashSet<String>(); + + Collection<String> resultEnabled = simulation.getParameter() + .getResultEnabled(); + enabledResult.addAll(resultEnabled); + + // test on export + List<String> exportNames = simulation.getParameter().getExportNames(); + if (exportNames != null) { + for (String exportName : exportNames) { + ExportStorage storage = ExportStorage.getExport(exportName); + try { + Export export = storage.getNewExportInstance(); + for (String resultName : export.getNecessaryResult()) { + enabledResult.add(resultName); + } + } catch (IsisFishException eee) { + if (log.isWarnEnabled()) { + log.warn(_("isisfish.error.instanciate.export", + exportName), eee); + } + } + } + } + + // test on sensitivity export + List<SensitivityExport> sensitivityExports = simulation + .getParameter().getSensitivityExport(); + if (sensitivityExports != null) { + for (SensitivityExport sensitivityExport : sensitivityExports) { + for (String resultName : sensitivityExport.getNecessaryResult()) { + enabledResult.add(resultName); + } + } + } + + // test on rules + List<Rule> rules = simulation.getParameter().getRules(); + if (rules != null) { + for (Rule rule : rules) { + for (String resultName : rule.getNecessaryResult()) { + enabledResult.add(resultName); + } + } + } + + // test on plans + List<SimulationPlan> plans = simulation.getParameter().getSimulationPlans(); + if (plans != null) { + for (SimulationPlan plan : plans) { + for (String resultName : plan.getNecessaryResult()) { + enabledResult.add(resultName); + } + } + } + log.info("Enabled result: " + enabledResult); + } + boolean result = enabledResult.contains(name); + return result; + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(fr.ifremer.isisfish.types.TimeStep, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(TimeStep step, MatrixND mat) throws IsisFishException { + addResult(false, step, mat.getName(), mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(fr.ifremer.isisfish.types.TimeStep, fr.ifremer.isisfish.entities.Population, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(TimeStep step, Population pop, MatrixND mat) throws IsisFishException { + addResult(false, step, mat.getName(), pop, mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(boolean, fr.ifremer.isisfish.types.TimeStep, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(boolean force, TimeStep step, MatrixND mat) throws IsisFishException { + addResult(force, step, mat.getName(), mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(boolean, fr.ifremer.isisfish.types.TimeStep, fr.ifremer.isisfish.entities.Population, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(boolean force, TimeStep step, Population pop, MatrixND mat) throws IsisFishException { + addResult(force, step, mat.getName(), pop, mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(fr.ifremer.isisfish.types.TimeStep, java.lang.String, fr.ifremer.isisfish.entities.Population, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(TimeStep step, String name, Population pop, MatrixND mat) throws IsisFishException { + addResult(false, step, name, pop, mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(fr.ifremer.isisfish.types.TimeStep, java.lang.String, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(TimeStep step, String name, MatrixND mat) throws IsisFishException { + addResult(false, step, name, mat); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(boolean, fr.ifremer.isisfish.types.TimeStep, java.lang.String, fr.ifremer.isisfish.entities.Population, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(boolean force, TimeStep step, String name, Population pop, MatrixND mat) throws IsisFishException { + if (force || isEnabled(name)) { + doAddResult(step, name + " " + pop, mat); + } + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addResult(boolean, fr.ifremer.isisfish.types.TimeStep, java.lang.String, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(boolean force, TimeStep step, String name, MatrixND mat) throws IsisFishException { + if (force || isEnabled(name)) { + doAddResult(step, name, mat); + } + } + + protected void doAddResult(TimeStep step, String name, MatrixND mat) throws IsisFishException { + try { + TopiaContext tx = null; + boolean mustClose = false; + + if (simulation == SimulationContext.get().getSimulationStorage()) { + tx = SimulationContext.get().getDbResult(); + } + if (tx == null) { + // not in simulation, create transaction + tx = simulation.getStorage().beginTransaction(); + mustClose = true; + } + doAddResult(step, name, mat, tx); + if (mustClose) { + tx.commitTransaction(); + tx.closeContext(); + } + } catch (TopiaException eee) { + log.warn("Can't add result '" + name + "' at step " + step, eee); + } + } + + protected void doAddResult(TimeStep step, String name, MatrixND mat, + TopiaContext tx) throws IsisFishException { + // si la matrice n'a pas de semantique on refuse + for (int i = 0; i < mat.getDimCount(); i++) { + // la semantique n'est pas bonne des qu'il y a un null dedans + if (mat.getSemantic(i).contains(null)) { + throw new SimulationException( + "Erreur le résultat que vous souhaitez enregistrer n'a pas d'information convenable pour la dimension: " + + i + " " + mat.getDimensionName(i)); + } + } + + // on fait une copie pour avoir reellement des resultats independant + // FIXME echatellier 20120829 : faire une copie optimiser + // suivant l'implementation du vector plutot qu'un parcourt + // via un iterateur de semantiques (plus couteux) + MatrixND newMat = mat.copy(); + try { + ResultDAO resultPS = IsisFishDAOHelper.getResultDAO(tx); + Result result = resultPS.create(); + result.setResultStep(step); + result.setName(name); + result.setMatrix(newMat); + resultPS.update(result); + + addAvailableResult(step, name); + putInCache(step, name, newMat, tx); + + // depuis isis fish 4.1.1, le commit est automatique à chaque + // résultat (gain de performance de 20% avec le clearCache) + tx.commitTransaction(); + // vide le cache hibernate. Sans cela, les resultats ne sont + // jamais supprimé du cache car la session n'est close + // qu'à la fin de la simulation + tx.clearCache(); + + // remove from cache result computed by #getMatrix(name) + // beacause, if a new step is added, result become false + // but DO NOT REMOVE result named step + name + removeInCache(name); + + } catch (TopiaException eee) { + log.warn("Can't add result '" + name + "' at step " + step, eee); + } + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#addActiveRule(fr.ifremer.isisfish.types.TimeStep, fr.ifremer.isisfish.rule.Rule) + */ + @Override + public void addActiveRule(TimeStep step, Rule rule) throws IsisFishException { + try { + TopiaContext tx = null; + boolean mustClose = false; + + if (simulation == SimulationContext.get().getSimulationStorage()) { + tx = SimulationContext.get().getDbResult(); + } + if (tx == null) { + // not in simulation, create transaction + tx = simulation.getStorage().beginTransaction(); + mustClose = true; + } + ActiveRuleDAO ps = IsisFishDAOHelper.getActiveRuleDAO(tx); + ActiveRule result = ps.create(); + result.setActiveRuleStep(step); + result.setName(RuleStorage.getName(rule)); + result.setParam(RuleStorage.getParamAsString(rule)); + ps.update(result); + if (mustClose) { + tx.commitTransaction(); + tx.closeContext(); + } + } catch (TopiaException eee) { + throw new IsisFishException("Can't add result", eee); + } + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getResultName() + */ + @Override + public List<String> getResultName() { + + List<String> result = null; + try { + TopiaContext tx = null; + boolean mustClose = false; + + if (simulation == SimulationContext.get().getSimulationStorage()) { + tx = SimulationContext.get().getDbResult(); + } + if (tx == null) { + // not in simulation, create transaction + tx = simulation.getStorage().beginTransaction(); + mustClose = true; + } + ResultDAO resultPS = IsisFishDAOHelper.getResultDAO(tx); + + result = (List<String>) resultPS.getContext() + .findAll("Select distinct name from fr.ifremer.isisfish.entities.Result order by name"); + if (mustClose) { + tx.closeContext(); + } + } catch (TopiaException eee) { + if (log.isWarnEnabled()) { + log.warn("Can't get result name", eee); + } + } + if (result == null) { + result = new ArrayList<String>(); + } + return result; + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(fr.ifremer.isisfish.types.TimeStep, fr.ifremer.isisfish.entities.Population, java.lang.String) + */ + @Override + public MatrixND getMatrix(TimeStep step, Population pop, String name) { + String newName = name + " " + pop; + return getMatrix(step, newName); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(fr.ifremer.isisfish.types.TimeStep, java.lang.String) + */ + @Override + public MatrixND getMatrix(TimeStep step, String name) { + MatrixND mat = getInCache(step, name); + if (mat == null && isAvailableResult(step, name)) { + try { + TopiaContext tx = null; + boolean mustClose = false; + + if (simulation == SimulationContext.get().getSimulationStorage()) { + tx = SimulationContext.get().getDbResult(); + } + if (tx == null) { + // not in simulation, create transaction + tx = simulation.getStorage().beginTransaction(); + mustClose = true; + } + mat = getMatrix(step, name, tx); + if (mustClose) { + // FIXME transaction never closed + // quand peut on fermer la transaction ? + // lorsque plus aucune matrice ne l'utilise. + // donc mettre la matrice et la connexion dans une map + // la matrice dans une weak reference. Des que la matrice + // est liberer faire un close sur la transaction + } else { + // echatellier 20120829 : vidage du cache hibernate + // sinon on fait trop de lecture que la meme transaction + // et le cache hibernate se remplit sans se vider + tx.clearCache(); + } + } catch (Exception eee) { + if (log.isWarnEnabled()) { + log.warn("Can't return matrix '" + name + "' for step " + + step, eee); + } + } + } + return mat; + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(fr.ifremer.isisfish.types.TimeStep, java.lang.String, org.nuiton.topia.TopiaContext) + */ + @Override + public MatrixND getMatrix(TimeStep step, String name, TopiaContext tx) { + MatrixND mat = getInCache(step, name); + if (mat == null && isAvailableResult(step, name)) { + try { + ResultDAO resultPS = IsisFishDAOHelper.getResultDAO(tx); + Result result = resultPS.findByProperties( + Result.PROPERTY_RESULT_STEP, step, + Result.PROPERTY_NAME, name); + if (result != null) { + mat = result.getMatrix(); + putInCache(step, name, mat, tx); + } + } catch (Exception eee) { + if (log.isWarnEnabled()) { + log.warn("Can't return matrix '" + name + "' for step " + + step, eee); + } + } + } + return mat; + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(fr.ifremer.isisfish.entities.Population, java.lang.String) + */ + @Override + public MatrixND getMatrix(Population pop, String name) { + String newName = name + " " + pop; + return getMatrix(newName); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(fr.ifremer.isisfish.entities.Population, java.lang.String, org.nuiton.topia.TopiaContext) + */ + @Override + public MatrixND getMatrix(Population pop, String name, TopiaContext tx) { + String newName = name + " " + pop; + return getMatrix(newName, tx); + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(java.lang.String) + */ + @Override + public MatrixND getMatrix(String name) { + MatrixND resultMat = null; + try { + TopiaContext tx = null; + boolean mustClose = false; + + if (simulation == SimulationContext.get().getSimulationStorage()) { + tx = SimulationContext.get().getDbResult(); + } + if (tx == null) { + // not in simulation, create transaction + tx = simulation.getStorage().beginTransaction(); + mustClose = true; + } + resultMat = getMatrix(name, tx); + if (mustClose) { + // FIXME transaction never closed + // quand peut on fermer la transaction ? + // lorsque plus aucune matrice ne l'utilise. + // donc mettre la matrice et la connexion dans une map + // la matrice dans une weak reference. Des que la matrice + // est liberer faire un close sur la transaction + } else { + // echatellier 20120829 : vidage du cache hibernate + // sinon on fait trop de lecture que la meme transaction + // et le cache hibernate se remplit sans se vider + tx.clearCache(); + } + } catch (TopiaException eee) { + if (log.isWarnEnabled()) { + log.warn("Can't get result: " + name, eee); + } + } + return resultMat; + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(java.lang.String, org.nuiton.topia.TopiaContext) + */ + @Override + public MatrixND getMatrix(String name, TopiaContext tx) { + log.debug("Get result: " + name); + + MatrixND resultMat = getInCache(name); + if (resultMat != null) { + return resultMat; + } + + // recuperation des resultats qui nous interesse + List<Result> results = null; + try { + ResultDAO resultPS = IsisFishDAOHelper.getResultDAO(tx); + results = resultPS.findAllByName(name); + } catch (TopiaException eee) { + if (log.isWarnEnabled()) { + log.warn("Can't get result: " + name, eee); + } + } + + // s'il n'y pas de resultat, on retourne null + if (results == null || results.size() == 0) { + return null; + } + + // Creation des listes pour chaque dimension + + // creation de la liste de date + TimeStep lastStep = getLastStep(); + List<TimeStep> steps = new ArrayList<TimeStep>(); + TimeStep step = new TimeStep(0); + steps.add(step); + while (step.before(lastStep)) { + step = step.next(); + steps.add(step); + } + + if (log.isTraceEnabled()) { + log.trace("Steps list : " + steps); + } + + // recuperation des dimensions des matrices + MatrixND mat = (MatrixND) results.get(0).getMatrix(); + + // recuperation des noms des dimensions + String[] dimNames = new String[1 + mat.getDimCount()]; + dimNames[0] = _("isisfish.common.date"); + for (int i = 1; i < dimNames.length; i++) { + dimNames[i] = mat.getDimensionName(i - 1); + } + + // creation de la semantique pour la matrice resultat. +1 pour les dates + List[] sem = new List[1 + mat.getDimCount()]; + sem[0] = steps; + + for (int i = 1; i < sem.length; i++) { + sem[i] = new HashList(); + } + + for (Result result : results) { + MatrixND mattmp = result.getMatrix(); + if (log.isTraceEnabled()) { + log.trace("Ajout de la semantics: " + + Arrays.asList(mattmp.getSemantics())); + } + + for (int s = 0; s < mattmp.getDimCount(); s++) { + sem[s + 1].addAll(mattmp.getSemantic(s)); + } + } + + if (log.isTraceEnabled()) { + log.trace("La semantique final est: " + Arrays.asList(sem)); + } + + // creation de la matrice resultat + resultMat = MatrixFactory.getInstance().create(name, sem, dimNames); + + // recuperation du resultat pour chaque date de la simulation, de Date(0) à lastDate + for (Result result : results) { + TimeStep d = result.getResultStep(); + mat = result.getMatrix(); + // on met ce resultat dans la matrice result si besoin + if (mat != null) { + // on recupere dans la matrice resultat l'endroit on il faut + // mettre la matrice + MatrixND submat = resultMat.getSubMatrix(0, d, 1); + // on met les valeur de mat dans la sous matrice extraite + for (MatrixIterator mi = mat.iterator(); mi.next();) { + submat.setValue( + ArrayUtil.concat(new Object[] { d }, + mi.getSemanticsCoordinates()), mi.getValue()); + } + } + } + + putInCache(name, resultMat, tx); + return resultMat; + } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getLastStep() + */ + @Override + public TimeStep getLastStep() { + int monthNumber = simulation.getParameter().getNumberOfYear() + * Month.NUMBER_OF_MONTH; + TimeStep result = new TimeStep(monthNumber - 1); // -1 because date begin at 0 + return result; + } + + /* + * @see fr.ifremer.isisfish.simulator.SimulationResultListener#addResult(fr.ifremer.isisfish.simulator.SimulationContext, fr.ifremer.isisfish.types.TimeStep, java.lang.String, org.nuiton.math.matrix.MatrixND) + */ + @Override + public void addResult(SimulationContext context, TimeStep step, String name, + MatrixND mat) throws IsisFishException { + try { + doAddResult(step, name, mat, context.getDbResult()); + } catch (TopiaException eee) { + log.warn(_("Can't add result '%1$s' at date %2$s", name, step), eee); + } + } + + /* + * @see fr.ifremer.isisfish.simulator.SimulationResultGetter#getMatrix(fr.ifremer.isisfish.simulator.SimulationContext, fr.ifremer.isisfish.types.TimeStep, java.lang.String) + */ + @Override + public MatrixND getMatrix(SimulationContext context, TimeStep step, String name) { + MatrixND result = null; + try { + result = getMatrix(step, name, context.getDbResult()); + } catch (TopiaException eee) { + if (log.isWarnEnabled()) { + log.warn(_("Can't get result: %1$s", name), eee); + } + } + return result; + } + + /* + * @see fr.ifremer.isisfish.simulator.SimulationResultGetter#getMatrix(fr.ifremer.isisfish.simulator.SimulationContext, java.lang.String) + */ + @Override + public MatrixND getMatrix(SimulationContext context, String name) { + MatrixND result = null; + try { + result = getMatrix(name, context.getDbResult()); + } catch (TopiaException eee) { + if (log.isWarnEnabled()) { + log.warn(_("Can't get result: %1$s", name), eee); + } + } + return result; + } + + /* + * @see fr.ifremer.isisfish.simulator.SimulationListener#afterSimulation(fr.ifremer.isisfish.simulator.SimulationContext) + */ + @Override + public void afterSimulation(SimulationContext context) { + } + + /* + * @see fr.ifremer.isisfish.simulator.SimulationListener#beforeSimulation(fr.ifremer.isisfish.simulator.SimulationContext) + */ + @Override + public void beforeSimulation(SimulationContext context) { + } + + // public void addActivatedRule(ResultStorage self, Date date, RegleParam rule){ + // List rules = (List)activatedRules.get(date); + // if(rules == null){ + // activatedRules.put(date, rules = new LinkedList()); + // } + // rules.add(rule); + // } + + // /** + // * Retourne pour une date données tous les RegleParam qui ont été activé + // * a la date demandé. + // * @return une list de {@link fr.ifremer.nodb.RegleParam} + // */ + // public List getActivatedRule(ResultStorage self, Date date){ + // List rules = (List)activatedRules.get(date); + // if(rules == null){ + // activatedRules.put(date, rules = new LinkedList()); + // } + // return rules; + // } + +} // ResultDatabaseStorage Modified: trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultMappedStorage.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultMappedStorage.java 2012-08-31 14:12:18 UTC (rev 3751) +++ trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultMappedStorage.java 2012-08-31 16:11:36 UTC (rev 3752) @@ -5,7 +5,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2002 - 2011 Ifremer, Code Lutin, Cédric Pineau, Benjamin Poussin, Chatellier Eric + * Copyright (C) 2012 Ifremer, Code Lutin, Benjamin Poussin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -83,7 +83,7 @@ * par : $Author$ */ public class ResultMappedStorage implements SimulationResultListener, - SimulationResultGetter { // ResultStorage + SimulationResultGetter, ResultStorage { // ResultStorage /** to use log facility, just put in your code: log.info(\"...\"); */ static private Log log = LogFactory.getLog(ResultMappedStorage.class); @@ -209,7 +209,6 @@ sems[i].add(s); } } - int size = (int) raf.getFilePointer(); int dataOffset = offset + size; @@ -602,6 +601,15 @@ String newName = name + " " + pop; return getMatrix(newName, null); } + + /* (non-Javadoc) + * @see fr.ifremer.isisfish.datastore.ResultStorage#getMatrix(fr.ifremer.isisfish.entities.Population, java.lang.String, org.nuiton.topia.TopiaContext) + */ + @Override + public MatrixND getMatrix(Population pop, String name, TopiaContext tx) { + String newName = name + " " + pop; + return getMatrix(newName, tx); + } /** * Retourne une matrice contenant tous les pas de temps. Modified: trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultStorage.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultStorage.java 2012-08-31 14:12:18 UTC (rev 3751) +++ trunk/src/main/java/fr/ifremer/isisfish/datastore/ResultStorage.java 2012-08-31 16:11:36 UTC (rev 3752) @@ -1,214 +1,22 @@ -/* - * #%L - * IsisFish - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2002 - 2011 Ifremer, Code Lutin, Cédric Pineau, Benjamin Poussin, Chatellier Eric - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 2 of the - * License, or (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-2.0.html>. - * #L% - */ - package fr.ifremer.isisfish.datastore; -import static org.nuiton.i18n.I18n._; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import org.apache.commons.collections.map.ReferenceMap; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.HibernateException; -import org.nuiton.math.matrix.MatrixFactory; -import org.nuiton.math.matrix.MatrixIterator; import org.nuiton.math.matrix.MatrixND; import org.nuiton.topia.TopiaContext; -import org.nuiton.topia.TopiaException; -import org.nuiton.topia.framework.TopiaContextImpl; -import org.nuiton.util.ArrayUtil; -import org.nuiton.util.HashList; -import fr.ifremer.isisfish.IsisFishDAOHelper; import fr.ifremer.isisfish.IsisFishException; -import fr.ifremer.isisfish.entities.ActiveRule; -import fr.ifremer.isisfish.entities.ActiveRuleDAO; import fr.ifremer.isisfish.entities.Population; -import fr.ifremer.isisfish.entities.Result; -import fr.ifremer.isisfish.entities.ResultDAO; import fr.ifremer.isisfish.export.Export; import fr.ifremer.isisfish.export.SensitivityExport; import fr.ifremer.isisfish.rule.Rule; -import fr.ifremer.isisfish.simulator.SimulationContext; -import fr.ifremer.isisfish.simulator.SimulationException; import fr.ifremer.isisfish.simulator.SimulationPlan; -import fr.ifremer.isisfish.simulator.SimulationResultGetter; import fr.ifremer.isisfish.simulator.SimulationResultListener; import fr.ifremer.isisfish.types.TimeStep; -import fr.ifremer.isisfish.types.Month; -/** - * Cette classe permet de conserver des résultats de simulation. Elle permet - * ensuite de les récupérer. - * - * Created: 29 sept. 2004 - * - * @author Benjamin Poussin <poussin@codelutin.com> - * @version $Revision$ - * - * Mise a jour: $Date$ - * par : $Author$ - */ -public class ResultStorage implements SimulationResultListener, - SimulationResultGetter { // ResultStorage +public interface ResultStorage extends SimulationResultListener { - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private Log log = LogFactory.getLog(ResultStorage.class); - - protected SimulationStorage simulation = null; - // transient protected HashMap<String, MatrixND> globalMatrix = new HashMap<String, MatrixND>(); - transient protected ReferenceMap cacheContext = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.WEAK); - - /** cache to maintains some result. key: String(date + ':' + name), value: matrix - * TODO: cache will be more efficient if it keep at min the number of result by year */ - transient protected ReferenceMap cache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT); - /** contains all available result as string: String(date + ':' + name) */ - transient protected Set<String> availableResult = null; - /** result enabled */ - transient protected Set<String> enabledResult = null; - /** - * Les ResultStorage ne doivent pas etre instancier directement, mais - * recuperer a partir d'un - * {@link fr.ifremer.isisfish.datastore.SimulationStorage#getResultStorage()} - * - * @param simulation storage to get result - */ - public ResultStorage(SimulationStorage simulation) { - this.simulation = simulation; - } - - protected void putInCache(TimeStep step, String name, MatrixND mat, TopiaContext context) { - String key = step.getStep() + ":" + name; - putInCache(key, mat, context); - } - - protected void putInCache(String name, MatrixND mat, TopiaContext context) { - if (mat != null) { - cache.put(name, mat); - cacheContext.put(name, context); - } - } - - /** - * Result can be removed from cache when computed result (from multiple step) - * become invalidated by new step result. - * - * @param name result name to remove - */ - protected void removeInCache(String name) { - cache.remove(name); - cacheContext.remove(name); - } - - protected MatrixND getInCache(TimeStep step, String name) { - // do not use toString for step (depend on i18n) - String key = step.getStep() + ":" + name; - MatrixND result = getInCache(key); - return result; - } - - protected MatrixND getInCache(String name) { - MatrixND result = null; - TopiaContext context = (TopiaContext) cacheContext.get(name); - if (context != null && !context.isClosed()) { - // on verifie que le context existe encore car on peut vouloir - // naviguer dans les semantics - result = (MatrixND) cache.get(name); - } - return result; - } - - /** - * Retourne le nom de tous les resultats disponibles le nom est constitué - * de la date et du nom du resultat. - * - * @return available results - */ - protected Set<String> getAvailableResult() { - if (availableResult == null) { - availableResult = new HashSet<String>(); - try { - TopiaContext tx = null; - boolean mustClose = false; - - if (simulation == SimulationContext.get().getSimulationStorage()) { - tx = SimulationContext.get().getDbResult(); - } - - if (tx == null) { - // not in simulation, create transaction - tx = simulation.getStorage().beginTransaction(); - mustClose = true; - } - - List<String> result = (List<String>) tx.findAll("Select " + Result.PROPERTY_RESULT_STEP + "||':'||name from fr.ifremer.isisfish.entities.Result"); - if (mustClose) { - tx.closeContext(); - } - availableResult.addAll(result); - } catch (Exception eee) { - if (log.isWarnEnabled()) { - log.warn("Can't get result available", eee); - } - } - } - return availableResult; - } - - /** - * Verifie si un resultat est disponible pour une date donnée. - * - * @param step - * @param name - * @return {@code true} if result is available - */ - protected boolean isAvailableResult(TimeStep step, String name) { - String key = step.getStep() + ":" + name; - boolean result = getAvailableResult().contains(key); - return result; - } - - /** - * Ajoute un resultat comme etant disponible pour une date donnée. - * - * @param step - * @param name - */ - protected void addAvailableResult(TimeStep step, String name) { - String key = step.getStep() + ":" + name; - getAvailableResult().add(key); - } - - /** * Permet de savoir si lorsque l'on ajoutera ce resultat, il sera * sauvé ou non. * @@ -223,241 +31,41 @@ * @param name result name * @return {@code true} if result is enabled */ - public boolean isEnabled(String name) { - name = name.trim(); - if (enabledResult == null) { - enabledResult = new HashSet<String>(); + public boolean isEnabled(String name); - Collection<String> resultEnabled = simulation.getParameter() - .getResultEnabled(); - enabledResult.addAll(resultEnabled); + public void addResult(TimeStep step, MatrixND mat) throws IsisFishException; - // test on export - List<String> exportNames = simulation.getParameter().getExportNames(); - if (exportNames != null) { - for (String exportName : exportNames) { - ExportStorage storage = ExportStorage.getExport(exportName); - try { - Export export = storage.getNewExportInstance(); - for (String resultName : export.getNecessaryResult()) { - enabledResult.add(resultName); - } - } catch (IsisFishException eee) { - if (log.isWarnEnabled()) { - log.warn(_("isisfish.error.instanciate.export", - exportName), eee); - } - } - } - } + public void addResult(TimeStep step, Population pop, MatrixND mat) + throws IsisFishException; - // test on sensitivity export - List<SensitivityExport> sensitivityExports = simulation - .getParameter().getSensitivityExport(); - if (sensitivityExports != null) { - for (SensitivityExport sensitivityExport : sensitivityExports) { - for (String resultName : sensitivityExport.getNecessaryResult()) { - enabledResult.add(resultName); - } - } - } + public void addResult(boolean force, TimeStep step, MatrixND mat) + throws IsisFishException; - // test on rules - List<Rule> rules = simulation.getParameter().getRules(); - if (rules != null) { - for (Rule rule : rules) { - for (String resultName : rule.getNecessaryResult()) { - enabledResult.add(resultName); - } - } - } + public void addResult(boolean force, TimeStep step, Population pop, + MatrixND mat) throws IsisFishException; - // test on plans - List<SimulationPlan> plans = simulation.getParameter().getSimulationPlans(); - if (plans != null) { - for (SimulationPlan plan : plans) { - for (String resultName : plan.getNecessaryResult()) { - enabledResult.add(resultName); - } - } - } - log.info("Enabled result: " + enabledResult); - } - boolean result = enabledResult.contains(name); - return result; - } + public void addResult(TimeStep step, String name, Population pop, + MatrixND mat) throws IsisFishException; - public void addResult(TimeStep step, MatrixND mat) throws IsisFishException { - addResult(false, step, mat.getName(), mat); - } + public void addResult(TimeStep step, String name, MatrixND mat) + throws IsisFishException; - public void addResult(TimeStep step, Population pop, MatrixND mat) throws IsisFishException { - addResult(false, step, mat.getName(), pop, mat); - } + public void addResult(boolean force, TimeStep step, String name, + Population pop, MatrixND mat) throws IsisFishException; - public void addResult(boolean force, TimeStep step, MatrixND mat) throws IsisFishException { - addResult(force, step, mat.getName(), mat); - } + public void addResult(boolean force, TimeStep step, String name, + MatrixND mat) throws IsisFishException; - public void addResult(boolean force, TimeStep step, Population pop, MatrixND mat) throws IsisFishException { - addResult(force, step, mat.getName(), pop, mat); - } + public void addActiveRule(TimeStep step, Rule rule) + throws IsisFishException; - public void addResult(TimeStep step, String name, Population pop, MatrixND mat) throws IsisFishException { - addResult(false, step, name, pop, mat); - } - - public void addResult(TimeStep step, String name, MatrixND mat) throws IsisFishException { - addResult(false, step, name, mat); - } - - public void addResult(boolean force, TimeStep step, String name, Population pop, MatrixND mat) throws IsisFishException { - if (force || isEnabled(name)) { - doAddResult(step, name + " " + pop, mat); - } - } - - public void addResult(boolean force, TimeStep step, String name, MatrixND mat) throws IsisFishException { - if (force || isEnabled(name)) { - doAddResult(step, name, mat); - } - } - - protected void doAddResult(TimeStep step, String name, MatrixND mat) throws IsisFishException { - try { - TopiaContext tx = null; - boolean mustClose = false; - - if (simulation == SimulationContext.get().getSimulationStorage()) { - tx = SimulationContext.get().getDbResult(); - } - if (tx == null) { - // not in simulation, create transaction - tx = simulation.getStorage().beginTransaction(); - mustClose = true; - } - doAddResult(step, name, mat, tx); - if (mustClose) { - tx.commitTransaction(); - tx.closeContext(); - } - } catch (TopiaException eee) { - log.warn("Can't add result '" + name + "' at step " + step, eee); - } - } - - protected void doAddResult(TimeStep step, String name, MatrixND mat, - TopiaContext tx) throws IsisFishException { - // si la matrice n'a pas de semantique on refuse - for (int i = 0; i < mat.getDimCount(); i++) { - // la semantique n'est pas bonne des qu'il y a un null dedans - if (mat.getSemantic(i).contains(null)) { - throw new SimulationException( - "Erreur le résultat que vous souhaitez enregistrer n'a pas d'information convenable pour la dimension: " - + i + " " + mat.getDimensionName(i)); - } - } - - // on fait une copie pour avoir reellement des resultats independant - // FIXME echatellier 20120829 : faire une copie optimiser - // suivant l'implementation du vector plutot qu'un parcourt - // via un iterateur de semantiques (plus couteux) - MatrixND newMat = mat.copy(); - try { - ResultDAO resultPS = IsisFishDAOHelper.getResultDAO(tx); - Result result = resultPS.create(); - result.setResultStep(step); - result.setName(name); - result.setMatrix(newMat); - resultPS.update(result); - - addAvailableResult(step, name); - putInCache(step, name, newMat, tx); - - // depuis isis fish 4.1.1, le commit est automatique à chaque - // résultat (gain de performance de 20% avec le clearCache) - tx.commitTransaction(); - // vide le cache hibernate. Sans cela, les resultats ne sont - // jamais supprimé du cache car la session n'est close - // qu'à la fin de la simulation - tx.clearCache(); - - // remove from cache result computed by #getMatrix(name) - // beacause, if a new step is added, result become false - // but DO NOT REMOVE result named step + name - removeInCache(name); - - } catch (TopiaException eee) { - log.warn("Can't add result '" + name + "' at step " + step, eee); - } - } - - public void addActiveRule(TimeStep step, Rule rule) throws IsisFishException { - try { - TopiaContext tx = null; - boolean mustClose = false; - - if (simulation == SimulationContext.get().getSimulationStorage()) { - tx = SimulationContext.get().getDbResult(); - } - if (tx == null) { - // not in simulation, create transaction - tx = simulation.getStorage().beginTransaction(); - mustClose = true; - } - ActiveRuleDAO ps = IsisFishDAOHelper.getActiveRuleDAO(tx); - ActiveRule result = ps.create(); - result.setActiveRuleStep(step); - result.setName(RuleStorage.getName(rule)); - result.setParam(RuleStorage.getParamAsString(rule)); - ps.update(result); - if (mustClose) { - tx.commitTransaction(); - tx.closeContext(); - } - } catch (TopiaException eee) { - throw new IsisFishException("Can't add result", eee); - } - } - /** * Retourne la liste de tous les résultats. Si le résultat est categorisé * par une population alors le nom de la population est automatiquement * ajouté au nom du résultat. */ - public List<String> getResultName() { + public List<String> getResultName(); - List<String> result = null; - try { - TopiaContext tx = null; - boolean mustClose = false; - - if (simulation == SimulationContext.get().getSimulationStorage()) { - tx = SimulationContext.get().getDbResult(); - } - if (tx == null) { - // not in simulation, create transaction - tx = simulation.getStorage().beginTransaction(); - mustClose = true; - } - ResultDAO resultPS = IsisFishDAOHelper.getResultDAO(tx); - - result = (List<String>) resultPS.getContext() - .findAll("Select distinct name from fr.ifremer.isisfish.entities.Result order by name"); - if (mustClose) { - tx.closeContext(); - } - } catch (TopiaException eee) { - if (log.isWarnEnabled()) { - log.warn("Can't get result name", eee); - } - } - if (result == null) { - result = new ArrayList<String>(); - } - return result; - } - /** * Retourne la matrice stocke pour un pas de temps * @param step le pas de temps que l'on souhaite @@ -466,50 +74,10 @@ * @return La matrice demandée ou null si aucune matrice ne correspond a * la demande. */ - public MatrixND getMatrix(TimeStep step, Population pop, String name) { - String newName = name + " " + pop; - return getMatrix(step, newName); - } + public MatrixND getMatrix(TimeStep step, Population pop, String name); - public MatrixND getMatrix(TimeStep step, String name) { - MatrixND mat = getInCache(step, name); - if (mat == null && isAvailableResult(step, name)) { - try { - TopiaContext tx = null; - boolean mustClose = false; + public MatrixND getMatrix(TimeStep step, String name); - if (simulation == SimulationContext.get().getSimulationStorage()) { - tx = SimulationContext.get().getDbResult(); - } - if (tx == null) { - // not in simulation, create transaction - tx = simulation.getStorage().beginTransaction(); - mustClose = true; - } - mat = getMatrix(step, name, tx); - if (mustClose) { - // FIXME transaction never closed - // quand peut on fermer la transaction ? - // lorsque plus aucune matrice ne l'utilise. - // donc mettre la matrice et la connexion dans une map - // la matrice dans une weak reference. Des que la matrice - // est liberer faire un close sur la transaction - } else { - // echatellier 20120829 : vidage du cache hibernate - // sinon on fait trop de lecture que la meme transaction - // et le cache hibernate se remplit sans se vider - tx.clearCache(); - } - } catch (Exception eee) { - if (log.isWarnEnabled()) { - log.warn("Can't return matrix '" + name + "' for step " - + step, eee); - } - } - } - return mat; - } - /** * Retourne la matrice stocke pour un pas de temps. * @@ -519,37 +87,14 @@ * @return La matrice demandée ou {@code null} si aucune matrice ne correspond a * la demande. */ - public MatrixND getMatrix(TimeStep step, String name, TopiaContext tx) { - MatrixND mat = getInCache(step, name); - if (mat == null && isAvailableResult(step, name)) { - try { - ResultDAO resultPS = IsisFishDAOHelper.getResultDAO(tx); - Result result = resultPS.findByProperties( - Result.PROPERTY_RESULT_STEP, step, - Result.PROPERTY_NAME, name); - if (result != null) { - mat = result.getMatrix(); - putInCache(step, name, mat, tx); - } - } catch (Exception eee) { - if (log.isWarnEnabled()) { - log.warn("Can't return matrix '" + name + "' for step " - + step, eee); - } - } - } - return mat; - } + public MatrixND getMatrix(TimeStep step, String name, TopiaContext tx); /** * Retourne une matrice contenant tous les pas de temps. * @param pop la population pour lequel on souhaite la matrice * @param name le nom des resultats dont on veut une matrice globale. */ - public MatrixND getMatrix(Population pop, String name) { - String newName = name + " " + pop; - return getMatrix(newName); - } + public MatrixND getMatrix(Population pop, String name); /** * Retourne une matrice contenant tous les pas de temps. @@ -558,245 +103,25 @@ * @param tx la transaction a utiliser * @since 4.1.0.0 */ - public MatrixND getMatrix(Population pop, String name, TopiaContext tx) { - String newName = name + " " + pop; - return getMatrix(newName, tx); - } + public MatrixND getMatrix(Population pop, String name, TopiaContext tx); /** * Retourne une matrice contenant tous les pas de temps. * @param name le nom des resultats dont on veut une matrice globale. */ - public MatrixND getMatrix(String name) { - MatrixND resultMat = null; - try { - TopiaContext tx = null; - boolean mustClose = false; + public MatrixND getMatrix(String name); - if (simulation == SimulationContext.get().getSimulationStorage()) { - tx = SimulationContext.get().getDbResult(); - } - if (tx == null) { - // not in simulation, create transaction - tx = simulation.getStorage().beginTransaction(); - mustClose = true; - } - resultMat = getMatrix(name, tx); - if (mustClose) { - // FIXME transaction never closed - // quand peut on fermer la transaction ? - // lorsque plus aucune matrice ne l'utilise. - // donc mettre la matrice et la connexion dans une map - // la matrice dans une weak reference. Des que la matrice - // est liberer faire un close sur la transaction - } else { - // echatellier 20120829 : vidage du cache hibernate - // sinon on fait trop de lecture que la meme transaction - // et le cache hibernate se remplit sans se vider - tx.clearCache(); - } - } catch (TopiaException eee) { - if (log.isWarnEnabled()) { - log.warn("Can't get result: " + name, eee); - } - } - return resultMat; - } - /** * Retourne une matrice contenant tous les pas de temps. * @param name le nom des resultats dont on veut une matrice globale. * @param tx TopiaContext a utiliser pour recuperer les resultats et donc les semantiques */ - public MatrixND getMatrix(String name, TopiaContext tx) { - log.debug("Get result: " + name); + public MatrixND getMatrix(String name, TopiaContext tx); - MatrixND resultMat = getInCache(name); - if (resultMat != null) { - return resultMat; - } - - // recuperation des resultats qui nous interesse - List<Result> results = null; - try { - ResultDAO resultPS = IsisFishDAOHelper.getResultDAO(tx); - results = resultPS.findAllByName(name); - } catch (TopiaException eee) { - if (log.isWarnEnabled()) { - log.warn("Can't get result: " + name, eee); - } - } - - // s'il n'y pas de resultat, on retourne null - if (results == null || results.size() == 0) { - return null; - } - - // Creation des listes pour chaque dimension - - // creation de la liste de date - TimeStep lastStep = getLastStep(); - List<TimeStep> steps = new ArrayList<TimeStep>(); - TimeStep step = new TimeStep(0); - steps.add(step); - while (step.before(lastStep)) { - step = step.next(); - steps.add(step); - } - - if (log.isTraceEnabled()) { - log.trace("Steps list : " + steps); - } - - // recuperation des dimensions des matrices - MatrixND mat = (MatrixND) results.get(0).getMatrix(); - - // recuperation des noms des dimensions - String[] dimNames = new String[1 + mat.getDimCount()]; - dimNames[0] = _("isisfish.common.date"); - for (int i = 1; i < dimNames.length; i++) { - dimNames[i] = mat.getDimensionName(i - 1); - } - - // creation de la semantique pour la matrice resultat. +1 pour les dates - List[] sem = new List[1 + mat.getDimCount()]; - sem[0] = steps; - - for (int i = 1; i < sem.length; i++) { - sem[i] = new HashList(); - } - - for (Result result : results) { - MatrixND mattmp = result.getMatrix(); - if (log.isTraceEnabled()) { - log.trace("Ajout de la semantics: " - + Arrays.asList(mattmp.getSemantics())); - } - - for (int s = 0; s < mattmp.getDimCount(); s++) { - sem[s + 1].addAll(mattmp.getSemantic(s)); - } - } - - if (log.isTraceEnabled()) { - log.trace("La semantique final est: " + Arrays.asList(sem)); - } - - // creation de la matrice resultat - resultMat = MatrixFactory.getInstance().create(name, sem, dimNames); - - // recuperation du resultat pour chaque date de la simulation, de Date(0) à lastDate - for (Result result : results) { - TimeStep d = result.getResultStep(); - mat = result.getMatrix(); - // on met ce resultat dans la matrice result si besoin - if (mat != null) { - // on recupere dans la matrice resultat l'endroit on il faut - // mettre la matrice - MatrixND submat = resultMat.getSubMatrix(0, d, 1); - // on met les valeur de mat dans la sous matrice extraite - for (MatrixIterator mi = mat.iterator(); mi.next();) { - submat.setValue( - ArrayUtil.concat(new Object[] { d }, - mi.getSemanticsCoordinates()), mi.getValue()); - } - } - } - - putInCache(name, resultMat, tx); - return resultMat; - } - /** * Get last simulation date. * * @return last simulation date */ - public TimeStep getLastStep() { - int monthNumber = simulation.getParameter().getNumberOfYear() - * Month.NUMBER_OF_MONTH; - TimeStep result = new TimeStep(monthNumber - 1); // -1 because date begin at 0 - return result; - } - - /* - * @see fr.ifremer.isisfish.simulator.SimulationResultListener#addResult(fr.ifremer.isisfish.simulator.SimulationContext, fr.ifremer.isisfish.types.TimeStep, java.lang.String, org.nuiton.math.matrix.MatrixND) - */ - @Override - public void addResult(SimulationContext context, TimeStep step, String name, - MatrixND mat) throws IsisFishException { - try { - doAddResult(step, name, mat, context.getDbResult()); - } catch (TopiaException eee) { - log.warn(_("Can't add result '%1$s' at date %2$s", name, step), eee); - } - } - - /* - * @see fr.ifremer.isisfish.simulator.SimulationResultGetter#getMatrix(fr.ifremer.isisfish.simulator.SimulationContext, fr.ifremer.isisfish.types.TimeStep, java.lang.String) - */ - @Override - public MatrixND getMatrix(SimulationContext context, TimeStep step, String name) { - MatrixND result = null; - try { - result = getMatrix(step, name, context.getDbResult()); - } catch (TopiaException eee) { - if (log.isWarnEnabled()) { - log.warn(_("Can't get result: %1$s", name), eee); - } - } - return result; - } - - /* - * @see fr.ifremer.isisfish.simulator.SimulationResultGetter#getMatrix(fr.ifremer.isisfish.simulator.SimulationContext, java.lang.String) - */ - @Override - public MatrixND getMatrix(SimulationContext context, String name) { - MatrixND result = null; - try { - result = getMatrix(name, context.getDbResult()); - } catch (TopiaException eee) { - if (log.isWarnEnabled()) { - log.warn(_("Can't get result: %1$s", name), eee); - } - } - return result; - } - - /* - * @see fr.ifremer.isisfish.simulator.SimulationListener#afterSimulation(fr.ifremer.isisfish.simulator.SimulationContext) - */ - @Override - public void afterSimulation(SimulationContext context) { - } - - /* - * @see fr.ifremer.isisfish.simulator.SimulationListener#beforeSimulation(fr.ifremer.isisfish.simulator.SimulationContext) - */ - @Override - public void beforeSimulation(SimulationContext context) { - } - - // public void addActivatedRule(ResultStorage self, Date date, RegleParam rule){ - // List rules = (List)activatedRules.get(date); - // if(rules == null){ - // activatedRules.put(date, rules = new LinkedList()); - // } - // rules.add(rule); - // } - - // /** - // * Retourne pour une date données tous les RegleParam qui ont été activé - // * a la date demandé. - // * @return une list de {@link fr.ifremer.nodb.RegleParam} - // */ - // public List getActivatedRule(ResultStorage self, Date date){ - // List rules = (List)activatedRules.get(date); - // if(rules == null){ - // activatedRules.put(date, rules = new LinkedList()); - // } - // return rules; - // } - -} // ResultStorage + public TimeStep getLastStep(); +} Modified: trunk/src/main/java/fr/ifremer/isisfish/datastore/SimulationStorage.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/datastore/SimulationStorage.java 2012-08-31 14:12:18 UTC (rev 3751) +++ trunk/src/main/java/fr/ifremer/isisfish/datastore/SimulationStorage.java 2012-08-31 16:11:36 UTC (rev 3752) @@ -444,15 +444,20 @@ } /** - * Get simulation {@link ResultStorage}. + * Get simulation {@link ResultDatabaseStorage}. * - * @return le {@link ResultStorage} a utiliser pour cette simulation + * @return le {@link ResultDatabaseStorage} a utiliser pour cette simulation + * @throws StorageException */ - public ResultStorage getResultStorage() { + public ResultStorage getResultStorage() throws StorageException { if (resultStorage == null) { - // FIXME poussin 20120831 en fonction de la version de la base // instancier un ResultStorage ou un ResultMappedStorage - resultStorage = new ResultStorage(this); + //resultStorage = new ResultDatabaseStorage(this); + try { + resultStorage = new ResultMappedStorage(this); + } catch (IOException ex) { + throw new StorageException("Can't get storage", ex); + } } return resultStorage; }
participants (1)
-
echatellier@users.forge.codelutin.com