From 0cdc976684efcf478397b68c1d54cefc87bb92c9 Mon Sep 17 00:00:00 2001 From: Henri Yandell Date: Tue, 23 Apr 2013 06:00:41 +0000 Subject: [PATCH] Allow LookupTranslator to support CharSequence properly; previously it was working only for CharSequence's that implemented hashCode and equals(Object). LANG-882 git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1470822 13f79535-47bb-0310-9956-ffa450edef68 --- src/changes/changes.xml | 1 + .../lang3/text/translate/LookupTranslator.java | 17 +++++++++-------- .../text/translate/LookupTranslatorTest.java | 10 ++++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 80161590b..62fb41809 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -22,6 +22,7 @@ + LookupTranslator now works with implementations of CharSequence other than String ClassUtils.getShortName(String) will now only do a reverse lookup for array types Added CharSetUtils.containsAny(String, String) Provide CharSequenceUtils.regionMatches with a proper green implementation instead of inefficiently converting to Strings diff --git a/src/main/java/org/apache/commons/lang3/text/translate/LookupTranslator.java b/src/main/java/org/apache/commons/lang3/text/translate/LookupTranslator.java index d6cb07768..9cf45f8f4 100644 --- a/src/main/java/org/apache/commons/lang3/text/translate/LookupTranslator.java +++ b/src/main/java/org/apache/commons/lang3/text/translate/LookupTranslator.java @@ -23,31 +23,32 @@ import java.util.HashMap; /** * Translates a value using a lookup table. * - * NOTE: This class is broken for any CharSequence implementation that does not define - * equals(Object) and hashCode() methods as the class uses the CharSequence as - * the key to a HashMap. See http://issues.apache.org/jira/browse/LANG-882. - * * @since 3.0 * @version $Id$ */ public class LookupTranslator extends CharSequenceTranslator { - private final HashMap lookupMap; + private final HashMap lookupMap; private final int shortest; private final int longest; /** * Define the lookup table to be used in translation * + * Note that, as of Lang 3.1, the key to the lookup table is converted to a + * java.lang.String, while the value remains as a java.lang.CharSequence. + * This is because we need the key to support hashCode and equals(Object), + * allowing it to be the key for a HashMap. See LANG-882. + * * @param lookup CharSequence[][] table of size [*][2] */ public LookupTranslator(final CharSequence[]... lookup) { - lookupMap = new HashMap(); + lookupMap = new HashMap(); int _shortest = Integer.MAX_VALUE; int _longest = 0; if (lookup != null) { for (final CharSequence[] seq : lookup) { - this.lookupMap.put(seq[0], seq[1]); + this.lookupMap.put(seq[0].toString(), seq[1]); final int sz = seq[0].length(); if (sz < _shortest) { _shortest = sz; @@ -73,7 +74,7 @@ public class LookupTranslator extends CharSequenceTranslator { // descend so as to get a greedy algorithm for (int i = max; i >= shortest; i--) { final CharSequence subSeq = input.subSequence(index, index + i); - final CharSequence result = lookupMap.get(subSeq); + final CharSequence result = lookupMap.get(subSeq.toString()); if (result != null) { out.write(result.toString()); return i; diff --git a/src/test/java/org/apache/commons/lang3/text/translate/LookupTranslatorTest.java b/src/test/java/org/apache/commons/lang3/text/translate/LookupTranslatorTest.java index af4d6843b..67419f86e 100644 --- a/src/test/java/org/apache/commons/lang3/text/translate/LookupTranslatorTest.java +++ b/src/test/java/org/apache/commons/lang3/text/translate/LookupTranslatorTest.java @@ -39,4 +39,14 @@ public class LookupTranslatorTest { assertEquals("Incorrect value", "two", out.toString()); } + // Tests: https://issues.apache.org/jira/browse/LANG-882 + @Test + public void testLang882() throws IOException { + final LookupTranslator lt = new LookupTranslator(new CharSequence[][] { { new StringBuffer("one"), new StringBuffer("two") } }); + final StringWriter out = new StringWriter(); + final int result = lt.translate(new StringBuffer("one"), 0, out); + assertEquals("Incorrect codepoint consumption", 3, result); + assertEquals("Incorrect value", "two", out.toString()); + } + }