package org.emdev.utils;
import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.Collator;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.Set;
public class StringUtils {
public static final NaturalStringComparator NSC = new NaturalStringComparator();
public static final NaturalFileComparator NFC = new NaturalFileComparator();
private StringUtils() {
}
/**
* Cleanup title. Remove from title file extension and (...), [...]
*/
public static String cleanupTitle(final String in) {
String out = in;
try {
out = in.substring(0, in.lastIndexOf('.'));
out = out.replaceAll("\\(.*?\\)|\\[.*?\\]", "").replaceAll("_", " ").replaceAll(".fb2$", "").trim();
} catch (final IndexOutOfBoundsException e) {
}
return out;
}
public static String md5(final String in) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(in.getBytes());
final byte[] a = digest.digest();
final int len = a.length;
final StringBuilder sb = new StringBuilder(len << 1);
for (int i = 0; i < len; i++) {
sb.append(Character.forDigit((a[i] & 0xf0) >> 4, 16));
sb.append(Character.forDigit(a[i] & 0x0f, 16));
}
return sb.toString();
} catch (final NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public static Set<String> split(final String separator, final String value) {
final Set<String> list = new LinkedHashSet<String>();
final String[] split = value.split(separator);
for (final String string : split) {
if (LengthUtils.isNotEmpty(string)) {
list.add(string);
}
}
return list;
}
public static String merge(final String separator, final String... items) {
final StringBuffer result = new StringBuffer();
for (final String item : items) {
if (LengthUtils.isNotEmpty(item)) {
if (result.length() > 0) {
result.append(separator);
}
result.append(item);
}
}
return result.toString();
}
public static String merge(final String separator, final Collection<String> items) {
final StringBuffer result = new StringBuffer();
for (final String item : items) {
if (LengthUtils.isNotEmpty(item)) {
if (result.length() > 0) {
result.append(separator);
}
result.append(item);
}
}
return result.toString();
}
public static final int compareNatural(String firstString, String secondString) {
int firstIndex = 0;
int secondIndex = 0;
Collator collator = Collator.getInstance();
while (true) {
if (firstIndex == firstString.length() && secondIndex == secondString.length()) {
return 0;
}
if (firstIndex == firstString.length()) {
return -1;
}
if (secondIndex == secondString.length()) {
return 1;
}
if (Character.isDigit(firstString.charAt(firstIndex))
&& Character.isDigit(secondString.charAt(secondIndex))) {
int firstZeroCount = 0;
while (firstString.charAt(firstIndex) == '0') {
firstZeroCount++;
firstIndex++;
if (firstIndex == firstString.length()) {
break;
}
}
int secondZeroCount = 0;
while (secondString.charAt(secondIndex) == '0') {
secondZeroCount++;
secondIndex++;
if (secondIndex == secondString.length()) {
break;
}
}
if ((firstIndex == firstString.length() || !Character.isDigit(firstString.charAt(firstIndex)))
&& (secondIndex == secondString.length() || !Character
.isDigit(secondString.charAt(secondIndex)))) {
continue;
}
if ((firstIndex == firstString.length() || !Character.isDigit(firstString.charAt(firstIndex)))
&& !(secondIndex == secondString.length() || !Character.isDigit(secondString
.charAt(secondIndex)))) {
return -1;
}
if ((secondIndex == secondString.length() || !Character.isDigit(secondString.charAt(secondIndex)))) {
return 1;
}
int diff = 0;
do {
if (diff == 0) {
diff = firstString.charAt(firstIndex) - secondString.charAt(secondIndex);
}
firstIndex++;
secondIndex++;
if (firstIndex == firstString.length() && secondIndex == secondString.length()) {
return diff != 0 ? diff : firstZeroCount - secondZeroCount;
}
if (firstIndex == firstString.length()) {
if (diff == 0) {
return -1;
}
return Character.isDigit(secondString.charAt(secondIndex)) ? -1 : diff;
}
if (secondIndex == secondString.length()) {
if (diff == 0) {
return 1;
}
return Character.isDigit(firstString.charAt(firstIndex)) ? 1 : diff;
}
if (!Character.isDigit(firstString.charAt(firstIndex))
&& !Character.isDigit(secondString.charAt(secondIndex))) {
if (diff != 0) {
return diff;
}
break;
}
if (!Character.isDigit(firstString.charAt(firstIndex))) {
return -1;
}
if (!Character.isDigit(secondString.charAt(secondIndex))) {
return 1;
}
} while (true);
} else {
int aw = firstIndex;
int bw = secondIndex;
do {
firstIndex++;
} while (firstIndex < firstString.length() && !Character.isDigit(firstString.charAt(firstIndex)));
do {
secondIndex++;
} while (secondIndex < secondString.length() && !Character.isDigit(secondString.charAt(secondIndex)));
String as = firstString.substring(aw, firstIndex);
String bs = secondString.substring(bw, secondIndex);
int subwordResult = collator.compare(as, bs);
if (subwordResult != 0) {
return subwordResult;
}
}
}
}
@Deprecated
public static Comparator<? super File> getNaturalFileComparator() {
return NFC;
}
public static int split(char[] str, int begin, int len, int[] outStart, int[] outLength, boolean lineBreaksOnly) {
if (str == null) {
return 0;
}
if (len == 0) {
return 0;
}
int i = begin, start = begin;
int index = 0;
boolean match = false;
while (i < begin + len) {
if ((lineBreaksOnly && (str[i] == 0x0D || str[i] == 0x0A)) || (!lineBreaksOnly && (str[i] == 0x20 || str[i] == 0x0D || str[i] == 0x0A || str[i] == 0x09))) {
if (match) {
outStart[index] = start;
outLength[index] = i - start;
index++;
match = false;
}
start = ++i;
continue;
}
match = true;
i++;
}
if (match) {
outStart[index] = start;
outLength[index] = i - start;
index++;
}
return index;
}
public static final class NaturalStringComparator implements Comparator<String> {
public int compare(String o1, String o2) {
return compareNatural(o1, o2);
}
}
public static final class NaturalFileComparator implements Comparator<File> {
public int compare(File o1, File o2) {
if (o1 == null) {
return -1;
}
if (o2 == null) {
return 1;
}
return compareNatural(o1.getAbsolutePath(), o2.getAbsolutePath());
}
}
public static int parseInt(char[]string, int start, int length, int radix) throws NumberFormatException {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
throw new NumberFormatException("Invalid radix: " + radix);
}
if (string == null) {
throw new NumberFormatException(new String(string, start, length));
}
int i = 0;
if (length == 0) {
throw new NumberFormatException(new String(string, start, length));
}
boolean negative = string[start+i] == '-';
if (negative && ++i == length) {
throw new NumberFormatException(new String(string, start, length));
}
return parse(string, start, length, i, radix, negative);
}
private static int parse(char[]string, int start, int length, int offset, int radix, boolean negative) throws NumberFormatException {
int max = Integer.MIN_VALUE / radix;
int result = 0;
while (offset < length) {
int digit = Character.digit(string[start+(offset++)], radix);
if (digit == -1) {
throw new NumberFormatException(new String(string, start, length));
}
if (max > result) {
throw new NumberFormatException(new String(string, start, length));
}
int next = result * radix - digit;
if (next > result) {
throw new NumberFormatException(new String(string, start, length));
}
result = next;
}
if (!negative) {
result = -result;
if (result < 0) {
throw new NumberFormatException(new String(string, start, length));
}
}
return result;
}
}