
org.nuiton.util.StringUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nuiton-utils Show documentation
Show all versions of nuiton-utils Show documentation
Library of usefull class to be used in any project.
/*
* #%L
* Nuiton Utils
*
* $Id: StringUtil.java 2386 2012-07-31 22:27:06Z tchemit $
* $HeadURL: http://svn.nuiton.org/svn/nuiton-utils/tags/nuiton-utils-2.6.10/nuiton-utils/src/main/java/org/nuiton/util/StringUtil.java $
* %%
* Copyright (C) 2004 - 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
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package org.nuiton.util;
import org.apache.commons.lang3.SystemUtils;
import java.awt.Color;
import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* Classe contenant un ensemle de methode static utiles pour la manipulation des
* chaine de caractere mais qui ne sont pas defini dans la classe String de
* Java.
*
* Created: 21 octobre 2003
*
* @author bpoussin
* @author tchemit
* $Id: StringUtil.java 2386 2012-07-31 22:27:06Z tchemit $
*/
public class StringUtil { // StringUtil
public static final String[] EMPTY_STRING_ARRAY = new String[0];
/** Constructor for the StringUtil object */
protected StringUtil() {
}
/**
* Know if a string is a valid e-mail.
*
* @param str a string
* @return true if str
is syntactically a valid e-mail address
* @since 2.1
*/
public static boolean isEmail(String str) {
return str.matches("^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+((\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)?)+@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\\-]*[a-zA-Z0-9])?$");
}
/**
* Add cotes if needed to escape special csv chars (',', '\n', '\t', ',', ';')
*
* @param value to escape
* @param csvSeparator separator used for csv
* @return escaped if needed value
*/
public static String escapeCsvValue(String value, String csvSeparator) {
boolean valueNeedQuotes =
value.contains("\n")
|| value.contains("\t")
|| value.contains(",")
|| value.contains(";")
|| value.contains(csvSeparator);
if (valueNeedQuotes) {
// escape '"' char to prevent
value = value.replaceAll("\"", "\"\"");
value = "\"" + value + "\"";
}
return value;
}
/**
* Contract to use in {@link StringUtil#join(Iterable, ToString, String, boolean) }
* method. This will provide a toString method to convert an object in a
* string.
*
* @param type of object manipulated
*/
public interface ToString {
/**
* Convert an object o in a string.
*
* @param o to convert
* @return the string for this object o
*/
String toString(O o);
}
/**
* Used to build csv file using {@link StringUtil#join(Iterable, ToString, String, boolean) }
* method. This will provide a toString method to convert an object in a
* string and escape csv values if needed.
*
* @param type of object manipulated
*/
public static class ToCSV implements StringUtil.ToString {
protected String csvSeparator;
public ToCSV(String csvSeparator) {
this.csvSeparator = csvSeparator;
}
@Override
public String toString(O o) {
String value = getStringValue(o);
return escapeCsvValue(value, csvSeparator);
}
/**
* Use {@link Object#toString()} method by default
* Must be @{@link Override} to use other methods to get string value.
*
* @param o to convert
* @return String value
*/
public String getStringValue(O o) {
return o.toString();
}
}
/**
* Used to concat an {@code iterable} of Object separated
* by {@code separator} using the toString() method of each object.
* You can specify if the string must be trimmed or not.
*
* @param iterable Iterable with objects to treate
* @param separator to used
* @param trim if each string must be trim
* @return the String chain of all elements separated by separator, never
* return null, will return an empty String for an empty list.
*/
public static String join(Iterable> iterable, String separator,
boolean trim) {
String result = join(iterable, null, separator, trim);
return result;
}
/**
* Used to concat an {@code iterable} of object {@code } separated by
* {@code separator}. This method need a {@code ts} contract to
* call on each object. The ToString can be null to use directly the
* toString() method on the object. The {@code trim} boolean is used
* to specify if each string object has to be trimmed. The null elements
* in the {@code list} will be ignored.
*
* @param type of object in the list
* @param iterable Iterable with objects to treate
* @param ts used to specify how the object is converted in String
* @param separator to used between each object string
* @param trim if trim() method need to by apply on each object string
* @return the String chain of all elements separated by separator, never
* return null, will return an empty String for an empty list.
* @throws NullPointerException if iterable is {@code null}.
*/
public static String join(Iterable iterable, ToString ts,
String separator, boolean trim) throws NullPointerException {
if (iterable == null) {
throw new NullPointerException("null iterable can't be used" +
" to join the elements with " + separator);
}
// Do nothing for an empty list
if (!iterable.iterator().hasNext()) {
return "";
}
StringBuilder builder = new StringBuilder();
for (O o : iterable) {
// Ignore the null object in the list
if (o == null) {
continue;
}
String str;
// Use ToString contract from argument
if (ts != null) {
str = ts.toString(o);
// Or call toString() method directly on object
} else {
str = o.toString();
}
// Apply trim if needed
if (trim) {
str = str.trim();
}
builder.append(separator).append(str);
}
// Suppress the first separator at beginning of the chain
String result = builder.substring(separator.length());
return result;
}
/**
* substring from begin to end of s
*
* example:
* substring("tatetitotu", -4) => totu
*
* @param s the string to substring
* @param begin if begin < 0 then begin start at end of string - begin
* @return the result of substring
*/
public static String substring(String s, int begin) {
String result = substring(s, begin, s.length());
return result;
}
/**
* substring from begin to end of s
*
* example:
* substring("tatetitotu", -4, -2) => to
*
* @param s the string to substring
* @param begin if begin < 0 then begin start at end of string - begin
* @param end if end < 0 then end start at end of string - end
* @return the result of substring
*/
public static String substring(String s, int begin, int end) {
if (begin < 0) {
begin = s.length() + begin;
}
if (end < 0) {
end = s.length() + end;
}
if (end < begin) {
end = begin;
}
String result;
result = s.substring(begin, end);
return result;
}
private static final Character[] openingChars = {'(', '{', '['};
private static final Character[] closingChars = {')', '}', ']'};
/**
* Split string use 'separator' as separator. If String contains "'()[]{}
* this method count the number of open char end close char to split
* correctly argument
*
* WARNING: cette method ne fonctionne pas si le contenu contient
* des carateres utilisé pour le parsing et présent une seule fois.
* Par exemple: "l'idenfiant" contient ' qui empeche totalement le
* parsing de fonctionner.
*
* @param args string to split
* @param separator separator use to split string
* @return array of string
*/
public static String[] split(String args, String separator) {
return split(openingChars, closingChars, args, separator);
}
/**
* Use to split string array representation in array according with ',' as
* default separator.
*
* WARNING: cette method ne fonctionne pas si le contenu contient
* des carateres utilisé pour le parsing et présent une seule fois.
* Par exemple: "l'idenfiant" contient ' qui empeche totalement le
* parsing de fonctionner.
*
* @param stringList string that represent array
* @return array with length > 0 if listAsString != null or null
*/
public static String[] split(String stringList) {
String[] result;
result = split(stringList, ",");
return result;
}
/**
* Split string use 'separator' as separator. If String contains "'
* and openingChar
closingChars
*
* this method count the number of open char end close char to split
* correctly argument
*
* WARNING: cette method ne fonctionne pas si le contenu contient
* des carateres utilisé pour le parsing et présent une seule fois.
* Par exemple: "l'idenfiant" contient ' qui empeche totalement le
* parsing de fonctionner.
*
* @param openingChars list of opening caracteres
* @param closingChars list of closing caracteres
* @param args string to split
* @param separator separator use to split string
* @return array of string
*/
public static String[] split(Character[] openingChars,
Character[] closingChars,
String args, String separator) {
if (args == null) {
return EMPTY_STRING_ARRAY;
}
List result = new ArrayList();
int start = 0;
int end;
StringBuilder op = new StringBuilder(); // stack of {([< currently open
char last = '\0'; // contains " or ' if string is openned
List opening = Arrays.asList(openingChars);
List closing = Arrays.asList(closingChars);
for (int i = 0; i < args.length(); i++) {
char c = args.charAt(i);
if (c == '\\') {
// pass next char
i++;
} else if (last != '"' && last != '\'') {
if (opening.contains(c)) {
op.append(c);
} else if (closing.contains(c)) {
op.deleteCharAt(op.length() - 1);
} else if (c == '"' || c == '\'') {
// open string " or '
last = c;
} else if (op.length() == 0 &&
args.regionMatches(i, separator, 0,
separator.length())) {
// end of one arguement
end = i;
// pass separator
i += separator.length() - 1;
String a = args.substring(start, end);
result.add(a);
// start of next argument
start = end + separator.length();
}
} else if (c == last) {
// close string " or '
last = '\0';
}
}
if (start < args.length()) {
String a = args.substring(start, args.length());
result.add(a);
}
return result.toArray(new String[result.size()]);
}
public static boolean toBoolean(String s) {
return "true".equalsIgnoreCase(s);
}
public static byte toByte(String s) {
return Byte.parseByte(s);
}
public static double toDouble(String s) {
return Double.parseDouble(s);
}
public static float toFloat(String s) {
return Float.parseFloat(s);
}
public static long toLong(String s) {
return Long.parseLong(s);
}
public static short toShort(String s) {
return Short.parseShort(s);
}
public static int toInt(String s) {
return Integer.parseInt(s);
}
public static char toChar(String s) {
// fixme a revoir
return s.charAt(0);
}
public static boolean[] toArrayBoolean(String... s) {
boolean[] result = new boolean[s.length];
for (int i = 0; i < result.length; i++) {
result[i] = toBoolean(s[i]);
}
return result;
}
public static byte[] toArrayByte(String... s) {
byte[] result = new byte[s.length];
for (int i = 0; i < result.length; i++) {
result[i] = toByte(s[i]);
}
return result;
}
public static double[] toArrayDouble(String... s) {
double[] result = new double[s.length];
for (int i = 0; i < result.length; i++) {
result[i] = toDouble(s[i]);
}
return result;
}
public static float[] toArrayFloat(String... s) {
float[] result = new float[s.length];
for (int i = 0; i < result.length; i++) {
result[i] = toFloat(s[i]);
}
return result;
}
public static long[] toArrayLong(String... s) {
long[] result = new long[s.length];
for (int i = 0; i < result.length; i++) {
result[i] = toLong(s[i]);
}
return result;
}
public static short[] toArrayShort(String... s) {
short[] result = new short[s.length];
for (int i = 0; i < result.length; i++) {
result[i] = toShort(s[i]);
}
return result;
}
public static int[] toArrayInt(String... s) {
int[] result = new int[s.length];
for (int i = 0; i < result.length; i++) {
result[i] = toInt(s[i]);
}
return result;
}
public static char[] toArrayChar(String... s) {
char[] result = new char[s.length];
for (int i = 0; i < result.length; i++) {
result[i] = toChar(s[i]);
}
// fixme a revoir
return result;
}
private static final char[] HEX_CHARS = {'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f',};
/**
* Turns array of bytes into string representing each byte as
* unsigned hex number.
*
* @param hash Array of bytes to convert to hex-string
* @return Generated hex string
*/
public static String asHex(byte hash[]) {
char buf[] = new char[hash.length * 2];
for (int i = 0, x = 0; i < hash.length; i++) {
buf[x++] = HEX_CHARS[hash[i] >>> 4 & 0xf];
buf[x++] = HEX_CHARS[hash[i] & 0xf];
}
return new String(buf);
}
/**
* Essai de convertir une chaine de caractere en une couleur si possible si
* ce n'est pas possible retourne null.
*
* @param s la couleur sous la forme de string, par exemple "red",
* "yellow" ou bien en RGB "#FFAA99", et avec un canal alpha
* "#FFAA3366"
* @return la couleur demandé si possible sinon null
* @throws IllegalArgumentException
* @throws StringUtilException if any problem while conversion
*/
public static Color toColor(String s) throws StringUtilException {
try {
if (s.startsWith("#")) {
// récuperation des valeurs hexa
String hr = s.substring(1, 3);
String hg = s.substring(3, 5);
String hb = s.substring(5, 7);
// conversion en entier
int r = Integer.parseInt(hr, 16);
int g = Integer.parseInt(hg, 16);
int b = Integer.parseInt(hb, 16);
if (s.length() == 9) {
// s'il y a un canal alpha on l'utilise
String ha = s.substring(7, 9);
int a = Integer.parseInt(ha, 16);
return new Color(r, g, b, a);
} else {
return new Color(r, g, b);
}
} else {
Field f;
f = Color.class.getField(s);
return (Color) f.get(Color.class);
}
} catch (NumberFormatException e) {
throw new StringUtilException(
"Error during conversion from string to color", e);
} catch (SecurityException e) {
throw new StringUtilException(
"Error during conversion from string to color", e);
} catch (NoSuchFieldException e) {
throw new StringUtilException(
"Error during conversion from string to color", e);
} catch (IllegalArgumentException e) {
throw new StringUtilException(
"Error during conversion from string to color", e);
} catch (IllegalAccessException e) {
throw new StringUtilException(
"Error during conversion from string to color", e);
}
}
public static Date toDate(String s) throws ParseException {
return DateFormat.getDateInstance().parse(s);
}
static final protected double[] timeFactors = {1000000, 1000, 60, 60, 24};
static final protected String[] timeUnites = {"ns", "ms", "s", "m", "h",
"d"};
/**
* Converts an time delay into a human readable format.
*
* @param value the delay to convert
* @return the memory representation of the given value
* @see #convert(long, double[], String[])
*/
public static String convertTime(long value) {
return convert(value, timeFactors, timeUnites);
}
/**
* Converts an time period into a human readable format.
*
* @param value the begin time
* @param value2 the end time
* @return the time representation of the given value
* @see #convert(long, double[], String[])
*/
public static String convertTime(long value, long value2) {
return convertTime(value2 - value);
}
static final protected double[] memoryFactors = {1024, 1024, 1024, 1024};
static final protected String[] memoryUnites = {"o", "Ko", "Mo", "Go",
"To"};
/**
* Converts an memory measure into a human readable format.
*
* @param value the memory measure to convert
* @return the memory representation of the given value
* @see #convert(long, double[], String[])
*/
public static String convertMemory(long value) {
return convert(value, memoryFactors, memoryUnites);
}
/**
* Note: this method use the current locale
* (the {@link Locale#getDefault()}) in the method
* {@link MessageFormat#MessageFormat(String)}.
*
* @param value value to convert
* @param factors facotrs used form conversion
* @param unites libelle of unites to use
* @return the converted representation of the given value
*/
public static String convert(long value, double[] factors, String[] unites) {
long sign = value == 0 ? 1 : value / Math.abs(value);
int i = 0;
double tmp = Math.abs(value);
while (i < factors.length && i < unites.length && tmp > factors[i]) {
tmp = tmp / factors[i++];
}
tmp *= sign;
String result;
result = MessageFormat.format("{0,number,0.###}{1}", tmp,
unites[i]);
return result;
}
/**
* Vérifie q'une chaine de caractère est valid pour les bloc openner closer, ie.
*
* que les blocs définit par les deux caractères s'entrechevauchent pas.
*
* Exemple avec '(' ')' :
*
* (a(b)) est valide, par contre ((aaa))) n'est pas valide
*
* @param txt txte a verifier
* @param opener le caractère ouvrant
* @param closer le caractère fermant
* @return true
is la chaine est valide
*/
public static boolean checkEnclosure(String txt, char opener, char closer) {
if (txt.indexOf(opener) == -1 && txt.indexOf(closer) == -1) {
// ok pas de block détectés
return true;
}
List opens = new ArrayList();
for (int i = 0; i < txt.length(); i++) {
char c = txt.charAt(i);
if (c == opener) {
// add a open block
opens.add(i);
continue;
}
if (c == closer) {
if (opens.isEmpty()) {
// problem no block left
return false;
}
// on supprime le dernier bloc
opens.remove(opens.size() - 1);
}
}
return opens.isEmpty();
}
/**
* Convertir un nom en une constante Java
*
* Les seuls caractères autorisés sont les alpha numériques, ains
* que l'underscore. tous les autres caractères seront ignorés.
*
* @param name le nom à convertir
* @return la constante générée
*/
public static String convertToConstantName(String name) {
StringBuilder sb = new StringBuilder();
char lastChar = 0;
for (int i = 0, j = name.length(); i < j; i++) {
char c = name.charAt(i);
if (Character.isDigit(c)) {
sb.append(c);
lastChar = c;
continue;
}
if (!Character.isLetter(c)) {
if (lastChar != '_') {
sb.append('_');
}
lastChar = '_';
continue;
}
if (Character.isUpperCase(c)) {
if (!Character.isUpperCase(lastChar) && lastChar != '_') {
sb.append('_');
}
sb.append(c);
} else {
sb.append(Character.toUpperCase(c));
}
lastChar = c;
}
String result = sb.toString();
// clean tail
while (!result.isEmpty() && result.endsWith("_")) {
result = result.substring(0, result.length() - 1);
}
// clean head
while (!result.isEmpty() && result.startsWith("_")) {
result = result.substring(1);
}
return result;
}
/**
* Convert a String to MD5.
*
* @param toEncode string concerned
* @return md5 corresponding
* @throws IllegalStateException if could not found algorithm MD5
*/
public static String encodeMD5(String toEncode) {
byte[] uniqueKey = toEncode.getBytes();
byte[] hash;
// on récupère un objet qui permettra de crypter la chaine
hash = MD5InputStream.getMD5Digest().digest(uniqueKey);
// hash = MessageDigest.getInstance("MD5").digest(uniqueKey);
StringBuilder hashString = new StringBuilder();
for (byte aHash : hash) {
String hex = Integer.toHexString(aHash);
if (hex.length() == 1) {
hashString.append("0");
hashString.append(hex.charAt(hex.length() - 1));
} else {
hashString.append(hex.substring(hex.length() - 2));
}
}
return hashString.toString();
}
/**
* Convert a String to SHA1.
*
* @param toEncode string to encode
* @return sha1 corresponding
* @throws IllegalStateException if could not found algorithm SHA1
*/
public static String encodeSHA1(String toEncode) {
String result;
try {
MessageDigest sha1Md = MessageDigest.getInstance("SHA-1");
byte[] digest = sha1Md.digest(toEncode.getBytes());
result = asHex(digest);
} catch (NoSuchAlgorithmException ex) {
throw new IllegalStateException("Can't find SHA-1 message digest algorithm", ex);
}
return result;
}
/**
*
* @return the file separator escaped for a regex regarding the os used.
*/
public static String getFileSeparatorRegex() {
String result;
if(SystemUtils.IS_OS_WINDOWS) {
result = "\\\\";
} else {
result = "/";
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy