Author: chatellier Date: 2010-11-05 16:39:07 +0000 (Fri, 05 Nov 2010) New Revision: 174 Log: Sauvegarde et relecture des selections (properties) Sauvegarde et relecture des commandes (selection et control) Added: trunk/coser-business/src/main/java/fr/ifremer/coser/CoserUtils.java Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/CoserConstants.java trunk/coser-business/src/main/java/fr/ifremer/coser/bean/Selection.java trunk/coser-business/src/main/java/fr/ifremer/coser/command/Command.java trunk/coser-business/src/main/java/fr/ifremer/coser/command/DeleteLineCommand.java trunk/coser-business/src/main/java/fr/ifremer/coser/command/MergeSpeciesCommand.java trunk/coser-business/src/main/java/fr/ifremer/coser/command/ModifyFieldCommand.java trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java trunk/coser-business/src/test/java/fr/ifremer/coser/services/CoserTestAbstract.java trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionDetailsView.jaxx trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListCheckBoxRenderer.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListRenderer.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListTestModel.java Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/CoserConstants.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/CoserConstants.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/CoserConstants.java 2010-11-05 16:39:07 UTC (rev 174) @@ -55,6 +55,9 @@ /** Nom du dossier de sauvegarde des selections. */ public static final String STORAGE_SELECTION_DIRECTORY = "selections"; + + /** Nom du dossier de sauvegarde des données d'une selections. */ + public static final String STORAGE_DATA_SELECTION_DIRECTORY = "data"; /** Suffix des nom de fichiers data apres control. */ public static final String STORAGE_CONTROL_SUFFIX = "_co"; @@ -69,8 +72,14 @@ public static final String STORAGE_CSV_EXTENSION = ".csv"; /** Nom du fichier des historiques de modification */ - public static final String HISTORY_FILENAME = "history.csv"; + public static final String STORAGE_HISTORY_FILENAME = "history"; + /** Extension du fichier d'historique pour le control. */ + public static final String STORAGE_HISTORY_CONTROL_EXTENSION = ".chc"; + + /** Extension du fichier d'historique pour la selection. */ + public static final String STORAGE_HISTORY_SELECTION_EXTENSION = ".chs"; + /** Categories des données manipulées. */ public static enum Category { CATCH(n_("coser.business.category.catch"), "catch"), Added: trunk/coser-business/src/main/java/fr/ifremer/coser/CoserUtils.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/CoserUtils.java (rev 0) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/CoserUtils.java 2010-11-05 16:39:07 UTC (rev 174) @@ -0,0 +1,89 @@ +/* + * #%L + * + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2010 Codelutin, Chatellier Eric + * %% + * This program 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 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package fr.ifremer.coser; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.nuiton.util.StringUtil; + +/** + * Coser utility class. + * + * @author chatellier + * @version $Revision$ + * + * Last update : $Date$ + * By : $Author$ + */ +public class CoserUtils { + + public static final String BRACKET_STRING_SEPARATOR = ";"; + + /** + * Converti une collection de string en une string + * delimité par les () pour pouvoir être facilement relu par + * + * @param args + * @return string + */ + public static String convertBracketString(List<String> args) { + StringBuffer buffer = new StringBuffer(); + + Iterator<String> itArgs = args.iterator(); + while (itArgs.hasNext()) { + buffer.append('('); + buffer.append(itArgs.next()); + buffer.append(')'); + if (itArgs.hasNext()) { + buffer.append(BRACKET_STRING_SEPARATOR); + } + } + return buffer.toString(); + } + + /** + * Parse la string avec les gestions des () en les supprimant. + * + * @param argsString string to parse + * @return parse list + */ + public static List<String> convertBracketToList(String argsString) { + String[] args = StringUtil.split(argsString, BRACKET_STRING_SEPARATOR); + + List<String> listArgs = new ArrayList<String>(); + for (String arg : args) { + if (arg.startsWith("(") && arg.endsWith(")")) { + arg = StringUtils.removeStart(arg, "("); + arg = StringUtils.removeEnd(arg, ")"); + listArgs.add(arg); + } + } + return listArgs; + } +} Property changes on: trunk/coser-business/src/main/java/fr/ifremer/coser/CoserUtils.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/bean/Selection.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/bean/Selection.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/bean/Selection.java 2010-11-05 16:39:07 UTC (rev 174) @@ -25,6 +25,12 @@ package fr.ifremer.coser.bean; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +import org.apache.commons.lang.StringUtils; + /** * Project selection. * @@ -40,7 +46,21 @@ private static final long serialVersionUID = -1484104459960459854L; protected String name; - + + protected int beginDate; + + protected int endDate; + + protected List<String> zones; + + protected List<String> filterSpecyTypes; + + protected List<String> species; + + protected String technicalComment; + + protected String otherComment; + public String getName() { return name; } @@ -50,4 +70,112 @@ this.name = name; getPropertyChangeSupport().firePropertyChange("name", oldValue, name); } + + public int getBeginDate() { + return beginDate; + } + + public void setBeginDate(int beginDate) { + this.beginDate = beginDate; + } + + public int getEndDate() { + return endDate; + } + + public void setEndDate(int endDate) { + this.endDate = endDate; + } + + public List<String> getZones() { + return zones; + } + + public void setZones(List<String> zones) { + this.zones = zones; + } + + public List<String> getFilterSpecyTypes() { + return filterSpecyTypes; + } + + public void setFilterSpecyTypes(List<String> filterSpecyTypes) { + this.filterSpecyTypes = filterSpecyTypes; + } + + public List<String> getSpecies() { + return species; + } + + public void setSpecies(List<String> species) { + this.species = species; + } + + public String getThechnicalComment() { + return technicalComment; + } + + public void setTechnicalComment(String technicalComment) { + this.technicalComment = technicalComment; + } + + public String getOtherComment() { + return otherComment; + } + + public void setOtherComment(String otherComment) { + this.otherComment = otherComment; + } + + public Properties toProperties() { + Properties props = new Properties(); + props.setProperty("selection.begindate", String.valueOf(getBeginDate())); + props.setProperty("selection.enddate", String.valueOf(getEndDate())); + if (getSpecies() != null) { + props.setProperty("selection.species", StringUtils.join(getSpecies(),',')); + } + if (getZones() != null) { + props.setProperty("selection.zones", StringUtils.join(getZones(),',')); + } + if (getFilterSpecyTypes() != null) { + props.setProperty("selection.specy.types", StringUtils.join(getFilterSpecyTypes(),',')); + } + if (technicalComment != null) { + props.setProperty("selection.technicalcomment", technicalComment); + } + if (otherComment != null) { + props.setProperty("selection.othercomment", otherComment); + } + return props; + } + + public void fromProperties(Properties props) { + if (props.containsKey("selection.begindate")) { + setBeginDate(Integer.parseInt(props.getProperty("selection.begindate"))); + } + if (props.containsKey("selection.enddate")) { + setEndDate(Integer.parseInt(props.getProperty("selection.enddate"))); + } + if (props.containsKey("selection.species")) { + setSpecies(splitAsList(props.getProperty("selection.species"))); + } + if (props.containsKey("selection.zones")) { + setZones(splitAsList(props.getProperty("selection.zones"))); + } + if (props.containsKey("selection.specy.types")) { + setFilterSpecyTypes(splitAsList(props.getProperty("selection.specy.types"))); + } + if (props.containsKey("selection.technicalcomment")) { + setTechnicalComment(props.getProperty("selection.technicalcomment")); + } + if (props.containsKey("selection.othercomment")) { + setOtherComment(props.getProperty("selection.othercomment")); + } + } + + protected List<String> splitAsList(String str) { + String[] strArray = str.split(","); + List<String> strList = Arrays.asList(strArray); + return strList; + } } Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/command/Command.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/command/Command.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/command/Command.java 2010-11-05 16:39:07 UTC (rev 174) @@ -110,4 +110,18 @@ * @throws CoserBusinessException */ public abstract void undoCommand(Project project, AbstractDataContainer container) throws CoserBusinessException; + + /** + * Get command argument string representation. + * + * @return command argument string representation + */ + public abstract String toStringRepresentation(); + + /** + * Init command from string representation. + * + * @param representation string command representation + */ + public abstract void fromStringRepresentation(String representation); } Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/command/DeleteLineCommand.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/command/DeleteLineCommand.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/command/DeleteLineCommand.java 2010-11-05 16:39:07 UTC (rev 174) @@ -27,8 +27,12 @@ import static org.nuiton.i18n.I18n._; +import java.util.ArrayList; +import java.util.List; + import fr.ifremer.coser.CoserBusinessException; import fr.ifremer.coser.CoserConstants.Category; +import fr.ifremer.coser.CoserUtils; import fr.ifremer.coser.bean.AbstractDataContainer; import fr.ifremer.coser.bean.Project; import fr.ifremer.coser.storage.DataStorage; @@ -166,7 +170,38 @@ } } + /* + * @see fr.ifremer.coser.command.Command#toStringRepresentation() + */ @Override + public String toStringRepresentation() { + List<String> args = new ArrayList<String>(); + args.add("category=" + category.toString()); + args.add("lineNumber=" + lineNumber); + return CoserUtils.convertBracketString(args); + } + + /* + * @see fr.ifremer.coser.command.Command#fromStringRepresentation(java.lang.String) + */ + @Override + public void fromStringRepresentation(String representation) { + + List<String> args = CoserUtils.convertBracketToList(representation); + for (String arg : args) { + int indexOfEqual = arg.indexOf('='); + String argAttribute = arg.substring(0, indexOfEqual); + String value = arg.substring(indexOfEqual +1); + if (argAttribute.equals("category")) { + category = Category.valueOf(value); + } + else if (argAttribute.equals("lineNumber")) { + lineNumber = value; + } + } + } + + @Override public String toString() { return "Delete line " + lineNumber + " on " + category; } Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/command/MergeSpeciesCommand.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/command/MergeSpeciesCommand.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/command/MergeSpeciesCommand.java 2010-11-05 16:39:07 UTC (rev 174) @@ -25,7 +25,10 @@ package fr.ifremer.coser.command; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Iterator; +import java.util.List; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.NotImplementedException; @@ -35,6 +38,8 @@ import fr.ifremer.coser.CoserBusinessException; import fr.ifremer.coser.CoserConstants; +import fr.ifremer.coser.CoserUtils; +import fr.ifremer.coser.CoserConstants.Category; import fr.ifremer.coser.bean.AbstractDataContainer; import fr.ifremer.coser.bean.Project; import fr.ifremer.coser.data.Catch; @@ -353,4 +358,36 @@ } return tuple1; } + + /* + * @see fr.ifremer.coser.command.Command#toStringRepresentation() + */ + @Override + public String toStringRepresentation() { + List<String> args = new ArrayList<String>(); + args.add("newSpecyName=" + newSpecyName); + args.add("speciesNames=" + CoserUtils.convertBracketString(Arrays.asList(speciesNames))); + return CoserUtils.convertBracketString(args); + } + + /* + * @see fr.ifremer.coser.command.Command#fromStringRepresentation(java.lang.String) + */ + @Override + public void fromStringRepresentation(String representation) { + + List<String> args = CoserUtils.convertBracketToList(representation); + for (String arg : args) { + int indexOfEqual = arg.indexOf('='); + String argAttribute = arg.substring(0, indexOfEqual); + String value = arg.substring(indexOfEqual +1); + if (argAttribute.equals("newSpecyName")) { + newSpecyName = value; + } + else if (argAttribute.equals("speciesNames")) { + speciesNames = CoserUtils.convertBracketToList(value).toArray(new String[0]); + } + } + + } } Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/command/ModifyFieldCommand.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/command/ModifyFieldCommand.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/command/ModifyFieldCommand.java 2010-11-05 16:39:07 UTC (rev 174) @@ -27,11 +27,14 @@ import static org.nuiton.i18n.I18n._; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import org.apache.commons.beanutils.PropertyUtils; import fr.ifremer.coser.CoserBusinessException; +import fr.ifremer.coser.CoserUtils; import fr.ifremer.coser.CoserConstants.Category; import fr.ifremer.coser.bean.AbstractDataContainer; import fr.ifremer.coser.bean.Project; @@ -63,10 +66,10 @@ protected String fieldName; /** Field actual value. */ - protected Object currentValue; + protected String currentValue; /** Field new value. */ - protected Object newValue; + protected String newValue; public Category getCategory() { return category; @@ -96,7 +99,7 @@ return currentValue; } - public void setCurrentValue(Object currentValue) { + public void setCurrentValue(String currentValue) { this.currentValue = currentValue; } @@ -104,7 +107,7 @@ return newValue; } - public void setNewValue(Object newValue) { + public void setNewValue(String newValue) { this.newValue = newValue; } @@ -202,8 +205,51 @@ } } } - + + /* + * @see fr.ifremer.coser.command.Command#toStringRepresentation() + */ @Override + public String toStringRepresentation() { + List<String> args = new ArrayList<String>(); + args.add("category=" + category.toString()); + args.add("lineNumber=" + lineNumber); + args.add("fieldName=" + fieldName); + args.add("currentValue=" + currentValue); + args.add("newValue=" + newValue); + return CoserUtils.convertBracketString(args); + } + + /* + * @see fr.ifremer.coser.command.Command#fromStringRepresentation(java.lang.String) + */ + @Override + public void fromStringRepresentation(String representation) { + + List<String> args = CoserUtils.convertBracketToList(representation); + for (String arg : args) { + int indexOfEqual = arg.indexOf('='); + String argAttribute = arg.substring(0, indexOfEqual); + String value = arg.substring(indexOfEqual +1); + if (argAttribute.equals("category")) { + category = Category.valueOf(value); + } + else if (argAttribute.equals("lineNumber")) { + lineNumber = value; + } + else if (argAttribute.equals("fieldName")) { + fieldName = value; + } + else if (argAttribute.equals("currentValue")) { + currentValue = value; + } + else if (argAttribute.equals("newValue")) { + newValue = value; + } + } + } + + @Override public String toString() { String toString = "Modify field " + fieldName + " on line " + lineNumber; return toString; Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java 2010-11-05 16:39:07 UTC (rev 174) @@ -27,8 +27,15 @@ import static org.nuiton.i18n.I18n._; +import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -36,6 +43,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; @@ -43,6 +51,8 @@ import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -50,6 +60,7 @@ import fr.ifremer.coser.CoserBusinessException; import fr.ifremer.coser.CoserConstants; import fr.ifremer.coser.CoserConstants.Category; +import fr.ifremer.coser.CoserUtils; import fr.ifremer.coser.bean.AbstractDataContainer; import fr.ifremer.coser.bean.Control; import fr.ifremer.coser.bean.Project; @@ -253,12 +264,33 @@ if (selectionDirectory.isDirectory()) { Selection selection = new Selection(); selection.setName(selectionDirectory.getName()); + + // relecture des informations de la selection (properties) + File propertiesFile = new File(selectionDirectory, "selection.properties"); + + InputStream inputStream = null; + try { + Properties props = new Properties(); + inputStream = new FileInputStream(propertiesFile); + props.load(inputStream); + selection.fromProperties(props); + + if (log.isDebugEnabled()) { + log.debug("Read selection properties file : " + propertiesFile); + } + } catch (IOException ex) { + throw new CoserBusinessException("Can't read selection properties file", ex); + } + finally { + IOUtils.closeQuietly(inputStream); + } + selections.put(selectionDirectory.getName(), selection); } } } project.setSelections(selections); - + return project; } @@ -344,8 +376,11 @@ } } - // TODO echatellier 20101027 need history file reloading - control.setHistoryCommand(new ArrayList<Command>()); + // command file reloading + File historyFile = new File(controlDirectory, CoserConstants.STORAGE_HISTORY_FILENAME + + CoserConstants.STORAGE_HISTORY_SELECTION_EXTENSION); + List<Command> commands = loadHistoryCommands(historyFile); + control.setHistoryCommand(commands); project.setControl(control); @@ -361,7 +396,7 @@ * @throws CoserBusinessException */ public Project loadSelectionData(Project project, Selection selection) throws CoserBusinessException { - + File projectsDirectory = config.getProjectsDirectory(); File projectDirectory = new File(projectsDirectory, project.getName()); @@ -371,12 +406,13 @@ // try to load validated data first File selectionsDirectory = new File(projectDirectory, CoserConstants.STORAGE_SELECTION_DIRECTORY); File selectionDirectory = new File(selectionsDirectory, selection.getName()); + File selectionDataDirectory = new File(selectionDirectory, CoserConstants.STORAGE_DATA_SELECTION_DIRECTORY); int fileLoaded = 0; for (Category category : Category.values()) { // seulement les category de données ici if (category.isDataCategory()) { - File inputFile = new File(selectionDirectory, category.getStorageFileName() + + File inputFile = new File(selectionDataDirectory, category.getStorageFileName() + CoserConstants.STORAGE_SELECTION_SUFFIX + CoserConstants.STORAGE_CSV_EXTENSION); if (inputFile.isFile()) { @@ -390,8 +426,11 @@ } } - // TODO echatellier 20101027 need history file reloading - selection.setHistoryCommand(new ArrayList<Command>()); + // command file reloading + File historyFile = new File(selectionDirectory, CoserConstants.STORAGE_HISTORY_FILENAME + + CoserConstants.STORAGE_HISTORY_SELECTION_EXTENSION); + List<Command> commands = loadHistoryCommands(historyFile); + selection.setHistoryCommand(commands); return project; } @@ -438,6 +477,11 @@ } } } + + // sauvegarde de l'historique des commandes + File historyFile = new File(controlDirectory, CoserConstants.STORAGE_HISTORY_FILENAME + + CoserConstants.STORAGE_HISTORY_SELECTION_EXTENSION); + saveHistoryCommands(project.getControl().getHistoryCommand(), historyFile); } /** @@ -541,27 +585,162 @@ // creation du dossier de la selection courante File selectionDirectory = new File(selectionsDirectory, selection.getName()); + // copie des données (csv) + File selectionDataDirectory = new File(selectionDirectory, CoserConstants.STORAGE_DATA_SELECTION_DIRECTORY); for (Category category : Category.values()) { if (category.isDataCategory()) { - File controlFile = new File(selectionDirectory, + File dataFile = new File(selectionDataDirectory, category.getStorageFileName() + CoserConstants.STORAGE_SELECTION_SUFFIX + CoserConstants.STORAGE_CSV_EXTENSION); if (log.isDebugEnabled()) { - log.debug("Saving selection file : " + controlFile); + log.debug("Saving selection file : " + dataFile); } - + DataStorage content = getProjectContent(project, selection, category, false); - importService.storeData(project, content, controlFile); - + importService.storeData(project, content, dataFile); + // delete data are not saved here // can't delete data in selection } } + + // sauvegarde des informations de la selection (properties) + File propertiesFile = new File(selectionDirectory, "selection.properties"); + Properties props = selection.toProperties(); + OutputStream outputStream = null; + try { + outputStream = new FileOutputStream(propertiesFile); + props.store(outputStream, null); + + if (log.isDebugEnabled()) { + log.debug("Saving selection properties file : " + propertiesFile); + } + } catch (IOException ex) { + throw new CoserBusinessException("Can't save selection properties file", ex); + } + finally { + IOUtils.closeQuietly(outputStream); + } + // sauvegarde de l'historique des commandes + File historyFile = new File(selectionDirectory, CoserConstants.STORAGE_HISTORY_FILENAME + + CoserConstants.STORAGE_HISTORY_SELECTION_EXTENSION); + saveHistoryCommands(selection.getHistoryCommand(), historyFile); } /** + * Sauve une liste ordonnées de commande dans le fichier specifié. + * + * @param historyCommand command list to save + * @param historyFile file to save to + * @throws CoserBusinessException + */ + protected void saveHistoryCommands(List<Command> historyCommand, + File historyFile) throws CoserBusinessException { + + // don't save empty file if list is empty + if (CollectionUtils.isEmpty(historyCommand)) { + return; + } + + PrintStream printStream = null; + + try { + printStream = new PrintStream(historyFile); + + for (Command command : historyCommand) { + List<String> args = new ArrayList<String>(); + args.add(command.getCommandUUID()); + args.add(command.getClass().getSimpleName()); + args.add(command.getComment() == null ? "" : command.getComment()); + args.add(command.toStringRepresentation()); + String argsString = CoserUtils.convertBracketString(args); + printStream.println(argsString); + } + + } catch (IOException ex) { + throw new CoserBusinessException("Can't save command file", ex); + } + finally { + IOUtils.closeQuietly(printStream); + } + } + + /** + * Load history command list from file. + * + * @return command list (never null) + * @throws CoserBusinessException + */ + protected List<Command> loadHistoryCommands(File historyFile) throws CoserBusinessException { + List<Command> historyCommand = new ArrayList<Command>(); + + if (historyFile.exists()) { + if (log.isDebugEnabled()) { + log.debug("Loading command list from file " + historyFile.getAbsolutePath()); + } + + BufferedReader fileReader = null; + try { + fileReader = new BufferedReader(new FileReader(historyFile)); + + String line = null; + while ((line = fileReader.readLine()) != null) { + if (StringUtils.isNotBlank(line)) { + Command command = convertLineToCommand(line); + historyCommand.add(command); + } + } + } + catch (IOException ex) { + throw new CoserBusinessException("Can't read history file", ex); + } + finally { + IOUtils.closeQuietly(fileReader); + } + } + + return historyCommand; + } + + /** + * Convert a string line to parametized command. + * + * @param line line to convert + * @return + * @throws CoserBusinessException + */ + protected Command convertLineToCommand(String line) throws CoserBusinessException { + + Command result = null; + + List<String> lineDetail = CoserUtils.convertBracketToList(line); + String commandUUID = lineDetail.get(0); + String commandName = lineDetail.get(1); + String commandComment = lineDetail.get(2); + String commandArgs = lineDetail.get(3); + + // instancie dynamiquement la command + // en la charchant dans le meme package que la class "Command" + String commandFQN = Command.class.getPackage().getName() + "." + commandName; + if (log.isDebugEnabled()) { + log.debug("Make new instance of command : " + commandFQN); + } + + try { + result = (Command)Class.forName(commandFQN).newInstance(); + result.setCommandUUID(commandUUID); + result.setComment(commandComment); + result.fromStringRepresentation(commandArgs); + } catch (Exception ex) { + throw new CoserBusinessException("Can't init command intance", ex); + } + + return result; + } + + /** * Set content into project depending on category type. * * @param project project Modified: trunk/coser-business/src/test/java/fr/ifremer/coser/services/CoserTestAbstract.java =================================================================== --- trunk/coser-business/src/test/java/fr/ifremer/coser/services/CoserTestAbstract.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-business/src/test/java/fr/ifremer/coser/services/CoserTestAbstract.java 2010-11-05 16:39:07 UTC (rev 174) @@ -75,7 +75,7 @@ @AfterClass public static void cleanDirectory() throws IOException { - FileUtils.deleteDirectory(testDirectory); + //FileUtils.deleteDirectory(testDirectory); } /** Modified: trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java =================================================================== --- trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java 2010-11-05 16:39:07 UTC (rev 174) @@ -26,20 +26,23 @@ package fr.ifremer.coser.services; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; +import org.apache.commons.io.FileUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import fr.ifremer.coser.CoserBusinessException; import fr.ifremer.coser.CoserConstants; +import fr.ifremer.coser.CoserConstants.Category; import fr.ifremer.coser.bean.Project; import fr.ifremer.coser.bean.Selection; -import fr.ifremer.coser.bean.Specy; +import fr.ifremer.coser.command.DeleteLineCommand; /** * Project service tests. @@ -52,11 +55,14 @@ */ public class ProjectServiceTest extends CoserTestAbstract { - protected ProjectService service; + protected ProjectService projectService; + protected CommandService commandService; + @Before public void initService() { - service = new ProjectService(config); + projectService = new ProjectService(config); + commandService = new CommandService(config); } /** @@ -68,8 +74,8 @@ public void testDuplicatedProject() throws CoserBusinessException { Project p = new Project(); p.setName("myProject"); - service.createProject(p, new HashMap<CoserConstants.Category, File>()); - service.createProject(p, new HashMap<CoserConstants.Category, File>()); + projectService.createProject(p, new HashMap<CoserConstants.Category, File>()); + projectService.createProject(p, new HashMap<CoserConstants.Category, File>()); } /** @@ -80,7 +86,7 @@ */ @Test public void testCreateProject() throws CoserBusinessException { - Project project = createTestProject(service); + Project project = createTestProject(projectService); Assert.assertTrue(new File(config.getProjectsDirectory(), project.getName() + File.separator + "original" + File.separator + "catch.csv").exists()); @@ -102,8 +108,8 @@ */ @Test public void testSaveProject() throws CoserBusinessException { - Project project = createTestProject(service); - service.saveProjectControl(project); + Project project = createTestProject(projectService); + projectService.saveProjectControl(project); Assert.assertTrue(new File(config.getProjectsDirectory(), project.getName() + File.separator + "control" + File.separator + "catch_co.csv").exists()); @@ -116,10 +122,10 @@ */ @Test public void testCreateSelection() throws CoserBusinessException { - Project project = createTestProject(service); - Selection selection = service.initProjectSelection(project); + Project project = createTestProject(projectService); + Selection selection = projectService.initProjectSelection(project); selection.setName("titi"); - service.createProjectSelection(project, selection); + projectService.createProjectSelection(project, selection); Assert.assertTrue(new File(config.getProjectsDirectory(), project.getName() + File.separator + "selections" + File.separator + @@ -133,15 +139,15 @@ */ @Test public void testSelectionReloading() throws CoserBusinessException { - Project project = createTestProject(service); + Project project = createTestProject(projectService); Assert.assertEquals(25, project.getControl().getCatch().size()); - Selection selection = service.initProjectSelection(project); + Selection selection = projectService.initProjectSelection(project); selection.setName("titi"); - service.createProjectSelection(project, selection); + projectService.createProjectSelection(project, selection); project.clearData(); - service.loadSelectionData(project, selection); + projectService.loadSelectionData(project, selection); Assert.assertEquals(25, project.getSelections().get("titi").getCatch().size()); } @@ -153,11 +159,11 @@ */ @Test(expected=CoserBusinessException.class) public void testCreateSelectionError() throws CoserBusinessException { - Project project = createTestProject(service); - Selection selection = service.initProjectSelection(project); + Project project = createTestProject(projectService); + Selection selection = projectService.initProjectSelection(project); selection.setName("titi"); - service.createProjectSelection(project, selection); - service.createProjectSelection(project, selection); + projectService.createProjectSelection(project, selection); + projectService.createProjectSelection(project, selection); } /** @@ -167,10 +173,10 @@ */ @Test public void testSpeciesExistence() throws CoserBusinessException { - Project project = createTestProject(service); - Assert.assertFalse(service.isSpecyNameExist(project, "Coser_invalid")); - Assert.assertTrue(service.isSpecyNameExist(project, "COSER_SPECIES1")); - Assert.assertTrue(service.isSpecyNameExist(project, "COSER_SPECIES2")); + Project project = createTestProject(projectService); + Assert.assertFalse(projectService.isSpecyNameExist(project, "Coser_invalid")); + Assert.assertTrue(projectService.isSpecyNameExist(project, "COSER_SPECIES1")); + Assert.assertTrue(projectService.isSpecyNameExist(project, "COSER_SPECIES2")); } /** @@ -180,10 +186,10 @@ */ @Test public void testProjectYear() throws CoserBusinessException { - Project project = createTestProject(service); - Selection selection = service.initProjectSelection(project); + Project project = createTestProject(projectService); + Selection selection = projectService.initProjectSelection(project); - List<Integer> years = service.getProjectYears(selection); + List<Integer> years = projectService.getProjectYears(selection); Assert.assertEquals(2, years.size()); Assert.assertEquals(Integer.valueOf(2010), years.get(0)); Assert.assertEquals(Integer.valueOf(2011), years.get(1)); @@ -196,16 +202,16 @@ */ @Test public void testProjectZone() throws CoserBusinessException { - Project project = createTestProject(service); - Selection selection = service.initProjectSelection(project); + Project project = createTestProject(projectService); + Selection selection = projectService.initProjectSelection(project); - List<String> zones = service.getProjectZone(selection, 2010, 2011); + List<String> zones = projectService.getProjectZone(selection, 2010, 2011); Assert.assertEquals(6, zones.size()); - zones = service.getProjectZone(selection, 2011, 2011); + zones = projectService.getProjectZone(selection, 2011, 2011); Assert.assertEquals(3, zones.size()); - zones = service.getProjectZone(selection, 2009, 2009); + zones = projectService.getProjectZone(selection, 2009, 2009); Assert.assertEquals(0, zones.size()); } @@ -216,8 +222,8 @@ */ @Test public void testProjectSpecies() throws CoserBusinessException { - Project project = createTestProject(service); - Selection selection = service.initProjectSelection(project); + Project project = createTestProject(projectService); + Selection selection = projectService.initProjectSelection(project); List<String> allZones = new ArrayList<String>(); allZones.add("STR1"); @@ -227,21 +233,21 @@ allZones.add("STR5"); allZones.add("STR6"); - List<String> species = service.getProjectSpecies(project, selection, allZones, 2010, 2011, null); + List<String> species = projectService.getProjectSpecies(project, selection, allZones, 2010, 2011, null); Assert.assertEquals(4, species.size()); - species = service.getProjectSpecies(project, selection, allZones, 2011, 2011, null); + species = projectService.getProjectSpecies(project, selection, allZones, 2011, 2011, null); Assert.assertEquals(4, species.size()); - species = service.getProjectSpecies(project, selection, allZones, 2009, 2009, null); + species = projectService.getProjectSpecies(project, selection, allZones, 2009, 2009, null); Assert.assertEquals(0, species.size()); // test with no zones - species = service.getProjectSpecies(project, selection, new ArrayList<String>(), 2010, 2011, null); + species = projectService.getProjectSpecies(project, selection, new ArrayList<String>(), 2010, 2011, null); Assert.assertEquals(0, species.size()); // test with only one zone - species = service.getProjectSpecies(project, selection, Collections.singletonList("STR6"), 2010, 2011, null); + species = projectService.getProjectSpecies(project, selection, Collections.singletonList("STR6"), 2010, 2011, null); Assert.assertEquals(4, species.size()); } @@ -252,20 +258,45 @@ */ @Test public void testMergeSpecies() throws CoserBusinessException { - Project project = createTestProject(service); - Selection selection = service.initProjectSelection(project); + Project project = createTestProject(projectService); + Selection selection = projectService.initProjectSelection(project); selection.setName("test"); - Assert.assertTrue(service.isSpecyNameExist(project, "COSER_SPECIES_MERGE")); + Assert.assertTrue(projectService.isSpecyNameExist(project, "COSER_SPECIES_MERGE")); Assert.assertEquals(25, selection.getCatch().size()); Assert.assertEquals(30, selection.getLength().size()); - project = service.mergeSpecies(project, selection, "COSER_SPECIES_MERGE", "COSER_SPECIES1", "COSER_SPECIES2"); + project = projectService.mergeSpecies(project, selection, "COSER_SPECIES_MERGE", "COSER_SPECIES1", "COSER_SPECIES2"); Assert.assertEquals(19, selection.getCatch().size()); Assert.assertEquals(29, selection.getLength().size()); - service.createProjectSelection(project, selection); - System.out.println(selection.getName()); + projectService.createProjectSelection(project, selection); } + + /** + * Test que la sauvegarde des commandes d'un control et le + * rechargement des commandes fonctionne bien. + * + * @throws CoserBusinessException + * @throws IOException + */ + @Test + public void testCommandStoreAndReloading() throws CoserBusinessException, IOException { + Project project = createTestProject(projectService); + + DeleteLineCommand command = new DeleteLineCommand(); + command.setLineNumber("2"); + command.setCategory(Category.LENGTH); + + commandService.doAction(command, project, project.getControl()); + projectService.saveProjectControl(project); + + // clear, reload and undo command after reloading + project.clearData(); + projectService.loadControlData(project); + + commandService.undoAction(project, project.getControl()); + Assert.assertEquals(30, project.getControl().getLength().size()); + } } Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionDetailsView.jaxx =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionDetailsView.jaxx 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionDetailsView.jaxx 2010-11-05 16:39:07 UTC (rev 174) @@ -61,7 +61,7 @@ <YearComboBoxModel id="beginYearComboBoxModel" constructorParams="this" /> <JComboBox id="selectionDetailsBeginYearField" model="{beginYearComboBoxModel}" - onActionPerformed="getHandler().updateSelectionDateData(this, event)" /> + onActionPerformed="getHandler().updateSelectionDateData(this, event); getSelection().setBeginDate((Integer)selectionDetailsBeginYearField.getSelectedItem())" /> </cell> <cell anchor="west"> <JLabel text="coser.ui.selection.details.endDate" /> @@ -70,7 +70,7 @@ <YearComboBoxModel id="endYearComboBoxModel" constructorParams="this" /> <JComboBox id="selectionDetailsEndYearField" model="{endYearComboBoxModel}" - onActionPerformed="getHandler().updateSelectionDateData(this, event)" /> + onActionPerformed="getHandler().updateSelectionDateData(this, event); getSelection().setEndDate((Integer)selectionDetailsEndYearField.getSelectedItem())" /> </cell> </row> <row> @@ -90,7 +90,7 @@ cellRenderer="{new SelectionZoneListRenderer()}" enabled="{selectionDetailsBeginYearField.getSelectedItem() != null && selectionDetailsEndYearField.getSelectedItem() != null}" selectionModel="{new OneClicListSelectionModel(zoneList.getSelectionModel(), selectionZoneModel)}" - onValueChanged="getHandler().updateSelectionSpecies(this)"/> + onValueChanged="getHandler().zoneListChanged(this);"/> </JScrollPane> </cell> </row> @@ -112,7 +112,7 @@ <TypeSpecyListModel id="typeSpecyModel" constructorParams="this" /> <JList id="typeSpecyList" model="{typeSpecyModel}" selectionModel="{new OneClicListSelectionModel(typeSpecyList.getSelectionModel(), typeSpecyModel)}" - onValueChanged="getHandler().updateSelectionSpecies(this)"/> + onValueChanged="getHandler().typeSpecyListChanged(this)"/> </JScrollPane> </cell> </row> @@ -123,7 +123,8 @@ <JList id="specyList" model="{specyListModel}" cellRenderer="{new SpecyListRenderer()}" onMouseClicked="getHandler().showSpeciesContextMenu(this, event)" - selectionModel="{new OneClicListSelectionModel(specyList.getSelectionModel(), specyListModel)}"/> + selectionModel="{new OneClicListSelectionModel(specyList.getSelectionModel(), specyListModel)}" + onValueChanged="getHandler().specyListChanged(this)"/> <ListSelectionModel id="specyListSelectionModel" javaBean="specyList.getSelectionModel()" /> </JScrollPane> </cell> Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SelectionHandler.java 2010-11-05 16:39:07 UTC (rev 174) @@ -85,6 +85,61 @@ } /** + * Appellé lorsque la selection de la liste des zones a changé. + * + * @param view view + */ + public void zoneListChanged(SelectionDetailsView view) { + Selection selection = view.getContextValue(Selection.class); + + // get selected zones as list + Object[] selectedZones = view.getZoneList().getSelectedValues(); + List<String> zones = new ArrayList<String>(selectedZones.length); + for (Object selectedZone : selectedZones) { + zones.add((String)selectedZone); + } + selection.setZones(zones); + + updateSelectionSpecies(view); + } + + /** + * Appelé lorsque la selection de la liste des types. + * + * @param view view + */ + public void typeSpecyListChanged(SelectionDetailsView view) { + Selection selection = view.getContextValue(Selection.class); + + // get selected specy types + Object[] selectedSpecyTypes = view.getTypeSpecyList().getSelectedValues(); + List<String> specyTypes = new ArrayList<String>(); + for (Object selectedSpecyType : selectedSpecyTypes) { + specyTypes.add((String)selectedSpecyType); + } + selection.setFilterSpecyTypes(specyTypes); + + updateSelectionSpecies(view); + } + + /** + * Appelé lorsque la selection de la liste des especes change. + * + * @param view + */ + public void specyListChanged(SelectionDetailsView view) { + Selection selection = view.getContextValue(Selection.class); + + // get selected species + Object[] selectedSpecies = view.getSpecyList().getSelectedValues(); + List<String> species= new ArrayList<String>(); + for (Object selectedSpecy : selectedSpecies) { + species.add((String)selectedSpecy); + } + selection.setSpecies(species); + } + + /** * Rafraichit la liste des especes avec les dates sélectionnées * et les zones selectionnées ET filtrées par la liste * des type d'especes. @@ -93,17 +148,13 @@ * * @param view view */ - public void updateSelectionSpecies(SelectionDetailsView view) { + protected void updateSelectionSpecies(SelectionDetailsView view) { Project project = view.getContextValue(Project.class); Selection selection = view.getContextValue(Selection.class); ProjectService projectService = view.getContextValue(ProjectService.class); // get selected zones as list - Object[] selectedZones = view.getZoneList().getSelectedValues(); - List<String> zones = new ArrayList<String>(selectedZones.length); - for (Object selectedZone : selectedZones) { - zones.add((String)selectedZone); - } + List<String> zones = selection.getZones(); // get selected specy types Object[] selectedSpecyTypes = view.getTypeSpecyList().getSelectedValues(); Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListCheckBoxRenderer.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListCheckBoxRenderer.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListCheckBoxRenderer.java 2010-11-05 16:39:07 UTC (rev 174) @@ -31,8 +31,6 @@ import org.jdesktop.swingx.renderer.DefaultListRenderer; -import fr.ifremer.coser.bean.Specy; - /** * Check box list renderer. * Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListRenderer.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListRenderer.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListRenderer.java 2010-11-05 16:39:07 UTC (rev 174) @@ -30,8 +30,6 @@ import javax.swing.DefaultListCellRenderer; import javax.swing.JList; -import fr.ifremer.coser.bean.Specy; - /** * Basic list renderer. * Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListTestModel.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListTestModel.java 2010-11-05 11:34:40 UTC (rev 173) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/selection/SpecyListTestModel.java 2010-11-05 16:39:07 UTC (rev 174) @@ -33,11 +33,6 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import fr.ifremer.coser.bean.Specy; - /** * Test list model. * @@ -52,8 +47,6 @@ /** serialVersionUID. */ private static final long serialVersionUID = -4769109927915812519L; - private final static Log log = LogFactory.getLog(SpecyListTestModel.class); - protected List<String> species = new ArrayList<String>(); public void setSpecy(List<String> species) {