All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.util.StringUtil Maven / Gradle / Ivy

There is a newer version: 3.1
Show newest version
/*
 * #%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