Author: chatellier Date: 2010-11-16 08:43:10 +0000 (Tue, 16 Nov 2010) New Revision: 214 Log: Merge commands file and properties file into properties file Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/bean/AbstractDataContainer.java trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/bean/AbstractDataContainer.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/bean/AbstractDataContainer.java 2010-11-15 17:27:03 UTC (rev 213) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/bean/AbstractDataContainer.java 2010-11-16 08:43:10 UTC (rev 214) @@ -79,7 +79,6 @@ deletedDataHaul = null; dataLength = null; deletedDataLength = null; - historyCommand = null; } public DataStorage getCatch() { 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-15 17:27:03 UTC (rev 213) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java 2010-11-16 08:43:10 UTC (rev 214) @@ -27,17 +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.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -53,7 +51,6 @@ 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; import org.apache.commons.math.util.MathUtils; @@ -296,6 +293,9 @@ inputStream = new FileInputStream(propertiesFile); props.load(inputStream); selection.fromProperties(props); + + List<Command> commands = getHistoryCommandsFromProperties(props, "selection.commands"); + selection.setHistoryCommand(commands); if (log.isDebugEnabled()) { log.debug("Read selection properties file : " + propertiesFile); @@ -311,6 +311,7 @@ } } } + project.setSelections(selections); // relecture des informations du projet (properties) @@ -417,22 +418,19 @@ } } - // 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); - // relecture des informations du control (properties) File propertiesFile = new File(controlDirectory, "control.properties"); - if (propertiesFile.exists()) { // si on a vraiment pas sauver le control ... + if (propertiesFile.exists()) { // si on a vraiment pas sauve le control ... InputStream inputStream = null; try { Properties props = new Properties(); inputStream = new FileInputStream(propertiesFile); props.load(inputStream); control.fromProperties(props); - + + List<Command> commands = getHistoryCommandsFromProperties(props, "control.commands"); + control.setHistoryCommand(commands); + if (log.isDebugEnabled()) { log.debug("Read control properties file : " + propertiesFile); } @@ -443,6 +441,9 @@ IOUtils.closeQuietly(inputStream); } } + else { + control.setHistoryCommand(new ArrayList<Command>()); + } project.setControl(control); @@ -488,12 +489,6 @@ } } - // 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; } @@ -545,6 +540,7 @@ // sauvegarde des informations du control (properties) File propertiesFile = new File(controlDirectory, "control.properties"); Properties props = control.toProperties(); + addHistoryCommandsToProperties(props, project.getControl().getHistoryCommand(), "control.commands"); OutputStream outputStream = null; try { outputStream = new FileOutputStream(propertiesFile); @@ -560,10 +556,6 @@ IOUtils.closeQuietly(outputStream); } - // 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); } /** @@ -692,6 +684,7 @@ // sauvegarde des informations de la selection (properties) File propertiesFile = new File(selectionDirectory, "selection.properties"); Properties props = selection.toProperties(); + addHistoryCommandsToProperties(props, selection.getHistoryCommand(), "selection.commands"); OutputStream outputStream = null; try { outputStream = new FileOutputStream(propertiesFile); @@ -706,93 +699,99 @@ 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 props proparties to add command to * @param historyCommand command list to save - * @param historyFile file to save to + * @param propertyPrefix property prefix * @throws CoserBusinessException */ - protected void saveHistoryCommands(List<Command> historyCommand, - File historyFile) throws CoserBusinessException { + protected void addHistoryCommandsToProperties(Properties props, List<Command> historyCommand, + String propertyPrefix) throws CoserBusinessException { - // don't save empty file if list is empty - if (CollectionUtils.isEmpty(historyCommand)) { - return; + int commandIndex = 0; + for (Command command : historyCommand) { + String commandProperty = propertyPrefix + "." + commandIndex; + String commandValue = convertCommandToLine(command); + props.setProperty(commandProperty, commandValue); + commandIndex++; } - - 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. * + * @param props properties to parse + * @param propertyPrefix property prefix * @return command list (never null) * @throws CoserBusinessException */ - protected List<Command> loadHistoryCommands(File historyFile) throws CoserBusinessException { + protected List<Command> getHistoryCommandsFromProperties(Properties props, final String propertyPrefix) 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); + // take care of property name order + List<String> propertiesNames = new ArrayList<String>(props.stringPropertyNames()); + Collections.sort(propertiesNames, new Comparator<String>() { + @Override + public int compare(String o1, String o2) { + int result = -1; + if (o1.matches(Pattern.quote(propertyPrefix + ".") + "\\d+")) { + if (o2.matches(Pattern.quote(propertyPrefix + ".") + "\\d+")) { + int int1 = Integer.parseInt(o1.substring(propertyPrefix.length() + 1)); + int int2 = Integer.parseInt(o2.substring(propertyPrefix.length() + 1)); + result = int1 - int2; } + else { + result = o1.compareTo(o2); + } } + else { + result = o1.compareTo(o2); + } + return result; } - catch (IOException ex) { - throw new CoserBusinessException("Can't read history file", ex); + + }); + + for (String propertyName : propertiesNames) { + + if (propertyName.startsWith(propertyPrefix + ".")) { + String commandAsString = props.getProperty(propertyName); + Command command = convertLineToCommand(commandAsString); + historyCommand.add(command); } - finally { - IOUtils.closeQuietly(fileReader); - } } return historyCommand; } /** - * Convert a string line to parametized command. + * Convert a command to string info * + * @param command command to convert + * @return string command + * @throws CoserBusinessException + */ + protected String convertCommandToLine(Command command) { + + 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 result = CoserUtils.convertBracketString(args); + + return result; + } + + /** + * Convert a string line to parameized command. + * * @param line line to convert - * @return + * @return command * @throws CoserBusinessException */ protected Command convertLineToCommand(String line) throws CoserBusinessException { 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-15 17:27:03 UTC (rev 213) +++ trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java 2010-11-16 08:43:10 UTC (rev 214) @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Properties; import org.junit.Assert; import org.junit.Before; @@ -42,7 +43,10 @@ import fr.ifremer.coser.CoserConstants.Category; import fr.ifremer.coser.bean.Project; import fr.ifremer.coser.bean.Selection; +import fr.ifremer.coser.command.Command; import fr.ifremer.coser.command.DeleteLineCommand; +import fr.ifremer.coser.command.MergeSpeciesCommand; +import fr.ifremer.coser.command.ModifyFieldCommand; /** * Project service tests. @@ -299,8 +303,62 @@ commandService.undoAction(project, project.getControl()); Assert.assertEquals(30, project.getControl().getLength().size()); } - + /** + * Test que les commandes sont bien sauvées et restaurées dans l'ordre + * d'ajout. + * @throws CoserBusinessException + */ + @Test + public void testPropertiesCommandOrder() throws CoserBusinessException { + Properties props = new Properties(); + props.setProperty("test wrong data", "wrong data"); + + List<Command> commands = new ArrayList<Command>(); + + // make real commands + MergeSpeciesCommand msc1 = new MergeSpeciesCommand(); + //msc1.setCategory(Category.CATCH); + msc1.setSpeciesNames(new String[]{"thuna"}); + MergeSpeciesCommand msc2 = new MergeSpeciesCommand(); + //msc2.setCategory(Category.CATCH); + msc2.setSpeciesNames(new String[]{"bar"}); + + DeleteLineCommand dlc1 = new DeleteLineCommand(); + dlc1.setCategory(Category.CATCH); + dlc1.setLineNumber("10"); + DeleteLineCommand dlc2 = new DeleteLineCommand(); + dlc2.setCategory(Category.STRATA); + dlc2.setLineNumber("99"); + + ModifyFieldCommand mfc1 = new ModifyFieldCommand(); + mfc1.setCategory(Category.CATCH); + ModifyFieldCommand mfc2 = new ModifyFieldCommand(); + mfc2.setCategory(Category.STRATA); + + commands.add(msc1); + commands.add(dlc1); + commands.add(mfc1); + commands.add(dlc2); + commands.add(mfc2); + commands.add(msc2); + + projectService.addHistoryCommandsToProperties(props, commands, "control.commands"); + + // try to read it + commands = projectService.getHistoryCommandsFromProperties(props, "control.commands"); + + Assert.assertTrue(commands.get(0) instanceof MergeSpeciesCommand); + Assert.assertTrue(commands.get(1) instanceof DeleteLineCommand); + Assert.assertTrue(commands.get(2) instanceof ModifyFieldCommand); + Assert.assertTrue(commands.get(3) instanceof DeleteLineCommand); + Assert.assertTrue(commands.get(4) instanceof ModifyFieldCommand); + Assert.assertTrue(commands.get(5) instanceof MergeSpeciesCommand); + + + } + + /** * Test de la method sampling effort. * * @throws CoserBusinessException