Java tutorial
/******************************************************************************* * Copyright (c) 2005-2011, G. Weirich and Elexis * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * G. Weirich - initial implementation * *******************************************************************************/ package ch.rgw.tools; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Vector; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import org.apache.commons.compress.bzip2.CBZip2InputStream; import org.apache.commons.compress.bzip2.CBZip2OutputStream; import ch.rgw.compress.CompEx; import ch.rgw.compress.GLZInputStream; import ch.rgw.compress.GLZOutputStream; import ch.rgw.compress.HuffmanInputStream; import ch.rgw.compress.HuffmanOutputStream; import ch.rgw.compress.HuffmanTree; import ch.rgw.tools.net.NetTool; /** * Einige Hilfsfunktionen mit und an Strings und String-Collections * * @author Gerry Weirich */ public class StringTool { public static final String Version() { return "2.0.4"; } private static String default_charset = "utf-8"; public static final String leer = ""; public static final String space = " "; public static final String equals = "="; public static final String crlf = "\r\n"; public static final String lf = "\n"; public static final String slash = "/"; public static final String backslash = "\\"; public static final String numbers = "[0-9]+"; public static final String wordSeparatorChars = "\n\r\t.,;:!? "; public static final String wordSeparators = "[\\t ,\\.:\\?!\\n\\r]"; public static final String lineSeparators = "[\\n\\r\\.\\?!;]"; public static final String ipv4address = "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"; public static final String ipv6address = "((([0-9a-f]{1,4}+:){7}+[0-9a-f]{1,4}+)|(:(:[0-9a-f]{1,4}+){1,6}+)|(([0-9a-f]{1,4}+:){1,6}+:)|(::)|(([0-9a-f]{1,4}+:)(:[0-9a-f]{1,4}+){1,5}+)|(([0-9a-f]{1,4}+:){1,2}+(:[0-9a-f]{1,4}+){1,4}+)|(([0-9a-f]{1,4}+:){1,3}+(:[0-9a-f]{1,4}+){1,3}+)|(([0-9a-f]{1,4}+:){1,4}+(:[0-9a-f]{1,4}+){1,2}+)|(([0-9a-f]{1,4}+:){1,5}+(:[0-9a-f]{1,4}+))|(((([0-9a-f]{1,4}+:)?([0-9a-f]{1,4}+:)?([0-9a-f]{1,4}+:)?([0-9a-f]{1,4}+:)?)|:)(:(([0-9]{1,3}+\\.){3}+[0-9]{1,3}+)))|(:(:[0-9a-f]{1,4}+)*:([0-9]{1,3}+\\.){3}+[0-9]{1,3}+))(/[0-9]+)?"; // public static final String wordChars="a-zA-Z\'"; public static final String wordChars = "\\p{L}\'"; private static int ipHash; private static long sequence; public static final int LEFT = 1; public static final int RIGHTS = 2; /** * Set the charset to use in all charset-dependent String operations * * @param charset_name * the name of the charset (that must be valid) */ public static void setDefaultCharset(String charset_name) { default_charset = charset_name; } /** * get the configured default charset * * @return the charset name (defaults to utf-8) */ public static String getDefaultCharset() { return default_charset; } /** * create a String from a byte array, using the configured charset (defaults to utf-8) * * @param bytes * an array of bytes rthat constitute a String in the indicated charset. * @return the created String. */ public static String createString(byte[] bytes) { try { return new String(bytes, default_charset); } catch (UnsupportedEncodingException e) { // should not happen ExHandler.handle(e); } return null; } /** * Create a byte arra from a String using the configured charset (defaults to utf-8) * * @param string * @return */ public static byte[] getBytes(String string) { try { return string.getBytes(default_charset); } catch (UnsupportedEncodingException e) { // should not happen ExHandler.handle(e); } return null; } /** * return the bounds of a Rectangle around a String * * @deprecated this ist a dependency to Swing */ @Deprecated public static Rectangle2D getStringBounds(final String s, final Graphics g) { if (isNothing(s)) { return new Rectangle(0, 0); } FontRenderContext frc = ((Graphics2D) g).getFontRenderContext(); Font fnt = g.getFont(); Rectangle2D r = fnt.getStringBounds(s, frc); return r; } /** * Split a String into a String Arry * * @deprecated obsoleted by java 1.4x 's {@link String#split(String) String.split} method. */ @Deprecated @SuppressWarnings("unchecked") public static String[] split(final String m, final String delim) { Vector v = splitV(m, delim); if (v == null) { return null; } String[] ret = (String[]) v.toArray(new String[1]); return ret; } /** * Spaltet einen String in einen Vektor * * @param m * der zu splittende String * @param delim * Trennzeichen, an dem zu splitten ist. */ @SuppressWarnings("unchecked") public static Vector splitV(final String m, final String delim) { String mi = m; if (mi.equals("")) { return null; } Vector v = new Vector(30, 30); int i = 0, j = 0; while (true) { j = mi.indexOf(delim, i); if (j == -1) { v.add(mi.substring(i)); break; } String l = mi.substring(i, j).trim(); if (!l.equals("")) { v.add(l); } i = j + 1; } return v; } /** * Split a String into an ArrayList * * @param m * the String to msplit * @param delim * the delimiter to split at * @return an ArrayList containing at least one element without the delimiter */ @SuppressWarnings("unchecked") public static List<String> splitAL(final String m, final String delim) { ArrayList al = new ArrayList(); String mi = m; int i = 0, j = 0; while (true) { j = mi.indexOf(delim, i); if (j == -1) { al.add(mi.substring(i)); break; } String l = mi.substring(i, j).trim(); if (!l.equals("")) { al.add(l); } i = j + 1; } return al; } public static final String flattenSeparator = "~#<"; /** * Wandelt eine Hashtable in einen String aus Kommagetrennten a=b-Paaren um. */ @SuppressWarnings("unchecked") public static String flattenStrings(final Hashtable h) { return flattenStrings(h, null); } public static String flattenStrings(final Hashtable<Object, Object> h, final flattenFilter fil) { if (h == null) { return null; } Enumeration<Object> keys = h.keys(); StringBuffer res = new StringBuffer(1000); res.append("FS1").append(flattenSeparator); while (keys.hasMoreElements()) { Object ko = (keys.nextElement()); if (fil != null) { if (fil.accept(ko) == false) { continue; } } String v = ObjectToString(h.get(ko)); String k = ObjectToString(ko); if ((k == null) || (v == null) || k.matches(".*=.*")) { // log.log("attempt // to // flatten // unsupported // object // type",Log.FATALS); return null; } res.append(k).append("=").append(v).append(flattenSeparator); } String r = res.toString(); return r.replaceFirst(flattenSeparator + "$", ""); } public static final int NONE = 0; public static final int HUFF = 1; public static final int BZIP = 2; public static final int GLZ = 3; public static final int ZIP = 4; public static final int GUESS = 99; /** * Eine String-Collection comprimieren * * @param strings * @param compressMode * @return ein byte array mit dem komprimierten Inhalt der String-Collection */ public static byte[] pack(final Collection<String> strings) { String res = join(strings, "\n"); return CompEx.Compress(res, CompEx.ZIP); } /** * compress an array of single-lined Strings into a byte array * * @param strings * an array of String that must not contain newline (\n) characters * @return a byte array with the ZIP-compressed contents of the String array */ public static byte[] pack(final String[] strings) { String res = join(strings, "\n"); return CompEx.Compress(res, CompEx.ZIP); } /** * Unpack a Zip-compressed byte-Array in a List of Strings. * * @param pack * a packed byte array as created by pack() * @return an ArrayList of Strings * @see pack(String[]) * @see pack(Collection<String>) */ public static List<String> unpack(final byte[] pack) { try { String raw = new String(CompEx.expand(pack), default_charset); return splitAL(raw, "\n"); } catch (Exception ex) { return null; // Sollte sowieso nie vorkommen } } /** * Eine Hashtable in ein komprimiertes Byte-Array umwandeln * * @param hash * die Hashtable * @param compressMode * GLZ, HUFF, BZIP2 * @param ExtInfo * Je nach Kompressmode ntige zusatzinfo * @return das byte-Array mit der komprimierten Hashtable * @deprecated compressmode is always ZIP now. */ @SuppressWarnings("unchecked") @Deprecated public static byte[] flatten(final Hashtable hash, final int compressMode, final Object ExtInfo) { ByteArrayOutputStream baos = null; OutputStream os = null; ObjectOutputStream oos = null; try { baos = new ByteArrayOutputStream(hash.size() * 30); switch (compressMode) { case GUESS: case ZIP: os = new ZipOutputStream(baos); ((ZipOutputStream) os).putNextEntry(new ZipEntry("hash")); break; case BZIP: os = new CBZip2OutputStream(baos); break; case HUFF: os = new HuffmanOutputStream(baos, (HuffmanTree) ExtInfo, 0); break; case GLZ: os = new GLZOutputStream(baos, hash.size() * 30); break; default: os = baos; } oos = new ObjectOutputStream(os); oos.writeObject(hash); if (os != null) { os.close(); } baos.close(); return baos.toByteArray(); } catch (Exception ex) { ExHandler.handle(ex); return null; } } /** * Ein mit flatten() erzeugtes Byte-Array wieder in eine HAshtable zurckverwandeln * * @param flat * Die komprimierte Hashtable * @param compressMode * Expnad-Modus * @param ExtInfo * @return die Hastbale */ @SuppressWarnings("unchecked") @Deprecated public static Hashtable fold(final byte[] flat, final int compressMode, final Object ExtInfo) { ObjectInputStream ois = null; try { ByteArrayInputStream bais = new ByteArrayInputStream(flat); switch (compressMode) { case BZIP: ois = new ObjectInputStream(new CBZip2InputStream(bais)); break; case HUFF: ois = new ObjectInputStream(new HuffmanInputStream(bais)); break; case GLZ: ois = new ObjectInputStream(new GLZInputStream(bais)); break; case ZIP: ZipInputStream zis = new ZipInputStream(bais); zis.getNextEntry(); ois = new ObjectInputStream(zis); break; case GUESS: Hashtable<Object, Object> res = fold(flat, ZIP, null); if (res == null) { res = fold(flat, GLZ, null); if (res == null) { res = fold(flat, BZIP, null); if (res == null) { res = fold(flat, HUFF, ExtInfo); if (res == null) { return null; } } } } return res; default: ois = new ObjectInputStream(bais); break; } Hashtable<Object, Object> res = (Hashtable<Object, Object>) ois.readObject(); ois.close(); bais.close(); return res; } catch (Exception ex) { // ExHandler.handle(ex); deliberately don't mind return null; } } static private String ObjectToString(final Object o) { if (o instanceof String) { return "A" + (String) o; } if (o instanceof Integer) { return "B" + ((Integer) o).toString(); } if (o instanceof Serializable) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos; try { oos = new ObjectOutputStream(baos); oos.writeObject(o); oos.close(); byte[] ret = baos.toByteArray(); return "Z" + enPrintable(ret); } catch (IOException e) { ExHandler.handle(e); return null; } } return null; } static private Object StringToObject(final String s) { String sx = s.substring(1); char pref = s.charAt(0); switch (pref) { case 'A': return sx; case 'B': return (new Integer(Integer.parseInt(sx))); case 'Z': byte[] b = dePrintable(sx); try { ByteArrayInputStream bais = new ByteArrayInputStream(b); ObjectInputStream ois = new ObjectInputStream(bais); Object ret = ois.readObject(); ois.close(); bais.close(); return ret; } catch (Exception ex) { ExHandler.handle(ex); return null; } } return null; } @SuppressWarnings("unchecked") public static Hashtable foldStrings(final String s) { Hashtable h = new Hashtable(); if (StringTool.isNothing(s)) { return h; } String[] elems = s.split(flattenSeparator); if (!elems[0].equals("FS1")) { return null; } for (int i = 1; i < elems.length; i++) { String[] elem = elems[i].split("=", 2); if (elem.length != 2) { // log.log("Fehler in // Hash-Reprsentation",Log.ERRORS); return null; } Object k = StringToObject(elem[0].trim()); Object v = StringToObject(elem[1].trim()); if ((k == null) || (v == null)) { return null; } h.put(k, v); } return h; } /** gibt true zurck, wenn das Objekt kein String oder null oder "" ist */ static public boolean isNothing(final Object n) { if (n == null) { return true; } if (n instanceof String) { // if(((String)n).equals("")) return true; if (((String) n).trim().equals("")) { return true; } return false; } return true; } /** * Gibt true zurck, wenn das Feld null ist, leer ist, oder nur Leerstrings enthlt */ static public boolean isEmpty(final String[] f) { if (f == null) { return true; } for (int i = 0; i < f.length; i++) { if (!isNothing(f[i])) { return false; } } return true; } /** Verleicht zwei byte-Arrays */ static public boolean compare(final byte[] a, final byte[] b) { if (a.length == b.length) { for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } return false; } /** * Sucht einen String in einem String-Array und gibt dessen Index zurck. Die Suche erfolgt ohne * Bercksichtigung von Gross/Kleinschreibung. * * @return den index von val in arr oder -1 wenn nicht gefunden. */ static public int getIndex(final String[] arr, final String val) { for (int i = 0; i < arr.length; i++) { if (val.equalsIgnoreCase(arr[i])) { return i; } } return -1; } /** * Verlngert oder krzt einen String. * * @param where * LEFT vorne fllen, RIGHT hinten fllen * @param chr * Zeichen zum Fllen * @param src * Quellstring * @param size * erwnschte Lnge * @return der neue String */ static public String pad(final int where, final char chr, final String src, final int size) { int diff = size - src.length(); if (diff > 0) { StringBuffer s = new StringBuffer(diff); for (int i = 0; i < diff; i++) { s.append(chr); } if (where == LEFT) { return s + src; } return src + s; } return src.substring(0, size); } /** * Erstellt einen String aus mehreren nacheinander folgenden Strings * * @param str * der zu multiplizierende string * @param num * Zahl der Multiplikationen */ static public String filler(final String str, int num) { StringBuilder s = new StringBuilder(num); while (num-- > 0) { s.append(str); } return s.toString(); } public static String RectangleToString(int x, int y, int w, int h) { StringBuilder sb = new StringBuilder(); sb.append(x).append(",").append(y).append(",").append(w).append(",").append(h); return sb.toString(); } /** * Verknpft die Elemente eines String-Arrays mittels tren zu einem String * * @param arr * - String Array * @param tren * - Verbindingsstring * @return den verknpften String */ static public String join(final String[] arr, final String tren) { if ((arr == null) || (arr.length == 0)) { return ""; } StringBuffer res = new StringBuffer(100); for (int i = 0; i < arr.length; i++) { if (arr[i] == null) { continue; } res.append(arr[i]).append(tren); } String r2 = res.toString(); return r2.replaceFirst(tren + "$", ""); } public static String join(final Iterable<String> i, final String tren) { StringBuilder ret = new StringBuilder(); Iterator<String> it = i.iterator(); while (it.hasNext()) { ret.append(it.next()); if (it.hasNext()) { ret.append(tren); } } return ret.toString(); } /** * Wandelt ein Byte-Array in einen druckbaren String um. (Alle Bytes werden in ihre Nibbles * zerlegt, diese werden hnlich wie mit base64 als Zeichen gespeichert */ public static String enPrintable(final byte[] src) { return enPrintable(src, 70); // compatibility } static public String enPrintable(final byte[] src, final int offset) { byte[] out = new byte[src.length * 2]; for (int i = 0; i < src.length; i++) { out[2 * i] = (byte) ((src[i] >> 4) + offset); out[2 * i + 1] = (byte) ((src[i] & 0x0f) + offset); } try { return new String(out, default_charset); } catch (Exception ex) { ExHandler.handle(ex); return null; } } /** * Wandelt einen mit enPrintable erhaltenen String in ein byte-Array zurck. */ public static byte[] dePrintable(final String src) { return dePrintable(src, 70); // compatibility } static public byte[] dePrintable(final String src, final int offset) { byte[] input = null; try { input = src.getBytes(default_charset); } catch (Exception ex) { ExHandler.handle(ex); return null; } byte[] out = new byte[input.length / 2]; for (int i = 0; i < out.length; i++) { out[i] = (byte) ((input[2 * i] - offset) * 16 + (input[2 * i + 1] - offset)); } return out; } /** * Convert a byte array into a String that consists strictly only of numbers and capital * Letters. This can be useful for transmission over 7-Bit-Channels (In fact, 4 bit channels * would suffice) or Web Forms that would need URLConversion otherwise. * * @param src * the source array * @return a String that is 2 times the length of src + 3 Bytes and consists only of [0-9A-P]* */ public static String enPrintableStrict(byte[] src) { if (src == null) { return null; } byte[] out = new byte[(src.length << 1) + 3]; try { out[0] = 'E'; // header out[1] = 'P'; out[2] = '1'; // Version for (int i = 0; i < src.length; i++) { int i1 = (src[i] & 0xff) >> 4; byte o1 = (byte) (i1 + 65); byte o2 = (byte) ((src[i] & 0x0f) + 65); out[2 * i + 3] = o1; out[2 * i + 4] = o2; } return new String(out, default_charset); } catch (Exception ex) { ExHandler.handle(ex); return null; } } /** * Convert a String that was created with enPrintableStrict() back into a byte array * * @param src * a String previously created by enPrintableStrict * @return a byte array with the original data or null on errors */ public static byte[] dePrintableStrict(String src) { byte[] input = null; try { input = src.getBytes(default_charset); if ((input[0] != 'E') || (input[1] != 'P')) { return null; } } catch (Exception ex) { ExHandler.handle(ex); return null; } byte[] out = new byte[(input.length - 3) >> 1]; for (int i = 0; i < out.length; i++) { int o1 = input[2 * i + 3] - 65; int o2 = input[2 * i + 4] - 65; out[i] = (byte) ((o1 << 4) + o2); } return out; } /** * Gibt eine zufllige und eindeutige Zeichenfolge zurck * * @param salt * Ein beliebiger String oder null */ public static String unique(final String salt) { if (ipHash == 0) { Iterator<String> it = NetTool.IPs.iterator(); while (it.hasNext()) { ipHash += (it.next()).hashCode(); } } long t = System.currentTimeMillis(); int t1 = System.getProperty("user.name").hashCode(); long t2 = ((long) ipHash) << 32; long t3 = Math.round(Math.random() * Long.MAX_VALUE); long t4 = t + t1 + t2 + t3; if (salt != null) { long t0 = salt.hashCode(); t4 ^= t0; } t4 += sequence++; if (sequence > 99999) { sequence = 0; } long idx = sequence % salties.length; char start = salties[(int) idx]; return new StringBuilder().append(start).append(Long.toHexString(t4)) .append(Long.toHexString((long) Math.random() * 1000)).append(sequence).toString(); } /** * make sure a String is never null * * @param in * a String or null * @return "" if in was null, in otherwise */ public static String unNull(final String in) { return (in == null) ? "" : in; } /** * Dem StreamTokenizer nachempfundene Klasse, die auf einem String arbeitet. Kann gequotete und * geklammerte ausdrcke als token zusammenfassen. Wirft exceptions bei unmatched quotes oder * klammern. * * @author Gerry Weirich * */ static public class tokenizer { /** Betrachte in " eingeschlossene Phrasen als ein token */ public static final int DOUBLE_QUOTED_TOKENS = 1; /** Betrachte in ' eingeschlossene Phrasen als ein token */ public static final int SINGLE_QUOTED_TOKENS = 2; /** * In () geklammerte phrasen als ein token betrachten. Verschachtelte Klammern werden * unverndert bernommen */ public static final int ROUND_BRACKET_TOKENS = 4; /** In [] geklammerte Phrasen als ein token betrachten */ public static final int EDGE_BRACKET_TOKENS = 8; /** in {} geklammerte Phrasen als ein token betrachten */ public static final int CURLY_BRACKET_TOKENS = 16; /** Zeilenende bricht token ab */ public static final int CRLF_MATTERS = 32; private final String delim; private final int mode; private int pos; private final String mine; /** * Einziger Konstruktor * * @param m * der Quellstring * @param delim * Zeichen, die als Tokengrenze betrachtet werden * @param mode * OR-Kombination der obigen Token-Konstanten */ public tokenizer(final String m, final String delim, final int mode) { mine = m; this.delim = delim; this.mode = mode; pos = 0; } /** Splittet den String auf und liefert die tokens als List */ @SuppressWarnings("unchecked") public List<String> tokenize() throws IOException { ArrayList ret = new ArrayList(); StringBuffer token = new StringBuffer(); while (pos < mine.length()) { char c = mine.charAt(pos++); if (delim.indexOf(c) != -1) { ret.add(token.toString()); token.setLength(0); continue; } token.append(c); switch (c) { case '\"': if ((mode & DOUBLE_QUOTED_TOKENS) != 0) { token.append(readToMatching('\"', '\"')); } break; case '\'': if ((mode & SINGLE_QUOTED_TOKENS) != 0) { token.append(readToMatching('\'', '\'')); } break; case '(': if ((mode & ROUND_BRACKET_TOKENS) != 0) { token.append(readToMatching('(', ')')); } break; case ')': if ((mode & ROUND_BRACKET_TOKENS) != 0) { throw new IOException("unmatched bracket"); } break; case '[': if ((mode & EDGE_BRACKET_TOKENS) != 0) { token.append(readToMatching('[', ']')); } break; case ']': if ((mode & EDGE_BRACKET_TOKENS) != 0) { throw new IOException("unmatched bracket"); } break; case '{': if ((mode & CURLY_BRACKET_TOKENS) != 0) { token.append(readToMatching('{', '}')); } break; case '}': if ((mode & CURLY_BRACKET_TOKENS) != 0) { throw new IOException("unmatched bracket"); } } } ret.add(token.toString()); return ret; } private StringBuffer readToMatching(final char open, final char close) throws IOException { StringBuffer ret = new StringBuffer(); int level = 1; while (pos < mine.length()) { char c = mine.charAt(pos++); ret.append(c); if (c == close) { if (--level == 0) { return ret; } } else if (c == open) { level++; } else if (c == '\r') { if ((mode & CRLF_MATTERS) != 0) { throw new IOException("Unexpected end of line while looking for " + close); } } } throw new IOException("Unexpected end of line while looking for " + close); } } public interface flattenFilter { boolean accept(Object key); } /** * Versucht herauszufinden, ob ein Name weiblich ist * * @param name * der Name * @return true wenn der Name vielleicht weiblich ist */ public static boolean isFemale(final String name) { if (isNothing(name)) { return false; } final String[] suffices = { "a", "is", "e", "id", "ah", "eh", "th" }; for (String s : suffices) { if (name.endsWith(s)) { return true; } } return false; } public static boolean isMailAddress(final String in) { if (StringTool.isNothing(in)) { return false; } // up to 7 characters in device for james@bond.invalid return in.matches("\\w[\\w|\\.\\-]+@\\w[\\w\\.\\-]+\\.[a-zA-Z]{2,7}"); // oder \w[\w|\.\-]+@\w[\w\.\-]+\.[a-zA-Z]{2,4} } /** * Test whether a String is an IPV4 or IPV6-Address * * @param in * a String that is possibly an ipv4 or ipv6-Address * @return true if ir seems to be an IP-Address */ public static boolean isIPAddress(final String in) { if (in.matches(ipv4address)) { return true; } if (in.matches(ipv6address)) { return true; } return false; } /** * Return the first word of the given String */ public static String getFirstWord(final String in) { if (isNothing(in)) { return ""; } String[] words = in.split(wordSeparators); return words[0]; } /** * Return the first line if the given String but at most maxChars */ public static String getFirstLine(final String in, final int maxChars) { if (isNothing(in)) { return ""; } String[] lines = in.split(lineSeparators); if (lines[0].length() > maxChars) { int ix = lines[0].lastIndexOf(' ', maxChars); return lines[0].substring(0, ix); } return lines[0]; } /** * Gibt das Wort des Inhalts zurck das an oder unmittelbar vor der angegebenen Position ist * * @return Das mit an dieser Stelle befindliche Wort des Strings, <code>String.empty</code> * falls kein Wort dort ist idt oder der Index ausserhalb des Textbereichs ist */ public static String getWordAtIndex(String text, int index) { char c; if (index < 0 || text == null || index > text.length()) { return ""; } int start; int end; for (start = index - 1; start >= 0; start--) { c = text.charAt(start); if (wordSeparatorChars.indexOf(c) != -1) { start++; break; } } if (start < 0) { start = 0; } for (end = index; end < text.length(); end++) { c = text.charAt(end); if (wordSeparatorChars.indexOf(c) != -1) { break; } } if (end > text.length()) { end = text.length() + 1; } return text.substring(start, end); } @SuppressWarnings("unchecked") public static void dumpHashtable(final Log log, final Hashtable table) { Set<String> keys = table.keySet(); log.log("Dump Hashtable\n", Log.INFOS); for (String key : keys) { log.log(key + ": " + table.get(key).toString(), Log.INFOS); } log.log("End dump\n", Log.INFOS); } /** * Change first lettere to uppercase, other letters to lowercase * * @param orig * the word to change (at least 2 characters) * @return the normalized word. Tis will return orig if orig is less than 2 characters */ public static String normalizeCase(final String orig) { if (orig == null) { return ""; } if (orig.length() < 2) { return orig; } return orig.substring(0, 1).toUpperCase() + orig.substring(1).toLowerCase(); } /** * Convert first Character to uppercase. leave rest unchanged * * @param orig * the original String * @return the original String with first Character uppercase */ public static String capitalize(final String orig) { if (orig == null) { return ""; } if (orig.length() < 2) { return orig; } return orig.substring(0, 1).toUpperCase() + orig.substring(1); } /** * Zwei Strings verleichen. Bercksichtigen, dass einer oder beide auch Null sein knnten. * * @param a * erster String * @param b * zweiter String * @return -1,0 oder 1 */ public static int compareWithNull(String a, String b) { if (a == null) { if (b == null) { return 0; } else { return -1; } } else if (b == null) { return 1; } else { return a.compareTo(b); } } /** * String wenn ntig krzen * * @param orig * Originalstring * @param len * maximal zulssige Lenge * @return den String, der maximal len Zeichen lang ist */ public static String limitLength(final String orig, final int len) { if (orig == null) { return ""; } if (orig.length() > len) { return orig.substring(0, len); } return orig; } /** * String aus einem Array holen. Leerstring, wenn der angeforderte Index ausserhalb des Arrays * liegt * * @param array * @param index * @return */ public static String getSafe(final String[] array, final int index) { if ((index > -1) && (array.length > index)) { return array[index]; } return ""; } /** * Parse a String but don't throw expetion if not parsable. Return 0 instead * * @param string * @return */ public static int parseSafeInt(String string) { if (string == null) { return 0; } try { return Integer.parseInt(string.trim()); } catch (NumberFormatException ne) { return 0; } } /** * Parse a Double from a string but don't throw an Exception if not parseable. Return 0.0 * instead. * * @param string * a String containing probably a Double * @return always a double. 0.0 if the origin was 0.0 or null or not a Double */ public static double parseSafeDouble(String string) { if (string == null) { return 0.0; } try { return Double.parseDouble(string.trim()); } catch (NumberFormatException ne) { return 0.0; } } /** * String mit unterschiedlicher mglicher Schreibweise in einheitliche Schreibweise bringen * * @param in * ein String * @return derselbe String, aber alle mglicherweise kritische Zeichen durch _ ersetzt. */ public static String unambiguify(final String in) { String ret = in.toLowerCase(); ret = ret.replaceAll("([^a-z]|ue|oe|ae)", "_"); ret = ret.replaceAll("__+", "_"); return ret; } /** * convert a String from a source encoding to this platform's default encoding * * @param src * the source string * @param srcEncoding * the name of the encoding of the source * @return the transcoded String or the source String if the encoding is not supported */ public static String convertEncoding(String src, String srcEncoding) { try { byte[] bytes = src.getBytes(); return new String(bytes, srcEncoding); } catch (UnsupportedEncodingException e) { return src; } } /** * convert a String Array from a source encoding to this platform's default encoding * * @param src * the source Array * @param srcEncoding * the name of the encoding of the source * @return the transcoded Array or the source Array if the encoding is not supported */ public static String[] convertEncoding(String[] src, String srcEncoding) { String[] ret = new String[src.length]; for (int i = 0; i < src.length; i++) { ret[i] = convertEncoding(src[i], srcEncoding); } return ret; } /** * Eine beliebige Ziffernfolge mit der Modulo-10 Prfsumme verpacken * * @param number * darf nur aus Ziffern bestehen * @return die Eingabefolge, ergnzt um ihre Prfziffer */ public static String addModulo10(final String number) { int row = 0; String nr = number.replaceAll("[^0-9]", ""); for (int i = 0; i < nr.length(); i++) { int col = Integer.parseInt(nr.substring(i, i + 1)); row = mod10Checksum[row][col]; } return number + Integer.toString(mod10Checksum[row][10]); } /** * Die Modulo-10-Prfsumme wieder entfernen * * @param number * eine um eine prfziffer ergnzte Zahl * @return die Zahl ohne prfziffer oder null, wenn die Prfziffer falsch war. */ public static String checkModulo10(final String number) { String check = number.substring(0, number.length() - 1); String should = addModulo10(check); if (should.equals(number)) { return check; } return null; } /** Array fr den modulo-10-Prfsummencode */ private static final int[][] mod10Checksum = { { 0, 9, 4, 6, 8, 2, 7, 1, 3, 5, 0 }, { 9, 4, 6, 8, 2, 7, 1, 3, 5, 0, 9 }, { 4, 6, 8, 2, 7, 1, 3, 5, 0, 9, 8 }, { 6, 8, 2, 7, 1, 3, 5, 0, 9, 4, 7 }, { 8, 2, 7, 1, 3, 5, 0, 9, 4, 6, 6 }, { 2, 7, 1, 3, 5, 0, 9, 4, 6, 8, 5 }, { 7, 1, 3, 5, 0, 9, 4, 6, 8, 2, 4 }, { 1, 3, 5, 0, 9, 4, 6, 8, 2, 7, 3 }, { 3, 5, 0, 9, 4, 6, 8, 2, 7, 1, 2 }, { 5, 0, 9, 4, 6, 8, 2, 7, 1, 3, 1 } }; private static final char[] salties = { 'q', 'w', 'e', 'r', 't', 'z', 'u', 'o', 'i', 'p', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'y', 'x', 'c', 'v', 'b', 'n', 'm', 'Q', 'A', 'Y', 'W', 'E', 'D', 'C', 'R', 'F', 'V', 'T', 'G', 'B', 'Z', 'H', 'N', 'U', 'J', 'M', 'I', 'K', 'O', 'L', 'P' }; }