[gatein-commits] gatein SVN: r2314 - in components/common/trunk/common/src: test/java/org/gatein/common and 1 other directory.

do-not-reply at jboss.org do-not-reply at jboss.org
Fri Mar 19 11:50:48 EDT 2010


Author: chris.laprun at jboss.com
Date: 2010-03-19 11:50:46 -0400 (Fri, 19 Mar 2010)
New Revision: 2314

Modified:
   components/common/trunk/common/src/main/java/org/gatein/common/text/TextTools.java
   components/common/trunk/common/src/test/java/org/gatein/common/StringTestCase.java
Log:
- Rewrote TextTools.replaceBoundedString implementation so that we can also do partial matching in case the suffix is specified as optional.
- Added test cases.

Modified: components/common/trunk/common/src/main/java/org/gatein/common/text/TextTools.java
===================================================================
--- components/common/trunk/common/src/main/java/org/gatein/common/text/TextTools.java	2010-03-19 15:23:35 UTC (rev 2313)
+++ components/common/trunk/common/src/main/java/org/gatein/common/text/TextTools.java	2010-03-19 15:50:46 UTC (rev 2314)
@@ -100,25 +100,45 @@
     */
    public static String replaceAllInstancesOfBoundedString(String initial, String prefix, String suffix, String replacement)
    {
-      return replaceBoundedString(initial, prefix, suffix, replacement, true, false);
+      return replaceBoundedString(initial, prefix, suffix, replacement, true, false, false);
    }
 
+   public static String replaceAllInstancesOfBoundedString(String initial, String prefix, String suffix, StringReplacementGenerator generator)
+   {
+      return replaceBoundedString(initial, prefix, suffix, generator, true, false, false);
+   }
+
    public static String replaceBoundedString(String initial, String prefix, String suffix, String replacement,
                                              boolean replaceIfBoundedStringEmpty, boolean keepBoundaries)
    {
       ParameterValidation.throwIllegalArgExceptionIfNull(replacement, "replacement");
       return replaceBoundedString(initial, prefix, suffix, new ConstantStringReplacementGenerator(replacement),
-         replaceIfBoundedStringEmpty, keepBoundaries);
+         replaceIfBoundedStringEmpty, keepBoundaries, false);
    }
 
+   public static String replaceBoundedString(String initial, String prefix, String suffix, String replacement,
+                                             boolean replaceIfBoundedStringEmpty, boolean keepBoundaries, boolean suffixIsOptional)
+   {
+      ParameterValidation.throwIllegalArgExceptionIfNull(replacement, "replacement");
+      return replaceBoundedString(initial, prefix, suffix, new ConstantStringReplacementGenerator(replacement),
+         replaceIfBoundedStringEmpty, keepBoundaries, suffixIsOptional);
+   }
+
+   public static String replaceBoundedString(String initial, String prefix, String suffix, StringReplacementGenerator generator,
+                                             boolean replaceIfBoundedStringEmpty, boolean keepBoundaries)
+   {
+      return replaceBoundedString(initial, prefix, suffix, generator, replaceIfBoundedStringEmpty, keepBoundaries, false);
+   }
+
    /**
     * Replace instances of Strings delimited by the given prefix and suffix (hence, bounded) by a replacement String
     * computed by the specified StringReplacementGenerator based on the current bounded String match. It is possible to
     * specify whether the substitution will happen only if the delimited String is non-empty by setting
     * <code>replaceIfBoundedStringEmpty</code> to <code>false</code>. It is also possible to keep the boundaries (prefix
-    * and suffix) after the substitution by setting <code>keepBoundaries</code> to <code>true</code>.
-    * <p/>
-    * See org.gatein.common.StringTestCase.testReplaceBoundedString() for usage details.
+    * and suffix) after the substitution by setting <code>keepBoundaries</code> to <code>true</code>. <br/> Note that it
+    * is possible to specify that the suffix is optional, in which case, the prefix will be passed on to the specified
+    * StringReplacementGenerator and be replaced. <br/> See org.gatein.common.StringTestCase.testReplaceBoundedString()
+    * for usage details.
     *
     * @param initial                     the String in which we want to replace bounded Strings
     * @param prefix                      the prefix used identify the beginning of the String targeted for replacement
@@ -129,10 +149,11 @@
     *                                    of the replacement String between the prefix and suffix)
     * @param keepBoundaries              <code>true</code> to keep the prefix and suffix markers in the resulting
     *                                    String
+    * @param suffixIsOptional            whether or not the suffix is optional
     * @return a String where the Strings marked by prefix and suffix have been replaced by replacement
     */
-   public static String replaceBoundedString(String initial, String prefix, String suffix, StringReplacementGenerator generator,
-                                             boolean replaceIfBoundedStringEmpty, boolean keepBoundaries)
+   public static String replaceBoundedString(final String initial, final String prefix, final String suffix, final StringReplacementGenerator generator,
+                                             final boolean replaceIfBoundedStringEmpty, final boolean keepBoundaries, final boolean suffixIsOptional)
    {
       if (ParameterValidation.isNullOrEmpty(initial))
       {
@@ -142,39 +163,110 @@
       ParameterValidation.throwIllegalArgExceptionIfNull(generator, "StringReplacementGenerator");
 
       ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(prefix, "prefix", "Tools.replaceBoundedString");
-      ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(suffix, "suffix", "Tools.replaceBoundedString");
 
-      StringBuffer tmp = new StringBuffer(initial);
+      StringBuilder tmp = new StringBuilder(initial);
       int prefixIndex = tmp.indexOf(prefix);
-      int suffixLength = suffix.length();
-      int prefixLength = prefix.length();
+      final int prefixLength = prefix.length();
+      boolean suffixAbsent = suffix == null;
 
+      // nothing to do if didn't ask for an optional suffix and we have one and it's not present in our string
+      if (!suffixIsOptional && suffix != null && tmp.indexOf(suffix) == -1)
+      {
+         return initial;
+      }
+
+      // loop as long as we can find an instance of prefix in the String
       while (prefixIndex != -1)
       {
-         int suffixIndex = tmp.indexOf(suffix, prefixIndex);
+         int suffixIndex;
+         if (suffixAbsent)
+         {
+            // replace prefix with replacement
+            if (keepBoundaries)
+            {
+               // just insert replacement for prefix
+               tmp.insert(prefixIndex + prefixLength, generator.getReplacementFor(prefix, prefix, suffix));
+            }
+            else
+            {
+               // delete prefix then insert remplacement instead
+               tmp.delete(prefixIndex, prefixIndex + prefixLength);
+               tmp.insert(prefixIndex, generator.getReplacementFor(prefix, prefix, suffix));
+            }
 
-         if (suffixIndex != -1)
+            // new lookup starting position
+            prefixIndex = tmp.indexOf(prefix, prefixIndex + prefixLength);
+         }
+         else
          {
-            // we don't care about empty bounded strings or prefix and suffix don't delimit an empty String => replace!
-            if (replaceIfBoundedStringEmpty || suffixIndex != prefixIndex + prefixLength)
+            // look for suffix
+            suffixIndex = tmp.indexOf(suffix, prefixIndex);
+
+            if (suffixIndex == -1)
             {
-               String match;
-               if (keepBoundaries)
+               // we haven't found suffix in the rest of the String so don't look for it again
+               suffixAbsent = true;
+               continue;
+            }
+            else
+            {
+               if (suffixIsOptional)
                {
-                  match = tmp.substring(prefixIndex + prefixLength, suffixIndex);
-                  tmp.delete(prefixIndex + prefixLength, suffixIndex);
-                  tmp.insert(prefixIndex + prefixLength, generator.getReplacementFor(match));
+                  // if suffix is optional, look for potential next prefix instance that we'd need to replace
+                  int nextPrefixIndex = tmp.indexOf(prefix, prefixIndex + prefixLength);
+
+                  if (nextPrefixIndex != -1 && nextPrefixIndex <= suffixIndex)
+                  {
+                     // we've found an in-between prefix, use it as the suffix for the current match
+                     // delete prefix then insert remplacement instead
+                     tmp.delete(prefixIndex, prefixIndex + prefixLength);
+                     String replacement = generator.getReplacementFor(prefix, prefix, suffix);
+                     tmp.insert(prefixIndex, replacement);
+
+                     prefixIndex = nextPrefixIndex - prefixLength + replacement.length();
+                     continue;
+                  }
                }
-               else
+
+               // we don't care about empty bounded strings or prefix and suffix don't delimit an empty String => replace!
+               if (replaceIfBoundedStringEmpty || suffixIndex != prefixIndex + prefixLength)
                {
-                  match = tmp.substring(prefixIndex, suffixIndex + suffixLength);
-                  tmp.delete(prefixIndex, suffixIndex + suffixLength);
-                  tmp.insert(prefixIndex, generator.getReplacementFor(match));
+                  String match = tmp.substring(prefixIndex + prefixLength, suffixIndex);
+                  if (keepBoundaries)
+                  {
+                     if (suffix != null)
+                     {
+                        // delete only match
+                        tmp.delete(prefixIndex + prefixLength, suffixIndex);
+                     }
+                     else
+                     {
+                        // delete nothing
+                     }
+                     tmp.insert(prefixIndex + prefixLength, generator.getReplacementFor(match, prefix, suffix));
+                  }
+                  else
+                  {
+                     int suffixLength = suffix != null ? suffix.length() : 0;
+
+                     if (suffix != null)
+                     {
+                        // if we have a suffix, delete everything between start of prefix and end of suffix
+                        tmp.delete(prefixIndex, suffixIndex + suffixLength);
+                     }
+                     else
+                     {
+                        // only delete prefix
+                        tmp.delete(prefixIndex, prefixIndex + prefixLength);
+                     }
+                     tmp.insert(prefixIndex, generator.getReplacementFor(match, prefix, suffix));
+                  }
                }
             }
+
+            prefixIndex = tmp.indexOf(prefix, prefixIndex + prefixLength);
+
          }
-
-         prefixIndex = tmp.indexOf(prefix, prefixIndex + prefixLength);
       }
 
       return tmp.toString();
@@ -182,7 +274,7 @@
 
    public static interface StringReplacementGenerator
    {
-      String getReplacementFor(String match);
+      String getReplacementFor(String match, String prefix, String suffix);
    }
 
    public static class ConstantStringReplacementGenerator implements StringReplacementGenerator
@@ -194,7 +286,7 @@
          this.replacement = replacement;
       }
 
-      public String getReplacementFor(String match)
+      public String getReplacementFor(String match, String prefix, String suffix)
       {
          return replacement;
       }

Modified: components/common/trunk/common/src/test/java/org/gatein/common/StringTestCase.java
===================================================================
--- components/common/trunk/common/src/test/java/org/gatein/common/StringTestCase.java	2010-03-19 15:23:35 UTC (rev 2313)
+++ components/common/trunk/common/src/test/java/org/gatein/common/StringTestCase.java	2010-03-19 15:50:46 UTC (rev 2314)
@@ -31,6 +31,10 @@
  */
 public class StringTestCase extends TestCase
 {
+   private static final String REPLACEMENT = "REPLACEMENT";
+   private static final String PREFIX = "PREFIX";
+   private static final String SUFFIX = "SUF";
+   private static final TestStringReplacementGenerator DEF_GEN = new TestStringReplacementGenerator(REPLACEMENT);
 
    public StringTestCase(String name)
    {
@@ -46,15 +50,102 @@
       assertEquals("_defg_defg_", TextTools.replace("_abc_abc_", "abc", "defg"));
    }
 
-   public void testReplaceBoundedString()
+   public void testReplaceAllInstancesOfBoundedString()
    {
-      assertEquals("", TextTools.replaceAllInstancesOfBoundedString("", "PREFIX", "SUFFIX", "REPLACEMENT"));
-      assertEquals("REPLACEMENT", TextTools.replaceAllInstancesOfBoundedString("PREFIXSUFFIX", "PREFIX", "SUFFIX", "REPLACEMENT"));
-      assertEquals("PREFIXSUFFIX", TextTools.replaceBoundedString("PREFIXSUFFIX", "PREFIX", "SUFFIX", "REPLACEMENT", false, true));
-      assertEquals("PREFIXSUFFIX", TextTools.replaceBoundedString("PREFIXSUFFIX", "PREFIX", "SUFFIX", "REPLACEMENT", false, false));
-      assertEquals("aaaaREPLACEMENTccccc", TextTools.replaceAllInstancesOfBoundedString("aaaaPREFIXbbbbbSUFFIXccccc", "PREFIX", "SUFFIX", "REPLACEMENT"));
-      assertEquals("aaaPREFIXbbbbSUFF", TextTools.replaceAllInstancesOfBoundedString("aaaPREFIXbbbbSUFF", "PREFIX", "SUFFIX", "REPLACEMENT"));
+      assertEquals("", TextTools.replaceAllInstancesOfBoundedString("", PREFIX, SUFFIX, REPLACEMENT));
+      assertEquals("", TextTools.replaceAllInstancesOfBoundedString("", PREFIX, "", REPLACEMENT));
+      assertEquals("", TextTools.replaceAllInstancesOfBoundedString("", "", "", REPLACEMENT));
+
+      DEF_GEN.setExpectedMatch("");
+      assertEquals(REPLACEMENT, TextTools.replaceAllInstancesOfBoundedString("PREFIXSUF", PREFIX, SUFFIX, DEF_GEN));
+
+      DEF_GEN.setExpectedMatch("bbbbb");
+      assertEquals("aaaaREPLACEMENTccccc", TextTools.replaceAllInstancesOfBoundedString("aaaaPREFIXbbbbbSUFccccc", PREFIX, SUFFIX, DEF_GEN));
+
+      DEF_GEN.setExpectedMatch(null);
+      assertEquals("aaaPREFIXbbbbSUFF", TextTools.replaceAllInstancesOfBoundedString("aaaPREFIXbbbbSUFF", PREFIX, "SUFFI", DEF_GEN));
       assertEquals("aRcccReeeR", TextTools.replaceAllInstancesOfBoundedString("aPbbScccPdSeeePS", "P", "S", "R"));
-      assertEquals("PSaPScccReeePS", TextTools.replaceBoundedString("PSaPScccPdSeeePS", "P", "S", "R", false, false));
    }
+
+   public void testReplaceBoundedString()
+   {
+      replaceBoundedString(false);
+      replaceBoundedString(true);
+   }
+
+   private void replaceBoundedString(boolean suffixIsOptional)
+   {
+      buildTestWithDefaults(PREFIX + SUFFIX, PREFIX + SUFFIX, false, true, suffixIsOptional, "");
+      buildTestWithDefaults(PREFIX + SUFFIX, PREFIX + SUFFIX, false, false, suffixIsOptional, "");
+      buildTestWithDefaults(REPLACEMENT, PREFIX + SUFFIX, true, false, suffixIsOptional, "");
+      buildTestWithDefaults(PREFIX + REPLACEMENT + SUFFIX, PREFIX + SUFFIX, true, true, suffixIsOptional, "");
+      buildTest(PREFIX + SUFFIX, PREFIX + SUFFIX, "", PREFIX, SUFFIX, false, false, suffixIsOptional, "");
+      buildTest("PSaPScccReeePS", "PSaPScccPdSeeePS", "R", "P", "S", false, false, suffixIsOptional, "d");
+   }
+
+   private void buildTestWithDefaults(String expected, String initial, boolean replaceIfBoundedStringEmpty, boolean keepBoundaries, boolean suffixIsOptional, String... expectedMatches)
+   {
+      buildTest(expected, initial, null, PREFIX, SUFFIX, replaceIfBoundedStringEmpty, keepBoundaries, suffixIsOptional, expectedMatches);
+   }
+
+   private void buildTest(String expected, String initial, String replacement, String prefix, String suffix, boolean replaceIfBoundedStringEmpty, boolean keepBoundaries, boolean suffixIsOptional, String... expectedMatches)
+   {
+      if (replacement == null)
+      {
+         replacement = REPLACEMENT;
+      }
+      TestStringReplacementGenerator gen = new TestStringReplacementGenerator(replacement);
+      gen.setExpectedMatch(expectedMatches);
+
+      assertEquals(expected, TextTools.replaceBoundedString(initial, prefix, suffix, gen, replaceIfBoundedStringEmpty, keepBoundaries, suffixIsOptional));
+   }
+
+   public void testReplaceStringsWithNullSuffix()
+   {
+      replaceStringsWithOptionalSuffix(false, null);
+      replaceStringsWithOptionalSuffix(true, null);
+   }
+
+   private void replaceStringsWithOptionalSuffix(boolean suffixIsOptional, String suffix)
+   {
+      buildTest(REPLACEMENT + "blah", PREFIX + "blah", REPLACEMENT, PREFIX, suffix, false, false, suffixIsOptional, PREFIX);
+      buildTest(PREFIX + REPLACEMENT + "blah", PREFIX + "blah", REPLACEMENT, PREFIX, suffix, false, true, suffixIsOptional, PREFIX);
+      buildTest(REPLACEMENT + "blah", PREFIX + "blah", REPLACEMENT, PREFIX, suffix, true, false, suffixIsOptional, PREFIX);
+      buildTest(REPLACEMENT, PREFIX, REPLACEMENT, PREFIX, suffix, true, false, suffixIsOptional, PREFIX);
+   }
+
+   public void testReplaceStringsWithOptionalSuffix()
+   {
+      replaceStringsWithOptionalSuffix(true, SUFFIX);
+      buildTest(REPLACEMENT + "blah" + REPLACEMENT + "foo", PREFIX + "blah" + PREFIX + "replaced" + SUFFIX + "foo", REPLACEMENT, PREFIX, SUFFIX, false, false, true, PREFIX, "replaced");
+      buildTest(REPLACEMENT + "blah" + PREFIX + REPLACEMENT + SUFFIX + "foo", PREFIX + "blah" + PREFIX + "replaced" + SUFFIX + "foo", REPLACEMENT, PREFIX, SUFFIX, false, true, true, PREFIX, "replaced");
+   }
+
+   static class TestStringReplacementGenerator implements TextTools.StringReplacementGenerator
+   {
+      private String replacement;
+      private String[] expectedMatch;
+      private int invocationCount;
+
+      TestStringReplacementGenerator(String replacement)
+      {
+         this.replacement = replacement;
+      }
+
+      public void setExpectedMatch(String... expectedMatch)
+      {
+         this.expectedMatch = expectedMatch;
+         this.invocationCount = 0;
+      }
+
+      public String getReplacementFor(String match, String prefix, String suffix)
+      {
+         if (expectedMatch == null)
+         {
+            fail("getReplacementFor shouldn't have been called");
+         }
+         assertEquals("'" + expectedMatch[invocationCount++] + "'", "'" + match + "'");
+         return replacement;
+      }
+   }
 }



More information about the gatein-commits mailing list