Commit 8a8e5998 authored by Christian Schudt's avatar Christian Schudt

StringUtils: Simplify verbose/duplicate and obsolete code constructs

- The 4 replace methods were nearly identical.
- Deprecate String utility, which has a simple one-liner equivalent in the JDK
- Use DatatypeConverter for byte[] to hex. It's less code and even 2-3 times faster than the previous method.
parent fbe74c8e
...@@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory; ...@@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory;
import javax.mail.internet.AddressException; import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
import javax.xml.bind.DatatypeConverter;
import java.net.IDN; import java.net.IDN;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
...@@ -45,7 +46,7 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -45,7 +46,7 @@ import java.util.concurrent.ConcurrentHashMap;
/** /**
* Utility class to perform common String manipulation algorithms. * Utility class to perform common String manipulation algorithms.
*/ */
public class StringUtils { public final class StringUtils {
private static final Logger Log = LoggerFactory.getLogger(StringUtils.class); private static final Logger Log = LoggerFactory.getLogger(StringUtils.class);
...@@ -69,32 +70,11 @@ public class StringUtils { ...@@ -69,32 +70,11 @@ public class StringUtils {
* @param oldString the String that should be replaced by newString. * @param oldString the String that should be replaced by newString.
* @param newString the String that will replace all instances of oldString. * @param newString the String that will replace all instances of oldString.
* @return a String will all instances of oldString replaced by newString. * @return a String will all instances of oldString replaced by newString.
* @deprecated Use {@link String#replaceAll(String, String)}}
*/ */
@Deprecated
public static String replace(String string, String oldString, String newString) { public static String replace(String string, String oldString, String newString) {
if (string == null) { return replace(string, oldString, newString, new int[1]);
return null;
}
int i = 0;
// Make sure that oldString appears at least once before doing any processing.
if ((i = string.indexOf(oldString, i)) >= 0) {
// Use char []'s, as they are more efficient to deal with.
char[] string2 = string.toCharArray();
char[] newString2 = newString.toCharArray();
int oLength = oldString.length();
StringBuilder buf = new StringBuilder(string2.length);
buf.append(string2, 0, i).append(newString2);
i += oLength;
int j = i;
// Replace all remaining instances of oldString with newString.
while ((i = string.indexOf(oldString, i)) > 0) {
buf.append(string2, j, i - j).append(newString2);
i += oLength;
j = i;
}
buf.append(string2, j, string2.length - j);
return buf.toString();
}
return string;
} }
/** /**
...@@ -108,29 +88,7 @@ public class StringUtils { ...@@ -108,29 +88,7 @@ public class StringUtils {
*/ */
public static String replaceIgnoreCase(String line, String oldString, public static String replaceIgnoreCase(String line, String oldString,
String newString) { String newString) {
if (line == null) { return replaceIgnoreCase(line, oldString, newString, new int[1]);
return null;
}
String lcLine = line.toLowerCase();
String lcOldString = oldString.toLowerCase();
int i = 0;
if ((i = lcLine.indexOf(lcOldString, i)) >= 0) {
char[] line2 = line.toCharArray();
char[] newString2 = newString.toCharArray();
int oLength = oldString.length();
StringBuilder buf = new StringBuilder(line2.length);
buf.append(line2, 0, i).append(newString2);
i += oLength;
int j = i;
while ((i = lcLine.indexOf(lcOldString, i)) > 0) {
buf.append(line2, j, i - j).append(newString2);
i += oLength;
j = i;
}
buf.append(line2, j, line2.length - j);
return buf.toString();
}
return line;
} }
/** /**
...@@ -146,34 +104,8 @@ public class StringUtils { ...@@ -146,34 +104,8 @@ public class StringUtils {
* @return a String will all instances of oldString replaced by newString * @return a String will all instances of oldString replaced by newString
*/ */
public static String replaceIgnoreCase(String line, String oldString, public static String replaceIgnoreCase(String line, String oldString,
String newString, int[] count) String newString, int[] count) {
{ return replace(line, oldString, newString, true, count);
if (line == null) {
return null;
}
String lcLine = line.toLowerCase();
String lcOldString = oldString.toLowerCase();
int i = 0;
if ((i = lcLine.indexOf(lcOldString, i)) >= 0) {
int counter = 1;
char[] line2 = line.toCharArray();
char[] newString2 = newString.toCharArray();
int oLength = oldString.length();
StringBuilder buf = new StringBuilder(line2.length);
buf.append(line2, 0, i).append(newString2);
i += oLength;
int j = i;
while ((i = lcLine.indexOf(lcOldString, i)) > 0) {
counter++;
buf.append(line2, j, i - j).append(newString2);
i += oLength;
j = i;
}
buf.append(line2, j, line2.length - j);
count[0] = counter;
return buf.toString();
}
return line;
} }
/** /**
...@@ -186,13 +118,19 @@ public class StringUtils { ...@@ -186,13 +118,19 @@ public class StringUtils {
* @return a String will all instances of oldString replaced by newString. * @return a String will all instances of oldString replaced by newString.
*/ */
public static String replace(String line, String oldString, public static String replace(String line, String oldString,
String newString, int[] count) String newString, int[] count) {
{ return replace(line, oldString, newString, false, count);
}
private static String replace(String line, String oldString,
String newString, boolean ignoreCase, int[] count) {
if (line == null) { if (line == null) {
return null; return null;
} }
String lcLine = ignoreCase ? line.toLowerCase() : line;
String lcOldString = ignoreCase ? oldString.toLowerCase() : oldString;
int i = 0; int i = 0;
if ((i = line.indexOf(oldString, i)) >= 0) { if ((i = lcLine.indexOf(lcOldString, i)) >= 0) {
int counter = 1; int counter = 1;
char[] line2 = line.toCharArray(); char[] line2 = line.toCharArray();
char[] newString2 = newString.toCharArray(); char[] newString2 = newString.toCharArray();
...@@ -201,7 +139,7 @@ public class StringUtils { ...@@ -201,7 +139,7 @@ public class StringUtils {
buf.append(line2, 0, i).append(newString2); buf.append(line2, 0, i).append(newString2);
i += oLength; i += oLength;
int j = i; int j = i;
while ((i = line.indexOf(oldString, i)) > 0) { while ((i = lcLine.indexOf(lcOldString, i)) > 0) {
counter++; counter++;
buf.append(line2, j, i - j).append(newString2); buf.append(line2, j, i - j).append(newString2);
i += oLength; i += oLength;
...@@ -437,25 +375,12 @@ public class StringUtils { ...@@ -437,25 +375,12 @@ public class StringUtils {
/** /**
* Turns an array of bytes into a String representing each byte as an * Turns an array of bytes into a String representing each byte as an
* unsigned hex number. * unsigned hex number.
* <p>
* Method by Santeri Paavolainen, Helsinki Finland 1996<br>
* (c) Santeri Paavolainen, Helsinki Finland 1996<br>
* Distributed under LGPL.</p>
* *
* @param bytes an array of bytes to convert to a hex-string * @param bytes an array of bytes to convert to a hex-string
* @return generated hex string * @return generated hex string
*/ */
public static String encodeHex(byte[] bytes) { public static String encodeHex(byte[] bytes) {
StringBuilder buf = new StringBuilder(bytes.length * 2); return DatatypeConverter.printHexBinary(bytes).toLowerCase();
int i;
for (i = 0; i < bytes.length; i++) {
if (((int)bytes[i] & 0xff) < 0x10) {
buf.append('0');
}
buf.append(Long.toString((int)bytes[i] & 0xff, 16));
}
return buf.toString();
} }
/** /**
...@@ -466,63 +391,7 @@ public class StringUtils { ...@@ -466,63 +391,7 @@ public class StringUtils {
* @return a byte array representing the hex String[ * @return a byte array representing the hex String[
*/ */
public static byte[] decodeHex(String hex) { public static byte[] decodeHex(String hex) {
char[] chars = hex.toCharArray(); return DatatypeConverter.parseHexBinary(hex);
byte[] bytes = new byte[chars.length / 2];
int byteCount = 0;
for (int i = 0; i < chars.length; i += 2) {
int newByte = 0x00;
newByte |= hexCharToByte(chars[i]);
newByte <<= 4;
newByte |= hexCharToByte(chars[i + 1]);
bytes[byteCount] = (byte)newByte;
byteCount++;
}
return bytes;
}
/**
* Returns the the byte value of a hexadecmical char (0-f). It's assumed
* that the hexidecimal chars are lower case as appropriate.
*
* @param ch a hexedicmal character (0-f)
* @return the byte value of the character (0x00-0x0F)
*/
private static byte hexCharToByte(char ch) {
switch (ch) {
case '0':
return 0x00;
case '1':
return 0x01;
case '2':
return 0x02;
case '3':
return 0x03;
case '4':
return 0x04;
case '5':
return 0x05;
case '6':
return 0x06;
case '7':
return 0x07;
case '8':
return 0x08;
case '9':
return 0x09;
case 'a':
return 0x0A;
case 'b':
return 0x0B;
case 'c':
return 0x0C;
case 'd':
return 0x0D;
case 'e':
return 0x0E;
case 'f':
return 0x0F;
}
return 0x00;
} }
/** /**
...@@ -1224,7 +1093,9 @@ public class StringUtils { ...@@ -1224,7 +1093,9 @@ public class StringUtils {
* *
* @param input The source string * @param input The source string
* @return The UTF-8 encoding for the given string * @return The UTF-8 encoding for the given string
* @deprecated Use {@code input.getBytes(StandardCharsets.UTF_8)}
*/ */
@Deprecated
public static byte[] getBytes(String input) { public static byte[] getBytes(String input) {
return input.getBytes(StandardCharsets.UTF_8); return input.getBytes(StandardCharsets.UTF_8);
} }
...@@ -1234,7 +1105,9 @@ public class StringUtils { ...@@ -1234,7 +1105,9 @@ public class StringUtils {
* *
* @param input The source byte array * @param input The source byte array
* @return The UTF-8 encoded String for the given byte array * @return The UTF-8 encoded String for the given byte array
* @deprecated Use {@code new String(input, StandardCharsets.UTF_8)}
*/ */
@Deprecated
public static String getString(byte[] input) { public static String getString(byte[] input) {
return new String(input, StandardCharsets.UTF_8); return new String(input, StandardCharsets.UTF_8);
} }
......
...@@ -28,6 +28,16 @@ public class StringUtilsTest { ...@@ -28,6 +28,16 @@ public class StringUtilsTest {
} }
@Test
public void testStringReplace() {
assertEquals(StringUtils.replace("Hello Foo Foo", "Foo", "World"), "Hello World World");
assertEquals(StringUtils.replace("Hello Foo foo", "Foo", "World"), "Hello World foo");
assertEquals(StringUtils.replaceIgnoreCase("Hello Foo foo", "Foo", "World"), "Hello World World");
int[] count = new int[1];
assertEquals(StringUtils.replaceIgnoreCase("Hello Foo foo", "Foo", "World", count), "Hello World World");
assertEquals(count[0], 2);
}
private void assertValidDomainName(String domain) { private void assertValidDomainName(String domain) {
assertValidDomainName(domain, domain); assertValidDomainName(domain, domain);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment