Author: chatellier Date: 2011-05-26 17:01:54 +0000 (Thu, 26 May 2011) New Revision: 830 Log: Fix command parsing when comment was containing special control char ' Modified: trunk/changelog.txt trunk/coser-business/src/main/java/fr/ifremer/coser/CoserUtils.java trunk/coser-business/src/test/java/fr/ifremer/coser/CoserUtilsTest.java Modified: trunk/changelog.txt =================================================================== --- trunk/changelog.txt 2011-05-26 14:22:04 UTC (rev 829) +++ trunk/changelog.txt 2011-05-26 17:01:54 UTC (rev 830) @@ -4,6 +4,7 @@ 1.0.6 ----- + * Fix command parsing when comment was containing special control char ' * Fix double min decimal check with negative values * Update to jQuery 1.6.1 * Update to HttpComponent Core 4.1.1 Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/CoserUtils.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/CoserUtils.java 2011-05-26 14:22:04 UTC (rev 829) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/CoserUtils.java 2011-05-26 17:01:54 UTC (rev 830) @@ -5,7 +5,7 @@ * $Id$ * $HeadURL$ * %% - * Copyright (C) 2010 Codelutin, Chatellier Eric + * Copyright (C) 2010 - 2011 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 @@ -55,7 +55,7 @@ */ public class CoserUtils { - public static final String BRACKET_STRING_SEPARATOR = ";"; + public static final char BRACKET_STRING_SEPARATOR = ';'; /** Pattern pour ajouter les suffix (probleme de replace sur le 'dernier' .) */ public static final Pattern FILENAME_SUFFIX_PATTERN = Pattern.compile("^(.+)(\\.[^\\.]+)$"); @@ -63,6 +63,7 @@ /** * Converti une collection de string en une string * delimité par les () pour pouvoir être facilement relu par + * {@link #splitWithBrackets(String, char)} * * @param args * @return string @@ -73,7 +74,13 @@ Iterator<String> itArgs = args.iterator(); while (itArgs.hasNext()) { buffer.append('('); - buffer.append(itArgs.next()); + String arg = itArgs.next(); + // escape special chars + // just (, ) and escape char \ + arg = StringUtils.replace(arg, "\\", "\\\\"); + arg = StringUtils.replace(arg, ")", "\\)"); + arg = StringUtils.replace(arg, "(", "\\("); + buffer.append(arg); buffer.append(')'); if (itArgs.hasNext()) { buffer.append(BRACKET_STRING_SEPARATOR); @@ -83,19 +90,74 @@ } /** + * Split line counting opened ( and ) and take care about escaped \\). + * + * @param str string to parse + * @param separator to take care + * @return string splited + */ + protected static List<String> splitWithBrackets(String str, char separator) { + + List<String> result = new ArrayList<String>(); + + StringBuffer op = new StringBuffer(); // stack of {([< currently open + int opened = 0; + boolean escapeNext = false; + + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (escapeNext) { + op.append(c); + escapeNext = false; + } + else if (c == '\\') { + escapeNext = true; + } else if (c == '(') { + op.append(c); + opened++; + } else if (c == ')') { + op.append(c); + opened--; + } else if (c == separator) { + if (opened == 0) { + result.add(op.toString()); + op = new StringBuffer(); + } + else { + op.append(c); + } + } else { + op.append(c); + } + } + + if (op.length() > 0) { + result.add(op.toString()); + } + + return result; + } + + /** * 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> args = splitWithBrackets(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, ")"); + + // unescape () and \ + arg = arg.replaceAll("\\)", ")"); + arg = arg.replaceAll("\\(", "("); + arg = arg.replaceAll("\\\\\\\\", "\\"); + listArgs.add(arg); } } Modified: trunk/coser-business/src/test/java/fr/ifremer/coser/CoserUtilsTest.java =================================================================== --- trunk/coser-business/src/test/java/fr/ifremer/coser/CoserUtilsTest.java 2011-05-26 14:22:04 UTC (rev 829) +++ trunk/coser-business/src/test/java/fr/ifremer/coser/CoserUtilsTest.java 2011-05-26 17:01:54 UTC (rev 830) @@ -26,6 +26,8 @@ package fr.ifremer.coser; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import org.junit.Assert; import org.junit.Test; @@ -69,4 +71,40 @@ Assert.assertNotNull(CoserUtils.parseDocument("<html>")); } + /** + * Test que la chaine est bien parsée (buggé dans coser 1.0.5). + */ + @Test + public void testBracketToList() { + String data = "(38be0fde-0f55-4dc1-a089-8e589a2623f0);(MergeSpeciesCommand);(Regroupe FMCOTTI, TAURBUB et MYOXSCO en FMCOTTI : PB d'identification avant 2000);((newSpecyName=FMCOTTI);(speciesNames=(FMCOTTI);(MYOXSCO);(TAURBUB)))"; + List<String> dataAsList = CoserUtils.convertBracketToList(data); + Assert.assertEquals(4, dataAsList.size()); + + data = "(38be0fde-0f55-4dc1-a089-8e589a2623f0);(test \\\\);(test \\) echappement)"; + dataAsList = CoserUtils.convertBracketToList(data); + + Assert.assertEquals(3, dataAsList.size()); + Assert.assertEquals("test \\", dataAsList.get(1)); + Assert.assertEquals("test ) echappement", dataAsList.get(2)); + } + + /** + * Convertit une liste en une string separé par des () et + * verifie que les echapements sont pris en compte. + */ + @Test + public void testListToBracket() { + List<String> myList = new ArrayList<String>(); + myList.add("string1"); + myList.add("string2 avec \\"); + myList.add("string3 avec )"); + myList.add("string4 avec ("); + myList.add("string5"); + String asString = CoserUtils.convertBracketString(myList); + Assert.assertEquals("(string1);(string2 avec \\\\);(string3 avec \\));(string4 avec \\();(string5)", asString); + + myList = CoserUtils.convertBracketToList(asString); + Assert.assertEquals(5, myList.size()); + Assert.assertEquals("[string1, string2 avec \\, string3 avec ), string4 avec (, string5]", myList.toString()); + } }