PK €Q5²îMETA-INF/MANIFEST.MFManifest-Version: 1.0 PK  ­ž4\]@y¾¾!com/myjavatools/lib/AllTests.javapackage com.myjavatools.lib; import junit.framework.*; public class AllTests extends TestCase { public AllTests(String s) { super(s); } public static Test suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(com.myjavatools.lib.foundation.TestCompoundCollection.class); suite.addTestSuite(com.myjavatools.lib.foundation.TestFilter.class); suite.addTestSuite(com.myjavatools.lib.foundation.TestFunction.class); suite.addTestSuite(com.myjavatools.lib.foundation.TestIterators.class); suite.addTestSuite(com.myjavatools.lib.foundation.TestMaps.class); suite.addTestSuite(com.myjavatools.lib.foundation.TestPair.class); suite.addTestSuite(com.myjavatools.lib.foundation.TestRestrictedFunctionEntrySet.class); suite.addTestSuite(com.myjavatools.lib.foundation.TestRestrictedMapEntrySet.class); suite.addTestSuite(com.myjavatools.lib.TestObjects.class); suite.addTestSuite(com.myjavatools.lib.TestStrings.class); suite.addTestSuite(com.myjavatools.lib.TestFiles.class); suite.addTestSuite(com.myjavatools.lib.TestWeb.class); suite.addTestSuite(com.myjavatools.lib.TestTools.class); return suite; } } PK 8vø01n)§ § com/myjavatools/lib/Bytes.java/** *

Title: MyJavaTools: Bytes Handling

*

Description: Several methods to handle data as bytes * * Good for Java 5.0 and up.

*

Copyright: This is public domain; * The right of people to use, distribute, copy or improve the contents of the * following may not be restricted.

* * @version 5.0 * @author Vlad Patryshev */ package com.myjavatools.lib; import java.util.zip.CRC32; public abstract class Bytes { /** * Converts char array to byte array (per-element casting) * * @param from char array * @return byte array * *

Example: *
  • toBytes(new char[] {0x0123, 0x4567, 0x89ab, 0xcdef}) * returns {0x23, 0x67, (byte)0xab, (byte)0xef}.
  • */ public static final byte[] toBytes(char[] from) { byte[] result = new byte[from.length]; for (int i = 0; i < from.length; i++) { result[i] = (byte)from[i]; } return result; } /** * Converts byte array to char array (per-element casting) * @param from byte array * @return char array * *

    Example: *
  • toChars(new byte[] {0x23, 0x67, (byte)0xab, (byte)0xef}) * returns new char[] {0x23, 0x67, 0xab, 0xef}.
  • */ public static final char[] toChars(byte[] from) { char[] result = new char[from.length]; for (int i = 0; i < from.length; i++) { result[i] = (char)(0xff & from[i]); } return result; } /** * Calculates crc32 on a byte array * * @param data source bytes * @return its crc32 * *

    Example: *
  • crc32(new byte[] {1, 2, 3}) * returns 1438416925.
  • */ public static final long crc32(byte[] data) { CRC32 crc32 = new CRC32(); crc32.update(data); return crc32.getValue(); } /** * Calculates crc32 on a byte array * * @param data source bytes * @param off offset in the array * @param len length of the area to crc * @return its crc32 * *

    Example: *
  • crc32(new byte[] {0, 1, 2, 3, 4}, 1, 3) * returns 1438416925.
  • */ public static final long crc32(byte[] data, int off, int len) { CRC32 crc32 = new CRC32(); crc32.update(data, off, len); return crc32.getValue(); } /** * Converts long to byte array (lower bytes first) * * @param from the long value * @return byte array * *

    Example: *
  • toBytes(0x0123456789abcdefl) * returns {(byte)0xef, (byte)0xcd, (byte)0xab, (byte)0x89, 0x67, 0x45, 0x23, 0x01}.
  • */ public static final byte[] toBytes(long from) { java.lang.Long l; byte[] result = new byte[8]; for (int i = 0; i < 8; i++) { result[i] = (byte)from; from >>= 8; } return result; } } // 07/23/2004 - TestBytes tests cr32(2), toBytes(2), toChars. PK ð¨r2˜_ñ¯ÀãÀãcom/myjavatools/lib/Files.java/* *

    Title: My Java Tools Library

    * *

    Description: This is a mixture of useful Java Tools

    * * @(#)Files.java 5.0 02/08/05 * *

    Copyright: This is public domain; The right of people to use, distribute, * copy or improve the contents of the following may not be restricted.

    */ package com.myjavatools.lib; import java.io.*; import java.util.*; import java.util.regex.*; import java.util.zip.*; import static com.myjavatools.lib.Bytes.*; import static com.myjavatools.lib.foundation.Iterators.*; import static com.myjavatools.lib.foundation.Objects.*; import static com.myjavatools.lib.Strings.*; import java.nio.channels.FileChannel; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.channels.Channels; import java.nio.MappedByteBuffer; import java.net.URL; /** * Files is a utility class that contains static methods for handling files and directories * * @version 5.0, 02/08/05 * @since 5.0 */ public abstract class Files { private static final boolean DEBUG = true; private static final char altSeparatorChar = File.separatorChar == '/' ? '\\' : '/'; /** * Calculates full path of a file * @param file * @return full path */ public static final String getFullPath(File file) { try { return file.getCanonicalPath(); } catch (IOException ex) { } return file.getAbsolutePath(); } /** * Calculates full path of a file by its path * @param path * @return full path */ public static final String getFullPath(String path) { return getFullPath(new File(path)); } /** * Calculates relative path * * @param dir directory path that is expected to start the file path * @param path file path, relativer or not * @return if path starts with dir, then the rest of the path, else path * *

    Examples: *
  • relPath("c:\\MyHome\\dev", "c:\\MyHome\\dev\\src\\java") returns "src\\java";
  • *
  • relPath("/home/zaphod", "/home/zaphod/jbuilder8/samples/welcome") returns "jbuilder8/samples/welcome";
  • *
  • relPath("/home/zaphod", "/home/ford/jbuilder8") returns "/home/ford/jbuilder8".
  • */ public static String relPath(String dir, String path) { String fullpath = getFullPath(path); String fulldir = getFullPath(dir); if (!fullpath.startsWith(fulldir + File.separatorChar)) { return path; } String result = fullpath.substring(fulldir.length() + 1); if (dir.indexOf(File.separatorChar) < 0 && path.indexOf(File.separatorChar) < 0 && (dir.indexOf(altSeparatorChar) >= 0 || path.indexOf(altSeparatorChar) >= 0)) { return result.replace(File.separatorChar, altSeparatorChar); } return result; } /** * Having a directory and file path (relative or absolute) calculates full path * * @param currentDir directory path * @param filepath file path, relative or not * @return full file path * *

    Examples: *
  • path("c:\\MyHome\\dev", "src\\java") returns "c:\\MyHome\\dev\\src\\java";
  • *
  • path("/root/inetd", "/home/zaphod/jbuilder8/samples/welcome") returns "/home/zaphod/jbuilder8/samples/welcome";
  • *
  • path("\\Program Files", "c:\\MyHome\\dev") returns "c:\\MyHome\\dev".
  • */ public static String path(String currentDir, String filepath) { return (filepath.charAt(0) == File.separatorChar || filepath.charAt(0) == altSeparatorChar || filepath.indexOf(':') > 0 || isEmpty(currentDir)) ? filepath : (currentDir + (currentDir.endsWith(File.separator) ? "" : File.separator) + filepath); } /** * Splits a path into directory name and file name * * @param path * @return String array consisting of two elements * *

    Examples: *
  • splitPath("/home/zaphod/jbuilder8/samples/welcome") returns {"/home/zaphod/jbuilder8/samples", "welcome"};
  • *
  • splitPath("src.java") returns {".", "src.java"};
  • *
  • splitPath("MyHome\\dev") returns {"MyHome", "dev"}.
  • */ public static String[] splitPath(String path) { return new String[] {dirname(path), new File(path).getName()}; } /** * Calculates directory path for a file (like in Perl) * * @param file * @return directory path * * Unlike java.io.File.getParent(), never returns null (see example 2 below). * *

    Examples: *
  • dirname(new File("/home/zaphod/jbuilder11/samples/welcome")) returns "/home/zaphod/jbuilder8/samples";
  • *
  • dirname(new File("src.java")) returns ".";
  • *
  • dirname(new File("MyHome\\dev")) returns "MyHome".
  • */ public static String dirname(File file) { String parent = file.getParent(); if (parent == null) parent = "."; if (file.getPath().indexOf(File.separatorChar) < 0 && file.getPath().indexOf(altSeparatorChar) >= 0 && parent.indexOf(File.separatorChar) >= 0) { parent = parent.replace(File.separatorChar, altSeparatorChar); } return parent; } /** * Calculates directory path by file path (like in Perl) * * @param path * @return directory path * * Unlike java.io.File.getParent(), never returns null (see example 2 below). * *

    Examples: *
  • dirname("/home/zaphod/jbuilder11/samples/welcome") returns "/home/zaphod/jbuilder8/samples";
  • *
  • dirname("src.java") returns ".";
  • *
  • dirname("MyHome\\dev") returns "MyHome".
  • */ public static String dirname(String path) { String dirname = dirname(new File(path)); if (path.indexOf(altSeparatorChar) >= 0 && path.indexOf(File.separatorChar) < 0) { return dirname.replace(File.separatorChar, altSeparatorChar); } return dirname; } /** * Calculates filename by file path (like in Perl) * * @param path * @return file name * *

    Example: *
  • filename("/home/zaphod/jbuilder11/samples/welcome") returns "welcome".
  • */ public static String filename(String path) { return new File(path).getName(); } /** * Lists recursively files and directories with name matching a regexp * * @param subdir where to look * @param pattern to match * @return List<String> of absolute filepaths * *

    Example: *
  • find(new File("."), Pattern.compile(".*les\\.java$"))) returns * Arrays.asList(new String[] {new File("Files.java").getCanonicalPath()}).
  • */ public static List find(File subdir, Pattern pattern) { List resultSet = new ArrayList(); File contents[] = subdir.listFiles(); for (File file : contents) { String path = getFullPath(file); if (file.isDirectory()) { resultSet.addAll(find(file, pattern)); } else if (pattern.matcher(path).find()) { resultSet.add(path); } else { path = path.replace(File.separatorChar, '/'); if (pattern.matcher(path).find()) { resultSet.add(path); } } } return resultSet; } /** * Lists recursively files and directories with name matching a regexp * * @param subdir where to look * @param pattern to match * @return List<String> of absolute filepaths * *

    Example: *
  • find(".", Pattern.compile(".*les\\.java$"))) returns * Arrays.asList(new String[] {"Files.java"}).
  • */ public static List find(String subdir, Pattern pattern) { return find(new File(subdir), pattern); } /** * Lists recursively files and directories with name matching a regexp * * @param subdir where to look * @param pattern to match * @return List<String> of absolute filepaths * *

    Example: *
  • find(".", ".*les\\.java$") returns * Arrays.asList(new String[] {"Files.java"}).
  • */ public static List find(String subdir, String pattern) { try { return find(subdir, Pattern.compile(pattern, Pattern.CASE_INSENSITIVE)); } catch (Exception e) { return new ArrayList(); } } public final static int FIND_FILE = 1; public final static int FIND_DIRECTORY = 2; public final static int FIND_ALL = 3; /** * Finds latest file or directory or one of these which name matches a pattern * * @param subdir where to look * @param pattern to match * @param whatExactly can be FIND_FILE or FIND_DIRECTORY or FIND_ALL * @return the path found */ public static String findLatest(String subdir, String pattern, int whatExactly) { String currentFile = null; long currentTime = 0; for (String path : find(subdir, pattern)) { File candidate = new File(path); boolean isGood = ((candidate.isDirectory() ? FIND_DIRECTORY : candidate.isFile() ? FIND_FILE : 0) & whatExactly) != 0; if (currentTime < candidate.lastModified() && isGood) { try { currentTime = candidate.lastModified(); currentFile = candidate.getCanonicalPath(); } catch (Exception e) {} } } return currentFile; } /** * Finds latest file or directory which name matches a pattern * * @param subdir where to look * @param pattern to match * @return the path found */ public static String findLatest(String subdir, String pattern) { return findLatest(subdir, pattern, FIND_ALL); } /** * Finds latest file which name matches a pattern * * @param subdir where to look * @param pattern to match * @return the path found */ public static String findLatestFile(String subdir, String pattern) { return findLatest(subdir, pattern, FIND_FILE); } /** * Finds latest directory which name matches a pattern * * @param subdir where to look * @param pattern to match * @return the path found */ public static String findLatestDirectory(String subdir, String pattern) { return findLatest(subdir, pattern, FIND_DIRECTORY); } /** * directoryFilter is a FileFilter that accepts directories only */ static public FileFilter DIRECTORY_FILTER = new FileFilter() { public boolean accept(File file) { return file.isDirectory(); } }; /** * fileFilter is a FileFilter that accepts files only */ static public FileFilter fileFilter = new FileFilter() { public boolean accept(File file) { return file.isFile(); } }; /** * Lists subdirectories of a directory * @param dir directory name * @return an array of subdirectores */ public static final File[] listSubdirectories(File dir) { return dir.isDirectory() ? dir.listFiles(DIRECTORY_FILTER) : null; } /** * Lists files in a directory * @param dir directory name * @return an array of files */ public static final File[] listFiles(File dir) { return dir.isDirectory() ? dir.listFiles(fileFilter) : null; } /** * Gets file modification date/time as a string * @param file * @return file modification time as a string * *

    Example: *
  • lastModified(new File("src/com/javatools/util/Objects.java")) returns * "something".
  • */ public static final String lastModified(File file) { return (new Date(file.lastModified())).toString(); } /** * Gets current directory path * * @return the current directory path */ public static String getcwd() { File here = new File("."); try { return here.getCanonicalPath(); } catch (Exception e) {}; return here.getAbsolutePath(); // return System.getProperty("user.dir"); } // /** // * Changes current directory // * // * @param dir to chdir // * @return previous current directory // */ // public static String chdir(String dir) { // String cwd = System.getProperty("user.dir"); // // if (dir != null) System.setProperty("user.dir", dir); // return cwd; // } /** * Deletes a file or a directory (with all its contents, they say it is dangerous) * @param filename * @return true if successful * *

    Bad Example: *
  • deleteFile("/etc") returns true if the program runs as root.
  • */ public static boolean deleteFile(String filename) { return deleteFile(new File(filename)); } /** * Deletes a file or a directory (with all its contents, they say it is dangerous) * @param file to delete * @return true if successful * */ public static boolean deleteFile(File file) { try { if (file.isDirectory()) { String fullpath = file.getCanonicalPath(); for (String filename : file.list()) { deleteFile(new File(fullpath, filename)); } } return !file.exists() || file.delete(); } catch (Exception e) {} return false; } /** * Creates or opens a file for output. * If subdirectories in the path do not exist, they are created too. * If the file exists, it is overwritten, unless append is true. * append determines whether to open in append mode * * @param dirname file location * @param filename the name of the file * @param append true if open in append mode * @return file output stream * @throws IOException */ public static FileOutputStream makeFile(String dirname, String filename, boolean append) throws IOException { if (isEmpty(dirname)) { return new FileOutputStream(new File(filename), append); } else { File dir = new File(dirname); if (!dir.isDirectory()) { if (dir.exists()) dir.delete(); dir.mkdirs(); } return new FileOutputStream(new File(dirname, filename), append); } } /** * Creates or opens a file for output. * If subdirectories in the path do not exist, they are created too. * If the file exists, it is overwritten. * * @param dir file location * @param filename the name of the file * @return file output stream * @throws IOException */ public static FileOutputStream makeFile(String dir, String filename) throws IOException { return makeFile(dir, filename, false); } /** * Creates or opens a file for output. * If subdirectories in the path do not exist, they are created too. * If the file exists, it is overwritten, unless append is true. * append determines whether to open in append mode * * @param path [0] is directory name, [1] is file name * @param append true if open in append mode * @return file output stream * @throws IOException */ public static FileOutputStream makeFile(String[] path, boolean append) throws IOException { return makeFile(path[0], path[1], append); } /** * Creates or opens a file for output. * If subdirectories in the path do not exist, they are created too. * If the file exists, it is overwritten. * * @param path String[] - a compound file path, ending with file name * @return file output stream * @throws IOException */ public static FileOutputStream makeFile(String... path) throws IOException { return path.length < 1 ? null : path.length < 2 ? makeFile(path[0]) : path.length < 3 ? makeFile(path[0], path[1]) : makeFile(join(File.separator, path)); } /** * Creates or opens a file for output. * If subdirectories in the path do not exist, they are created too. * If the file exists, it is overwritten, unless append is true. * append determines whether to open in append mode * * @param path file path * @param append true if open in append mode * @return file output stream * @throws IOException */ public static FileOutputStream makeFile(String path, boolean append) throws IOException { return makeFile(splitPath(path), append); } /** * Creates or opens a file for output. * If subdirectories in the path do not exist, they are created too. * If the file exists, it is overwritten. * * @param path file path * @return file output stream * @throws IOException */ public static FileOutputStream makeFile(String path) throws IOException { return makeFile(splitPath(path)); } /** * Creates or opens a file for output. * If subdirectories in the path do not exist, they are created too. * If the file exists, it is overwritten, unless append is true. * append determines whether to open in append mode * * @param file the file to open * @param append true if open in append mode * @return file output stream * @throws IOException */ public static FileOutputStream makeFile(File file, boolean append) throws IOException { return makeFile(file.getCanonicalPath(), append); } /** * Creates or opens a file for output. * If subdirectories in the path do not exist, they are created too. * If the file exists, it is overwritten. * * @param file the file to open * @return file output stream * @throws IOException */ public static FileOutputStream makeFile(File file) throws IOException { return makeFile(file.getCanonicalPath()); } /** * Creates or opens a file for output. * If subdirectories in the path do not exist, they are created too. * If the file exists, it is overwritten. * * @param path the file to open * @param encoding the encoding to use * @return output stream writer * @throws IOException */ public static final OutputStreamWriter makeFileWriter(String path, String encoding) throws IOException { return new OutputStreamWriter(makeFile(path), encoding); } /** * Adjusts buffer size according to Moore's law * @param size int original buffer size * @param thisYear int the year this specific size was chosen * @return int buffer size adjusted by Moore's law: "double it every three years" */ public static final int adjustSizeByMooreLaw(int size, int thisYear) { double milli = System.currentTimeMillis(); double aYear = (double)1000 * 60 * 60 * 24 * (365 * 4 + 1) / 4; double q = Math.exp((milli / aYear + 1970 - thisYear) / 3 * Math.log(2)); return (int)(size * q); } /** * Reads the whole reader contents into a string * * @param reader the reader to read * @return contents as a string, or null if error occurred * */ private final static int MAX_BUFFER_SIZE = Files.adjustSizeByMooreLaw(65536, 2004); public static final String readString(Reader reader) { try { StringBuffer buf = new StringBuffer(); char[] chars = new char[MAX_BUFFER_SIZE]; int l; while ((l = reader.read(chars)) > 0) { buf.append(chars, 0, l); } return buf.toString(); } catch (Exception e) { } return null; } /** * Reads the whole file into a string * * @param file the file to read * @return file contents as a string, or null if error occurred * *

    Example: *
  • readStringFromFile("../src/com/myjavatools/utils/Files.java") * returns a string starting with "/**\r\n * <p>Title: MyJavaTools: Files handling Tools</p>\r\n*".
  • */ public static final String readStringFromFile(File file) { try { return readString(new FileReader(file)); } catch (Exception e) { if (DEBUG) System.out.println(e); } return null; } /** * Reads the whole file into a string * * @param file the file to read * @param encoding the expected encoding * @return file contents as a string, or null if error occurred * */ public static final String readStringFromFile(File file, String encoding) { try { return readString(new InputStreamReader(new FileInputStream(file), encoding)); } catch (Exception e) { } return null; } /** * Reads the whole file into a string * * @param filename the file to read * @return file contents as a string, or null if error occurred * *

    Example: *
  • readStringFromFile("../src/com/myjavatools/utils/Files.java") * returns a string starting with "/**\r\n * <p>Title: MyJavaTools: Files handling Tools</p>\r\n*".
  • */ public static final String readStringFromFile(String filename) { return readStringFromFile(new File(filename)); } /** * Reads the whole input stream into a byte array * * @param is input stream to read * @return file contents as byte array, or null if error occurred * *

    Example: *
  • readBytesFromStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5})) * returns new byte[] {1, 2, 3, 4, 5}.
  • */ public static final byte[] readBytesFromStream(InputStream is) { try { ArrayList chunkList = new ArrayList(); int total = 0; int l; while ((l = is.available()) > 0) { byte[] chunk = new byte[l]; is.read(chunk); chunkList.add(chunk); total += l; } byte[] buffer = new byte[total]; int pos = 0; for (byte[] chunk : chunkList) { java.lang.System.arraycopy(chunk, 0, buffer, pos, chunk.length); } return buffer; } catch (Exception e) { } return null; } /** * Reads the whole input stream into a byte array * * @param filename file to read * @return file contents as byte array, or null if error occurred * *

    Example: *
  • readBytesFromFile("../src/com/myjavatools/utils/Files.java") * returns a byte array starting with {51, 50, 50, 13, 10, 32, 50}.
  • */ public static final byte[] readBytesFromFile(String filename) { try { File file = new File(filename); long fullsize = file.length(); if (fullsize > Integer.MAX_VALUE) { throw new IOException("File too large"); } FileChannel channel = new FileInputStream(file).getChannel(); MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); byte[] result = new byte[(int)fullsize]; buffer.get(result); return result; // return readBytesFromStream(); } catch (Exception e) { } return null; } /** * Creates a file and writes a char sequence into it * * @param data the char sequence to write to file * @param fileTo file path * @return file */ public static final File writeToFile(CharSequence data, String fileTo) { try { File file = new File(fileTo); OutputStreamWriter sw = new OutputStreamWriter(makeFile(file)); write(sw, data); sw.close(); return file; } catch (Exception e) { } return null; } /** * Creates a file and writes chars into it * * @param data array of characters to write to file * @param fileTo file path * @return file */ public static final File writeToFile(char[] data, String fileTo) { try { File file = new File(fileTo); OutputStreamWriter sw = new OutputStreamWriter(makeFile(file)); sw.write(data); sw.close(); return file; } catch (Exception e) { } return null; } /** * Creates a file and writes bytes into it * * @param data array of bytes to append to the end of file * @param fileTo file path * @return file */ public static final File writeToFile(byte[] data, String fileTo) { try { File file = new File(fileTo); OutputStream os = makeFile(file); os.write(data); os.close(); return file; } catch (Exception e) { } return null; } /** * Writes bytes to a file * * @see #writeToFile(byte[],String) * @return file */ public static final File writeBytesToFile(byte[] data, String fileTo) { return writeToFile(data, fileTo); } /** * Creates a file and copies into it bytes from an input stream * * @param is input stream * @param fileTo file path * @throws IOException * @return file */ public static final File writeToFile(InputStream is, String fileTo) throws IOException { File file = new File(fileTo); OutputStream os = makeFile(file); pipe(is, os, false); os.close(); return file; } /** * Appends a char sequence to the end of a file * * @param data char sequence to append to the end of file * @param fileTo file path * @return file */ public static final File appendToFile(CharSequence data, String fileTo) { try { File file = new File(fileTo); OutputStreamWriter sw = new OutputStreamWriter(makeFile(file, true)); write(sw, data); sw.close(); return file; } catch (Exception e) { } return null; } /** * Appends chars to the end of a file * * @param data array of characters to append to the end of file * @param fileTo file path * @return file */ public static final File appendToFile(char[] data, String fileTo) { try { File file = new File(fileTo); OutputStreamWriter sw = new OutputStreamWriter(makeFile(file, true)); sw.write(data); sw.close(); return file; } catch (Exception e) { } return null; } /** * Appends bytes to the end of a file * * @param data array of characters to append to the end of file * @param fileTo file path * @return file */ public static final File appendToFile(byte[] data, String fileTo) { try { File file = new File(fileTo); OutputStream os = makeFile(file, true); os.write(data); os.close(); return file; } catch (Exception e) { } return null; } /** * Appends bytes to the end of a file * * @param data chars to append are converted to bytes * @param fileTo * @return file */ public static final File appendBytesToFile(char[] data, String fileTo) { return appendBytesToFile(toBytes((char[])data), fileTo); } /** * Appends bytes to a file * @see #appendToFile(byte[],String) */ public static final File appendBytesToFile(byte[] data, String fileTo) { return appendToFile(data, fileTo); } /** * Calculates a java package name by directory name and base directory name * * @param basePath the base path for code source * @param currentPath the path of current directory * @return package name * *

    Examples: *
  • getPackageName("c:\\home\\myjavatools\\src", "c:\\home\\myjavatools\\src\\com\\myjavatools\\util") * returns "com.myjavatools.util".
  • *
  • getPackageName("c:\\home\\myjavatools\\src\\java", "c:\\home\\myjavatools\\src\\com\\myjavatools\\util") * returns null.
  • * */ public static final String getPackageName(String basePath, String currentPath) { String path = relPath(basePath, currentPath); return path == null ? null : path.equals(currentPath) ? null : path.replace(File.separatorChar, '.'); } /** *

    Description: The interface is used to define filters for * filtering data in pipes. Filters, similar to those in JSPs, can modify * the bytes going from one end of the pipe to another, or just sniff them * and act based on results - e.g. count bytes, calculate crc, you name it.

    */ public interface ByteFilter { /** * filters data coming from input * @param input byte[] input data * @param length int number of meaningful bytes * @return byte[] result of filtering */ byte[] filter(byte[] input, int length); } /** *

    Description: Buffering filter stores some data, and these data can be * retrieved later. * @see #ByteFilter */ public interface BufferingFilter extends ByteFilter { /** * gets data stored as a result of filtering; no assumption regarding the nature of the data. * @return byte[] */ byte[] getBuffer(); /** * clears the filter buffer */ void clear(); } /** * pipes data from input stream to output stream, possibly pumping them through * the filter (if any) * @param in InputStream the source of data * @param out OutputStream where the output goes, filtered if filter is present, or unfiltered otherwise * @param isBlocking boolean whether input is blocking (in this case the maximum amount is read in one operation; for nonblocking in.available() determines how many bytes can be read) * @param filter ByteFilter the filter that applies to data; can be null * @throws IOException when input or output fails * * see the test for examples */ public static void pipe(InputStream in, OutputStream out, boolean isBlocking, ByteFilter filter) throws IOException { byte[] buf = new byte[MAX_BUFFER_SIZE]; int nread; int navailable; int total = 0; synchronized (in) { while((navailable = isBlocking ? buf.length : in.available()) > 0 && (nread = in.read(buf, 0, Math.min(buf.length, navailable))) >= 0) { if (filter == null) { out.write(buf, 0, nread); } else { byte[] filtered = filter.filter(buf, nread); out.write(filtered); } total += nread; } } out.flush(); buf = null; } /** * pipes data from input stream to output stream * * @param in InputStream the source of data * @param out OutputStream where the output goes, filtered if filter is present, or unfiltered otherwise * @param isBlocking boolean whether input is blocking (in this case the maximum amount is read in one operation; for nonblocking in.available() determines how many bytes can be read) * @throws IOException when input or output fails * * see the test for examples */ public static void pipe(InputStream in, OutputStream out, boolean isBlocking) throws IOException { pipe(in, out, isBlocking, null); } /** * pipes data from input stream to output stream * * @param in Reader the source of data * @param out Writer where the output goes, filtered if filter is present, or unfiltered otherwise * @return boolean true if successful, false otherwise * * see the test for examples */ public static boolean pipe(Reader in, Writer out) { if (in == null) { return false; } if (out == null) { return false; } try { int c; synchronized (in) { while(in.ready() && (c = in.read()) > 0) { // have to have in.ready() here, otherwise it will hang! out.write(c); } } out.flush(); } catch(Exception e) { return false; } return true; } private static boolean COPY_DEBUG = false; /** * copies a file or a directory from one directory to another * @param from directory from where to copy * @param to directory where to copy * @param what what to copy (file or directory, recursively) * @return true if successful * *

    Example: *

  • copy("c:\\home\\vlad\\dev", "c:\\home\\vlad\\rtm", "contents.xml")
  • */ public static boolean copy(String from, String to, String what) { return copy(new File(from, what), new File(to, what)); } /** * copy copies a file or a directory from one directory to another * @param from directory from where to copy * @param to directory where to copy * @param what what to copy (file or directory, recursively) * @return true if successful * *

    Example: *
  • copy(new File(myHomeDir, "dev"), new File(myHomeDir, "rtm"), "contents.xml")
  • */ public static boolean copy(File from, File to, String what) { return copy(new File(from, what), new File(to, what)); } /** * copy copies a file or a directory to another * @param from * @param to * @return true if successful * *

    Example: *
  • copy("c:\\home\\vlad\\dev\\contents.xml", "c:\\home\\vlad\\rtm\\contents.rss")
  • */ public static boolean copy(String from, String to) { return copy(new File(from), new File(to)); } /** * copy copies a file or a directory to another * @param from * @param to * @return true if successful * *

    Example: *
  • copy(new File(myHomeDir, "contents.xml"), new File(mySite, "contents.rss")
  • */ public static boolean USE_NIO = true; public static boolean copy(File from, File to) { if (from.isDirectory()) { for (String name : Arrays.asList(from.list())) { if (!copy(from, to, name)){ if (COPY_DEBUG) System.out.println("Failed to copy " + name + " from " + from + " to " + to); return false; } } } else { try { FileInputStream is = new FileInputStream(from); FileChannel ifc = is.getChannel(); FileOutputStream os = makeFile(to); if (USE_NIO) { FileChannel ofc = os.getChannel(); ofc.transferFrom(ifc, 0, from.length()); } else { pipe(is, os, false); } is.close(); os.close(); } catch (IOException ex) { if (COPY_DEBUG) System.out.println("Failed to copy " + from + " to " + to + ": " + ex); return false; } } long time = from.lastModified(); setLastModified(to, time); long newtime = to.lastModified(); if (COPY_DEBUG) { if (newtime != time) { System.out.println("Failed to set timestamp for file " + to + ": tried " + new Date(time) + ", have " + new Date(newtime)); to.setLastModified(time); long morenewtime = to.lastModified(); return false; } else { System.out.println("Timestamp for " + to + " set successfully."); } } return time == newtime; } /** * Sets the last-modified time of the file or directory named by this * abstract pathname. * * The reason for this specific method is Java bug 4243868: * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4243868 * It does not always work without the trick... * * @see java.io.File#setLastModified * * @param file File * @param time long * * @return true if and only if the operation succeeded; * false otherwise * * @throws IllegalArgumentException If the argument is negative * * @throws SecurityException * If a security manager exists and its {@link * java.lang.SecurityManager#checkWrite(java.lang.String)} * method denies write access to the named file * * @since 5.0 */ public static boolean setLastModified(File file, long time) { if (file.setLastModified(time)) { return true; } System.gc(); return file.setLastModified(time); } private static final boolean EQUAL_DEBUG = DEBUG; /** * compares two files or directories, recursively * @param left File * @param right File * @return boolean */ public static boolean equal(File left, File right) { if (left.isDirectory() && right.isDirectory()) { Set leftSet = new HashSet(Arrays.asList(left.list())); Set rightSet = new HashSet(Arrays.asList(right.list())); if (leftSet.size() != rightSet.size()) { if (EQUAL_DEBUG) { System.out.println(left.getPath() + " has " + leftSet.size() + " while " + right.getPath() + " has " + rightSet.size()); } return false; } for (String name : leftSet) { if (rightSet.contains(name)) { if (!equal(new File(left, name), new File(right, name))) { if (EQUAL_DEBUG) { System.out.println(left.getPath() + File.separator + name + " is different from " + right.getPath() + File.separator + name); } return false; } } else { if (EQUAL_DEBUG) { System.out.println(right.getPath() + " does not contain " + name); } return false; } } return true; } else if (left.isFile() && right.isFile()) { try { return compare(left, right) == 0; } catch (IOException e) { if (EQUAL_DEBUG) { System.out.println(e.getMessage() + " while comparing " + left.getPath() + " and " + right.getPath()); } return false; } } else { return false; } } /** * Compare two files * @param left * @param right * @return -1 if left file is older or shorter or "smaller" than right * 0 if files are equal * 1 if right file is older or shorter or "smaller" than left * * *

    Example: *
  • copy(new File(myHomeDir, "contents.xml"), new File(mySite, "contents.rss");
    * compare(new File(myHomeDir, "contents.xml"), new File(mySite, "contents.rss")
    returns -1 *
  • */ public static int compare(File left, File right) throws IOException { long lm = left.lastModified() / 1000; long rm = right.lastModified() / 1000; if (lm < rm) return -1; if (lm > rm) return 1; long ll = left.length(); long rl = right.length(); if (ll < rl) return -1; if (ll > rl) return 1; InputStream is1 = new BufferedInputStream(new FileInputStream(left)); InputStream is2 = new BufferedInputStream(new FileInputStream(right)); for (long i = 0; i < ll; i++) { int b1 = is1.read(); int b2 = is2.read(); if (b1 < 0) return -1; if (b2 < 0) return 1; if (b1 != b2) return b1 < b2 ? -1 : 1; } return 0; } /** * synchronizes two directories, left/what and right/what * @param left File first directory that contains directory what * @param right File second directory that contains directory what * @param what String name of directory which contents is being synchronized * @return boolean true if success * *

    Example: *
  • synchronize(new File(myHomeDir), new File(mySite), "myjavatools.com") * will leave subdirectories named myjavatools.com in these two directories absolutely identical.
  • */ public static boolean synchronize(File left, File right, String what) { return synchronize(new File(left, what), new File(right, what)); } /** * synchronizes two directories * @param left File first directory * @param right File second directory * @return boolean true if success * *

    Example: *
  • synchronize(new File(myHomeDir), new File(myBackupDir)) * will leave the contents of directories myHomeDIr and myBackupDir absolutely identical.
  • */ public static boolean synchronize(File left, File right) { if (left.isDirectory() || right.isDirectory()) { String [] leftContents = left.list(); Set contents = leftContents == null ? new LinkedHashSet() : new LinkedHashSet(Arrays.asList(leftContents)); String[] rightContents = right.list(); if (rightContents != null) { contents.addAll(Arrays.asList(rightContents)); } for (String name : contents) { if (!synchronize(left, right, name)) return false; } } else { long leftTime = left.lastModified(); long rightTime = right.lastModified(); if (left.exists() && (!right.exists() || leftTime < rightTime)) { return copy(left, right); } else if (right.exists() && (!left.exists() || leftTime > rightTime)) { return copy(right, left); } } return true; } /** * unzips an input stream to a specified folder * @param zis ZipInputStream the source of zipped files * @param location File the folder (directory) where to unzip the files * @throws IOException when something went wrong * @return boolean true if success, false otherwise * * *

    Example: *
  • unzip(Web.getUrlInputStream(new URL(synchronize(new File(myHomeDir), new File(myBackupDir)) * will leave the contents of directories myHomeDIr and myBackupDir absolutely identical.
  • */ static public boolean unzip(ZipInputStream zis, File location) throws IOException { if (!location.exists()) { location.mkdirs(); } ZipEntry ze; while ((ze = zis.getNextEntry()) != null) { File output = new File(location, ze.getName()); if (ze.isDirectory()) { output.mkdirs(); } else { File dir = output.getParentFile(); if (!dir.isDirectory()) dir.delete(); dir.mkdirs(); if (!dir.exists()) { System.err.println("Could not create directory " + dir.getCanonicalPath()); return false; } OutputStream os = new FileOutputStream(output); pipe(zis, os, true); os.close(); } } zis.close(); return true; } /** * installs files from a resource archive * Reads a specified resource for aspecified class, unzips it to a specified directory * @param clazz Class the class whose package contains the archive as a resource * @param resourceArchiveName String the name of resource containing the archive * @param location File directory where the archive is unzipped * @throws IOException if something goes wrong * @return boolean true if success, false if failed */ public static boolean install(Class clazz, String resourceArchiveName, File location) throws IOException { ZipInputStream zis = new ZipInputStream(clazz.getResourceAsStream(resourceArchiveName)); return unzip(zis, location); } /** * installs files from a URL * Reads the contents of the specified URL, unzips it to a specified directory * @param URL url the url containing an archive to install * @param location File directory where the archive is unzipped * @throws IOException if something goes wrong * @return boolean true if success, false if failed */ public static boolean install(URL url, File location) throws IOException { return unzip(new ZipInputStream(url.openStream()), location); } /** * installs files from a URL * Reads the contents of the specified URL, unzips it to a specified directory * @param String urlString the string with the url containing an archive to install * @param location File directory where the archive is unzipped * @throws IOException if something goes wrong * @return boolean true if success, false if failed */ public static boolean install(String urlString, String directoryName) throws IOException { return unzip(new ZipInputStream(new URL(urlString).openStream()), new File(directoryName)); } /** * installs files from a resource archive * Reads a specified resource for aspecified class, unzips it to a specified directory * @param clazz Class the class whose package contains the archive as a resource * @param resourceArchiveName String the name of resource containing the archive * @param folderName String name of directory where the archive is unzipped * @throws IOException if something goes wrong * @return boolean true if success, false if failed */ public static boolean install(Class clazz, String resourceArchiveName, String folderName) throws IOException { return install(clazz, resourceArchiveName, new File(folderName)); } private static class ByteIterator implements Iterator { IOException exception = null; byte next; boolean have = false; InputStream is = null; private ByteIterator(InputStream is) { this.is = is; } public boolean hasNext() { if (have) { return true; } else if (is == null) { return false; } else { try { int input = is.read(); if (input < 0) { close(); } else { have = true; next = (byte)input; } } catch (IOException ex) { exception = ex; close(); } } return is != null; } public Byte next() { if (!hasNext()) { throw exception == null ? new NoSuchElementException() : new NoSuchElementException(exception.getMessage()); } have = false; return next; } public void remove() { throw new UnsupportedOperationException(); } private void close() { if (is != null) { try { is.close(); } catch (Exception e) {} } is = null; } protected void finalize() { close(); } } /** * returns an Iterable<Byte> enclosure that scans over the bytes returned by InputStream * @param is InputStream the stream to scan * @return Iterable<Byte> the enclosure * * The Iterator returned by the Iterable is a singleton; * you cannot expect to get a fresh Iterator by calling * iterator() several times. * *

    Example:

    * * for(byte b : bytes(new java.net.URL("http://yahoo.com").openSream())) { * System.out.println(b); * } * */ public static Iterable bytes(final InputStream is) { return new Iterable() { private final Iterator iterator = new ByteIterator(is); public Iterator iterator() { return iterator; } }; } /** * returns an Iterable<Byte> that scans over the bytes in a File * @param file File the file to scan * @return Iterable<Byte> the Iterable * *

    Example:

    * *
       *    for(byte b : bytes(new File("notepad.exe"))) {
       *      System.out.println(b);
       *    }
       * 
    */ public static Iterable bytes(final File file) { return new Iterable() { public Iterator iterator() { try { return new ByteIterator(new FileInputStream(file)); } catch (IOException e) { return new EmptyIterator(e.getMessage()); } } }; } private static class CharIterator implements Iterator { IOException exception = null; Reader reader; char next; boolean have = false; private CharIterator(Reader reader) { this.reader = reader; } public boolean hasNext() { if (have) { return true; } else if (reader == null) { return false; } else { try { int input = reader.read(); if (input < 0) { close(); } else { have = true; next = (char)input; return true; } } catch (IOException ex) { exception = ex; close(); } return reader != null; } } public Character next() { if (!hasNext()) { throw exception == null ? new NoSuchElementException() : new NoSuchElementException(exception.getMessage()); } have = false; return next; } public void remove() { throw new UnsupportedOperationException(); } private void close() { if (reader != null) { try { reader.close(); } catch (Exception e) {} } reader = null; } protected void finalize() { close(); } } /** * returns an Iterable<Character> enclosure that scans over the characters returned by Reader * @param reader Reader the reader to scan * @return Iterable<Character> the Iterable enclosure * * The Iterator returned by the Iterable is a singleton; * you cannot expect to get a fresh Iterator by calling * iterator() several times. *
    * Usage example:

    * * * for(char c : chars(new InputStreamReader(new java.net.URL("http://yahoo.com").openSream()))) { * System.out.println("[" + c + "]"); * } * */ public static Iterable chars(final Reader reader) { return new Iterable() { private final Iterator iterator = new CharIterator(reader); public Iterator iterator() { return iterator; } }; } /** * returns an Iterable<Character> that scans over the characters in a File * @param file File the file to scan * @return Iterable<Character> the Iterable *
    * Usage example:

    * * * for(char c : bytes(new File("readme.html"))) { * System.out.println("[" + c + "]"); * } * */ public static Iterable chars(final File file) { return new Iterable() { public Iterator iterator() { try { return new CharIterator(new FileReader(file)); } catch (IOException e) { return new EmptyIterator(e.getMessage()); } } }; } private static class LineIterator implements Iterator { LineNumberReader lr; IOException exception = null; String next; boolean have = false; private LineIterator(Reader reader) { lr = new LineNumberReader(reader); } public boolean hasNext() { if (have) { return true; } else if (lr == null) { return false; } else { try { next = lr.readLine(); if (next == null) { close(); } else { have = true; return true; } } catch (IOException ex) { exception = ex; close(); } return false; } } public String next() { if (!hasNext()) { throw exception == null ? new NoSuchElementException() : new NoSuchElementException(exception.getMessage()); } have = false; return next; } public void remove() { throw new UnsupportedOperationException(); } private void close() { if (lr != null) { try { lr.close(); } catch (Exception e) {} } lr = null; } protected void finalize() { close(); } } /** * returns an Iterable<String> enclosure that scans over the lines returned by Reader * @param reader Reader the reader to scan * @return Iterable<String> the Iterable enclosure * * The Iterator returned by the Iterable is a singleton; * you cannot expect to get a fresh Iterator by calling * iterator() several times. *
    * Usage example:

    * * * for(String line : chars(new LineNumberReader(new java.net.URL("http://yahoo.com").openSream()))) { * System.out.println(">" + line); * } * */ public static Iterable lines(final Reader reader) { return new Iterable() { private final Iterator iterator = new LineIterator(reader); public Iterator iterator() { return iterator; } }; } /** * returns an Iterable<String> that scans over the lines in a File * @param file File the file to scan * @return Iterable<String> the Iterable * * Usage example: * * * for(String line : lines(new File("readme.txt"))) { * System.out.println(">" + line); * } * */ public static Iterable lines(final File file) { return new Iterable() { public Iterator iterator() { try { return new LineIterator(new FileReader(file)); } catch (IOException e) { return new EmptyIterator(e.getMessage()); } } }; } /** * Returns an Iterable<File> that scans, recursively, through * the directory structure. * Traversal order is depth-first, preorder * * @param folder File starting directory * @return Iterable<File> the tree scanner * * Usage examples: * * * for(File subfolder : tree(new File("."))) { * System.out.println(subfolder.getCanonicalPath()); * } * * for(File folder : tree(new File("."))) { * System.out.println(file.getCanonicalPath()); * * for (File file : files(folder)) { * System.out.println(" " + file.getName()); * } * } * */ public static Iterable tree(final File folder) { return new Iterable() { public Iterator iterator() { return FolderIterator.preorder(folder); } }; } /** * Returns an Iterable<File> that scans, recursively, through * the directory structure. * Traversal order is depth-first, preorder * * @param folder File starting directory * @return Iterable<File> the tree scanner * * Usage examples: * * * for(File subfolder : tree(new File("."))) { * System.out.println(subfolder.getCanonicalPath()); * } * * for(File folder : tree(new File("."))) { * System.out.println(file.getCanonicalPath()); * * for (File file : files(folder)) { * System.out.println(" " + file.getName()); * } * } * */ public static Iterable tree(final File folder, final FileFilter filter) { return new Iterable() { public Iterator iterator() { return FolderIterator.preorder(folder, filter); } }; } /** * Returns an Iterable<File> that scans, recursively, * through the directory structure. * * Traversal order is depth-first, postorder * * @param folder File starting directory * @return Iterable<File> the tree scanner * * Usage examples: * * * for(File subfolder : treePostorder(new File("."))) { * System.out.println(subfolder.getCanonicalPath()); * } * * for(File folder : treePostorder(new File("."))) { * System.out.println(file.getCanonicalPath()); * * for (File file : files(folder)) { * System.out.println(" " + file.getName()); * } * } * */ public static Iterable treePostorder(final File folder) { return new Iterable() { public Iterator iterator() { return FolderIterator.postorder(folder); } }; } /** * Returns an Iterable<File> that scans all files in the folder * @param folder File directory to scan * @return Iterable<File> the scanner *
    * Usage example:

    * * * for (File file : files(new File(".")) { * System.out.println(file.getName()); * } * */ public static Iterable files(final File folder) { return Arrays.asList(listFiles(folder)); } } PK \>K2ú›.9¬¬'com/myjavatools/lib/FolderIterator.java/* *

    Title: My Java Tools Library

    * *

    Description: This is a mixture of useful Java Tools

    * * @(#)FileIterator.java 5.0 02/09/05 * *

    Copyright: This is public domain; The right of people to use, distribute, * copy or improve the contents of the following may not be restricted.

    */ package com.myjavatools.lib; import java.util.*; import java.io.File; import java.io.FileFilter; /** * FolderIterator is an Iterator that walks over the tree of * subfolders in a folder * Traversal order is depth-first; can be preorder or postorder. * To do breadth-first, we would need a queue; you are welcome to * implement it - I do not remember ever requiring breadth-first * traversal order for file folders since the time I learned about * file folders, which was long ago. * * @version 5.0, 02/10/05 * * @see java.util.Iterator * @see java.util.File * @see Iterators * @since 5.0 */ final class FolderIterator implements Iterator { private File self; private final Iterator outerIterator; private Iterator current = null; private FileFilter filter; private final boolean preorder; private FolderIterator(final File folder, boolean preorder) { this(folder, Files.DIRECTORY_FILTER, preorder); } private FolderIterator(final File folder, FileFilter filter, boolean preorder) { this.self = folder; this.filter = filter; this.preorder = preorder; this.outerIterator = Arrays.asList(folder.listFiles(filter)). iterator(); } private static FileFilter makeDirectoryFilter(final FileFilter filter) { return new FileFilter() { public boolean accept(File file) { return file.isDirectory() && filter.accept(file); } }; } /** * returns a FolderIterator to walk through directory tree, * depth-first, preorder * * @param folder File * @return FolderIterator */ public static FolderIterator preorder(File folder) { return new FolderIterator(folder, true); } /** * returns a FolderIterator to walk through directory tree, * depth-first, preorder, accepting only files that * FileFilter filter accepts. * * @param folder File * @param FileFilter filter * @return FolderIterator */ public static FolderIterator preorder(File folder, FileFilter filter) { return new FolderIterator(folder, makeDirectoryFilter(filter), true); } /** * returns a FolderIterator to walk through directory tree, * depth-first, postorder * * @param folder File * @return FolderIterator */ public static FolderIterator postorder(File folder) { return new FolderIterator(folder, false); } /** * returns a FolderIterator to walk through directory tree, * depth-first, postorder, accepting only files that * FileFilter filter accepts. * * @param folder File * @param FileFilter filter * @return FolderIterator */ public static FolderIterator postorder(File folder, FileFilter filter) { return new FolderIterator(folder, makeDirectoryFilter(filter), false); } /** * Returns true if the iterator has more elements to scan. * * @return true if the iterator has more elements. */ public boolean hasNext() { if (preorder && self != null) { return true; } return haveSubtree() || self != null; } private boolean haveSubtree() { while (current == null || !current.hasNext()) { if (outerIterator.hasNext()) { current = new FolderIterator(outerIterator.next(), filter, preorder); } else { return false; } } return true; } /** * Returns the next element in the iteration. * * @return the next element in the iteration. * @todo Implement this java.util.Iterator method */ public File next() { if (preorder && self != null) { return self(); } else if (haveSubtree()) { return current.next(); } else if (!preorder) { return self(); } throw new NoSuchElementException(); } private File self() { File result = self; self = null; return result; } /** * Removes from the underlying collection the last element returned by the * iterator (optional operation). */ public void remove() { throw new UnsupportedOperationException(); } } PK ›®õ0`—ï÷ŒŒ(com/myjavatools/lib/FormattedWriter.java/** *

    Title: MyJavaTools: Formatted File Output

    *

    Description: A typical formatted file consists of head, body and tail. * Body typicaly consists of repeating entries. This class does the output of this kind of files. * * Good for Java 5.0 and up.

    *

    Copyright: This is public domain; * The right of people to use, distribute, copy or improve the contents of the * following may not be restricted.

    * * @version 5.0 * @author Vlad Patryshev */ package com.myjavatools.lib; import java.io.*; import java.text.MessageFormat; public class FormattedWriter { MessageFormat head = null; MessageFormat body = null; MessageFormat tail = null; Writer writer = null; /** * Creates a writer that formats its output according to the format specified * * @see #FormattedWriter(Writer,String,String,String) * * @param writer the writer that outputs the formatted contents * @param format head format string * *

    Example
    * * String format = "Copyright (c) {0} {1}\r\n\r\n" +
    *         "{2}\r\n";
    *
    * FileFormat ff = new FileFormat(new FileWriter("readme.txt"), format);
    * ff.write("George Rasputin", "" + new Date().getYear(), "This is a stub for future readme text");
    *
    *

    This code will produce something like this:
    * Copyright (c) George Rasputin 2004
    *
    * This is a stub for future readme text
    *
    */ public FormattedWriter(Writer writer, String format) { this.writer = writer; head = format == null ? null : new MessageFormat(format); } /** * Creates a writer that formats its output according to head, body and tail formats specified * * @param writer the writer that outputs the formatted contents * @param head format string for the file head * @param body format string for (repeating) entries of the file body * @param tail format strings for the file tail * *

    Example
    * * String head = "/*\r\n Resource Data for package {0} in project {1}\r\n/*\r\n" +
    *         "class ResourceData {\r\n";
    * String body = " public String {0} = \"{1}\";\r\n";
    * String tail = "}\r\n";
    *
    * FileFormat ff = new FileFormat(new FileWriter("resource.java", head, body, tail);
    * ff.open(packageName, "My Cool Project");
    * Properties p = ...;
    * for (Enumeration i = p.keys(); i.hasMoreElements();) {
    *   String key = i.nextElement().toString();
    *   ff.write(new String[] {key, p.getProperty(key, "undef"});
    * }
    * ff.close();
    *

    This code will produce something like this:
    * /*
    * Resource Data for package com.my.package in project My Cool Project
    * */
    * class ResourceData {
    *   String dialogTitle = "Romeo vs Juliet";
    *   String label1 = "One of unmentionable major copyrighted labels";
    *   String size = "100x200";
    * }
    */ public FormattedWriter(Writer writer, String head, String body, String tail) { this(writer, head); this.body = body == null ? null : new MessageFormat(body); this.tail = tail == null ? null : new MessageFormat(tail); } /** * Creates a writer that formats its output according to the format specified * * @see #FormattedWriter(Writer,String) * * @param os output stream that outputs the formatted contents * @param format head format string */ public FormattedWriter(OutputStream os, String format) { this(new OutputStreamWriter(os), format); } /** * Creates a writer that formats its output according to head, body and tail formats specified * * @see #FormattedWriter(Writer,String,String,String) * * @param os output stream that outputs the formatted contents * @param head format string for the file head * @param body format string for (repeating) entries of the file body * @param tail format strings for the file tail */ public FormattedWriter(OutputStream os, String head, String body, String tail) { this(new OutputStreamWriter(os), head, body, tail); } /** * Gets head format string * @return head format string */ public MessageFormat getHead() { return head; } /** * Gets body format string * @return body format string */ public MessageFormat getBody() { return body; } /** * gets tail format string * @return tail format string */ public MessageFormat getTail() { return tail; } /** * Opens formatted output * @param args arguments for the head format * @throws IOException if write operation failes */ public void open(Object[]args) throws IOException { writer.write(head.format(args)); } /** * Opens formatted output * @param arg the only argiment for the head format * @throws IOException if write operation fails */ public void open(Object arg) throws IOException { writer.write(head.format(new Object[] {arg})); } /** * Opens formatted output, no arguments for head format * @throws IOException */ public void open() throws IOException { writer.write(head.format(null)); } /** * Writes a body string to formatted output * * @param args arguments for body format * @throws IOException if write operation fails * * Note. If body format is missing (then there is only head format), * then head format is applied to the arguments, the result of formatting is * written to the output, and the writer is closed. */ public void write(Object[]args) throws IOException { if (body != null) { writer.write(body.format(args)); } else { open(args); close(); } } /** * Writes an arbitrary string to (generally speaking) formatted output * * @param s the string to output * @throws IOException if write operation fails * * This skips any formatting; the string is just sent to output "as is". */ public void write(String s) throws IOException { writer.write(s); } /** * Writes the tail to formatted output and closes it * * @param args arguments for tail format * @throws IOException if write operation fails * * Note. if there is no tail format, the output just closes. */ public void close(Object[]args) throws IOException { if (tail != null) { writer.write(tail.format(args)); } writer.close(); } /** * Writes the tail to formatted output and closes it * * @throws IOException if write operation fails */ public void close() throws IOException { close(null); } } PK €š¤4ï|b­œîœî com/myjavatools/lib/Strings.java/* *

    Title: My Java Tools Library

    * *

    Description: This is a mixture of useful Java Tools

    * * @(#)Strings.java 5.0 11/15/04 * *

    Copyright: This is public domain; The right of people to use, distribute, * copy or improve the contents of the following may not be restricted.

    */ package com.myjavatools.lib; import java.io.*; import java.text.*; import java.util.*; import java.util.regex.*; import java.util.zip.*; import static com.myjavatools.lib.human.Logical.*; import static com.myjavatools.lib.foundation.Objects.*; public abstract class Strings { /** * CharSequence version of indexOf * * @param s CharSequence * @param c char * @param fromIndex int * @return int * * see java.lang.String#indexOf() for description */ public static int indexOf(CharSequence s, char c, int fromIndex) { for (int i = fromIndex; i < s.length(); i++) { if (s.charAt(i) == c) return i; } return -1; } /** * CharSequence version of indexOf * * @param s CharSequence * @param c char * @return int * * see java.lang.String.indexOf(char) for description */ public static int indexOf(CharSequence s, char c) { return indexOf(s, c, 0); } /** * CharSequence version of lastIndexOf * * @param s CharSequence * @param c char * @return int * * see java.lang.String.lastIndexOf(char) for description */ public static int lastIndexOf(CharSequence s, char c) { for (int i = s.length() - 1; i >= 0; i--) { if (s.charAt(i) == c)return i; } return -1; } /** * CharSequence version of indexOf * * @param sequence CharSequence * @param subsequence CharSequence * @param fromIndex int * @return int * * see java.lang.String.indexOf(String) for description */ public static int indexOf(CharSequence sequence, CharSequence subsequence, int fromIndex) { if (subsequence.length() == 0) return fromIndex; char c0 = subsequence.charAt(0); int subLength = subsequence.length(); int lastIndex = sequence.length() - subsequence.length(); for (int i = indexOf(sequence, c0, fromIndex); 0 <= i && i <= lastIndex; i = indexOf(sequence, c0, i+1)) { if (startsWith(sequence.subSequence(i, i + subLength), subsequence)) { return i; } } return -1; } /** * CharSequence version of indexOf * * @param sequence CharSequence * @param subsequence CharSequence * @return int * * see java.lang.String.indexOf(String) for description */ public static int indexOf(CharSequence sequence, CharSequence subsequence) { return indexOf(sequence, subsequence, 0); } /** * CharSequence version of startsWith * * @param sequence CharSequence * @param subsequence CharSequence * @return boolean * * see String.starstWith(String) for description */ public static boolean startsWith(CharSequence sequence, CharSequence subsequence) { if (sequence.length() < subsequence.length()) { return false; } for (int i = 0; i < subsequence.length(); i++) { if (sequence.charAt(i) != subsequence.charAt(i)) { return false; } } return true; } /** * Writes CharSequence to Writer (Hello, Sun! Ever heard of CharSequence class?) * * @param writer Writer * @param cs CharSequence * @throws IOException */ public static void write(Writer writer, CharSequence cs) throws IOException { if (cs == null) return; for (int i = 0; i < cs.length(); i++) { writer.write(cs.charAt(i)); } } /** * Checks whether a CharSequence does not contain anything except whitespaces and the like. * * @param s the sequence to check * @return true if empty * *

    Examples: *
  • isAlmostEmpty(""), isAlmostEmpty(null), isAlmostEmpty("\n \r \n") all return true;
  • *
  • isAlmostEmpty("."), isAlmostEmpty("Contains data!") returns false.
  • */ public static boolean isAlmostEmpty(CharSequence s) { if (isEmpty(s)) return true; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) > ' ') return false; } return true; } /** * Checks whether a character is a latin letter. * * @param c character to check * @return true if it is so * *

    Examples: *
  • isAlpha('a'), isAlpha('O'), isAlpha('I'), isAlpha('l') return true;
  • *
  • isAlpha('+'), isAlpha('0'), isAlpha('|'), isAlpha('1') return false.
  • */ public static boolean isAlpha(char c) { return Character.isJavaIdentifierStart(c); } /** * Checks whether a CharSequence contains any latin letters. * * @param s CharSequence to check * @return true if it is so * *

    Examples: *
  • hasAlpha("a"), hasAlpha("2OO2"), hasAlpha("This is a string") return true;
  • *
  • hasAlpha("+"), hasAlpha("1900"), hasAlpha("|1!*") return false.
  • */ public static boolean hasAlpha(CharSequence s) { for (int i = 0; i < s.length(); i++) { if (isAlpha(s.charAt(i))) return true; } return false; } /** * Counts the number of occurrences of char c in CharSequence s. * * @param s the string to scan * @param c the character to count * @return the number of occurrences * *

    Example: *
  • countChar("Goodness me, the clock has struck", 'o') returns 3.
  • */ public static int countChar(CharSequence s, char c) { int n = 0; for (int i = indexOf(s, c); i >= 0; i=indexOf(s, c, i+1)) { n++; } return n; } /** * Calculates how many lines the text contains. * Lines are supposed to be separated by '\n' character. * * @param s the CharSequence with text * @return number of lines in the string (separated by '\n') * *

    Examples: *
  • textHeight("One\nTwo\nThree") returns 3;
  • *
  • textHeight("\nOne\nTwo\nThree\n") returns 5.
  • */ public static int textHeight(CharSequence s) { return countChar(s, '\n') + 1; } /** * Calculates how many horizontal lines will the text take in a textarea. * This is the maximum line length for all lines in the text. * Lines are separated by '\n' character. * * @param s the CharSequence with text * @return maximum line length in the text * *

    Example: *
  • textWidth("One\nTwo\nThree") returns 5.
  • */ public static int textWidth(CharSequence s) { int n = 1; int curPos = 0; while (curPos < s.length()) { int nextPos = indexOf(s, '\n', curPos); if (nextPos < 0) nextPos = s.length(); if (n < nextPos - curPos) n = nextPos - curPos; curPos = nextPos+1; } return n; } /** * Calculates the number of words in the CharSequence. * This is just the number of tokens separated by default separators. * * @param s the CharSequence to analyze * @return number of words * *

    Examples: *
  • wordCount("This is life!") returns 3;
  • *
  • wordCount("C'est la vie !") returns 4, but for a wrong reason.
  • */ public static int wordCount(CharSequence s) { return (new StringTokenizer(s.toString())).countTokens(); } /** * Counts leading spaces in a char sequence * * @param s * @return number of leading spaces * *

    Example: *
  • countLeadingSpaces(" this is a string ") returns 1.
  • */ public static int countLeadingSpaces(CharSequence s) { int l = s.length(); int n = 0; while (n < l && s.charAt(n) == ' ') n++; return n; } /** * Counts trailing spaces in a char sequence * @param s * @return number of trailing spaces * *

    Example: *
  • countTrailingSpaces(" this is a string ") returns 3.
  • */ public static int countTrailingSpaces(CharSequence s) { int l = s.length(); int n = 0; while (n < l && s.charAt(l - n - 1) == ' ') n++; return n == s.length() ? 0 : n; } /** * Fills a string with a character * * @param c * @param n * @return a new string consisting of character c repeated n times * *

    Example: *
  • fill("*", 10) returns "**********".
  • */ public static String fill(char c, int n) { char[] data = new char[n]; Arrays.fill(data, c); return new String(data); } /** * "fast int to string hex" conversion array */ private static final String[] HEX = { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff", }; /** * Converts a byte to hex string. * * @param b the byte * @return b representation as a two-character hex string * *

    Example: *
  • toHex(155) returns "9b".
  • */ public static String toHex(byte b) { int i = b; return HEX[(i&255)]; } /** * Converts an integer to hex string. It is the same as Integer.toHexString(). * * @param i the integer * @return i representation as a hex string * *

    Example: *
  • toHex(1234) returns "4d2".
  • */ public static String toHex(int i) { return Integer.toHexString(i); } /** * Converts a char to hex string * * @param ch the char * @param up if true, use upper case, otherwise lower * @return i representation as a four-character hex string * *

    Examples: *
  • toHex('\u005cu12bc', true) returns "12BC";
  • *
  • toHex('\u005cu00af', false) returns "00af".
  • */ public static String toHex(char ch, boolean up) { String hex = "0000" + Integer.toHexString(ch); if (up) hex = hex.toUpperCase(); return hex.substring(hex.length() - 4); } /** * Converts a char to hex string * * @param ch the char * @return a four-character string (lower case) * *

    Example: *
  • toHex('\u005cu00af') returns "00af".
  • */ public static String toHex(char ch) { return toHex(ch, false); } /** * Converts a CharSequence to hex string (character by character) * * @param s the CharSequence * @param up if true, use upper case, otherwise lower * @return s representation as a hex string * *

    Examples: *
  • toHex("kl\u005cu12bc", true) returns "006B006C12BC";
  • *
  • toHex("kl\u005cu12bc", true) returns "006b006c12bc".
  • */ public static String toHex(CharSequence s, boolean up) { StringBuffer b = new StringBuffer(); for (int i = 0; i < s.length(); i++) { b.append(toHex(s.charAt(i), up)); } return b.toString(); } /** * Converts a character to its Java octal encoding format: \\o[o][o] * * @param c the character * @return a string * *

    Example: *
  • toJavaOctalEncoding('\n') returns "\\12".
  • */ public static String toJavaOctalEncoding(char c) { return "\\" + Integer.toString(c, 8); } /** * Converts a character to its Java hex encoding format: \\uxxxx * * @param c the character * @return a string, encoded c representation * *

    Example: *
  • toJavaHexEncoding('\u005cu00af') returns "\\u00af".
  • */ public static String toJavaHexEncoding(char c) { return "\\u" + toHex(c); } /** * Converts a character to its Java hex encoding format: \\uxxxx * * @param c the character * @param up if true, use upper case, otherwise lower * @return a string, encoded c representation * *

    Example: *
  • toJavaHexEncoding('\u005cu00af', false) returns "\\u00af".
  • */ public static String toJavaHexEncoding(char c, boolean up) { return "\\u" + toHex(c, up); } /** * Converts a character to how it should be represented in properties files * * @param c the character * @param up if true, use upper case, otherwise lower * @return a string, encoded c representation * *

    Examples: *
  • toPropertiesEncoding('\u005cu00af', false) returns "\\u00af";
  • *
  • toPropertiesEncoding('\u005cu00af', true) returns "\\u00AF";
  • *
  • toPropertiesEncoding('a', false) returns "a".
  • */ public static String toPropertiesEncoding(char c, boolean up) { return (c > 0x7f || c < ' ') ? toJavaHexEncoding(c, up) : ("" + c); } /** * Converts a character to how it should be represented in properties files * * @param c the character * @return a string, encoded c representation * *

    Examples: *
  • toPropertiesEncoding('\u005cu00af') returns "\\u00af";
  • *
  • toPropertiesEncoding('a') returns "a".
  • */ public static String toPropertiesEncoding(char c) { return toPropertiesEncoding(c, false); } /** * Characters that should be escaped in Java or C code * * {@value} */ public static final String ESCAPEE = "\\\"\'\n\r\t\f\b"; /** * Characters used in escapes * * {@value} */ public static final String ESCAPED = "\\\"'nrtfb"; /** * Checks whether a character needs encoding in Java * * @param c the character * @return true if so * *

    Examples: *
  • needsEncoding('\u005cu00af') returns true;
  • *
  • needsEncoding('a') returns false.
  • */ public static boolean needsEncoding(char c) { return ESCAPEE.indexOf(c) >= 0 || c < ' ' || c > 0x7f; } /** * Converts a character to its Java encoding (hex or escaped or intact) * * @param c the character * @param up if true, use upper case, otherwise lower * @param escape if true, escape escapable characters * @return a string with a proper Java representation of the character c * *

    Examples: *
  • toJavaEncoding('\u005cu00af', false, false) returns "\\u00af";
  • *
  • toJavaEncoding('\u005cu000a', true, true) returns "\\n";
  • *
  • toJavaEncoding('\u005cu000e', true, true) returns "\\16";
  • *
  • toJavaEncoding('a', true, true) returns "a".
  • */ public static String toJavaEncoding(char c, boolean up, boolean escape) { int i = escape ? ESCAPEE.indexOf(c) : -1; return (i >= 0) ? ("\\" + ESCAPED.charAt(i)) : (c < ' ') ? toJavaOctalEncoding(c) : (c > 0x7f) ? toJavaHexEncoding(c, up) : ("" + c); } /** * Converts a character to its Java encoding (hex or escaped or intact) * * @param c the character * @param up if true, use upper case, otherwise lower * @return a string with a proper Java representation of the character c * *

    Examples: *
  • toJavaEncoding('\u005cu00af', false) returns "\\u00af";
  • *
  • toJavaEncoding('\u005cu00af', true) returns "\\u00AF";
  • *
  • toJavaEncoding('\u005cu000a', true) returns "\\n";
  • *
  • toJavaEncoding('\u005cu000e', true) returns "\\16";
  • *
  • toJavaEncoding('a', true) returns "a".
  • */ public static String toJavaEncoding(char c, boolean up) { return toJavaEncoding(c, up, true); } /** * Converts a character to its Java encoding (hex or escaped or intact) * * @param c the character * @return a string with a proper Java representation of the character c * *

    Examples: *
  • toJavaEncoding('\u005cu00af') returns "\\u00af";
  • *
  • toJavaEncoding('\u005cu000a') returns "\\n";
  • *
  • toJavaEncoding('\u005cu000e') returns "\\16";
  • *
  • toJavaEncoding('a') returns "a".
  • */ public static String toJavaEncoding(char c) { return toJavaEncoding(c, false); } /** * Converts a character to its C encoding (hex or escaped or intact) * * @param c the character * @return a string with a proper C language representation of the character c * *

    Examples: *
  • toCEncoding('\u005cuabcd') returns "\\xabcd";
  • *
  • toCEncoding('\u005cu00af') returns "\\xaf";
  • *
  • toCEncoding('\u005cu000a') returns "\\n";
  • *
  • toCEncoding('a') returns "a".
  • */ public static String toCEncoding(char c) { int i = ESCAPEE.indexOf(c); return (i >= 0) ? ("\\" + ESCAPED.charAt(i)) : (c < ' ' || c > 0x7f) ? ("\\x" + Long.toHexString(c)) : ("" + c); } /** * Checks whether a CharSequence needs encoding in Java * * @param s the CharSequence * @return true if so * *

    Examples: *
  • needsEncoding("Feliz Año Nuevo") returns true;
  • *
  • needsEncoding("Feliz Navedad") returns false.
  • */ public static boolean needsEncoding(CharSequence s) { if (s == null) return false; for (int i = 0; i < s.length(); i++) { if (needsEncoding(s.charAt(i))) return true; } return false; } /** * Converts a CharSequence to its Java encoding (hex or escaped or intact, per char) * * @param s the CharSequence * @param up if true, use upper case, otherwise lower * @param escape if true, escape escapable characters * @return the encoded string * *

    Examples: *
  • toJavaEncoding("\nFeliz Año Nuevo\n", true, false) * returns "\u005cu000AFeliz \u005cu00A4o Nuevo\u005cu000A";
  • *
  • toJavaEncoding("\nFeliz Año Nuevo\n", true, true) * returns "\\nFeliz \u005cu00A4o Nuevo\\n";
  • *
  • toJavaEncoding("\nFeliz Año Nuevo\n\0", false, true) * returns "\\nFeliz \u005cu00a4o Nuevo\\n\\0".
  • */ public static String toJavaEncoding(CharSequence s, boolean up, boolean escape) { if (!needsEncoding(s)) return s.toString(); StringBuffer buf = new StringBuffer(); for (int i = 0; i < s.length(); i++) { buf.append(toJavaEncoding(s.charAt(i), up, escape)); } return buf.toString(); } /** * Converts a CharSequence to its Java encoding (hex or escaped or intact, per char) * * @param s the CharSequence * @param up if true, use upper case, otherwise lower * @return the encoded string * *

    Examples: *
  • toJavaEncoding("\nFeliz Año Nuevo\n", true) * returns "\nFeliz \u005cu00A4o Nuevo\n";
  • *
  • toJavaEncoding("\nFeliz Año Nuevo\n\0", false) * returns "\\nFeliz \u005cu00a4o Nuevo\\n\\0".
  • */ public static String toJavaEncoding(CharSequence s, boolean up) { return toJavaEncoding(s, up, true); } /** * Converts a CharSequence to its Java encoding (hex or escaped or intact, per char) * * @param s the CharSequence * @return the encoded string * *

    Example: *
  • toJavaEncoding("\nFeliz Año Nuevo\n\0") * returns "\\nFeliz A\u005cu00f1o Nuevo\\n\\0".
  • */ public static String toJavaEncoding(CharSequence s) { return toJavaEncoding(s, false); } /** * Converts a CharSequence to its C encoding * * @param s the CharSequence * @return the encoded string * *

    Example: *
  • toCEncoding("\nFeliz Año Nuevo\n") * returns "\\nFeliz A\\x00f1o Nuevo\\n".
  • */ public static String toCEncoding(CharSequence s) { if (!needsEncoding(s)) return s.toString(); StringBuffer buf = new StringBuffer(); for (int i = 0; i < s.length(); i++) { buf.append(toCEncoding(s.charAt(i))); } return buf.toString(); } /** * Converts a character to its SGML numeric encoding * * @param c the character * @return a string with the representation of c as * "Numeric Character Reference" in SGMLese * *

    Example: *
  • toSgmlEncoding('\n') * returns "&#10;".
  • */ public static String toSgmlEncoding(char c) { return c > 0x20 || c == 0x9 || c == 0xa || c == 0xd ? "&#" + (int)c + ";" : "?"; } /** * Encodes a character by SGML rules * It can be a hex representation * @param c the character * @return the string with either Predefined Entity, Numeric Character Reference, * or null if no entity could be found * *

    Examples: *
  • sgmlEntity('\u005c60ab') returns "&#24747;" (that is, Numeric Character Reference);
  • *
  • sgmlEntity('<') returns "&lt;" (that is, Predefined Entity);
  • *
  • sgmlEntity('&') returns "&lt;" (that is, Predefined Entity);
  • *
  • sgmlEntity('X') returns null";
  • *
  • sgmlEntity('\n') returns null".
  • */ public static String sgmlEntity(char c) { return c == '<' ? "<" : c == '>' ? ">" : c == '\'' ? "'" : c == '\"' ? """ : c == '&' ? "&" : c == ']' ? "]" : (c < '\u0020' && c != '\n' && c != '\r' && c != '\t') || c > '\u0080' ? toSgmlEncoding(c) : null; } /** * Encodes a CharSequence by SGML rules * (using predefined entities and numeric character encodings when necessary) * @param s the original CharSequence * @return the encoded string * *

    Example: *
  • toSgmlEncoding("Feliz Año Nuevo\n") * returns "&lt;i&gt;Feliz A&#164;o Nuevo&lt;/i&gt;\n".
  • */ public static String toSgmlEncoding(CharSequence s) { if (isEmpty(s)) return s.toString(); StringBuffer buffer = new StringBuffer(s.length() * 2); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); String entity = sgmlEntity(c); if (entity == null) { buffer.append(c); } else { buffer.append(entity); } } return buffer.toString(); } //**************************************************** // html-encode all non-ascii chars /** * encodes a CharSequence into an HTML-acceptable format * * @param s CharSequence original CharSequence * @return String encoded string * * All non-ascii characters are replaced with their &# representation; other * characters are left intact. * *

    Example: *
  • htmlEncode("Feliz Año Nuevo\n") * returns "Feliz A&#164;o Nuevo\n".
  • */ public static String htmlEncode(CharSequence s) { if (isEmpty(s)) return ""; StringBuffer out = new StringBuffer(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); int k = c; if (c > 0x100) { out.append("&#" + k + ";"); } else { out.append(c); } } return out.toString(); } /** * Converts a char array to a readable string. * (By Replacing potentially unreadables characters with '.') * * @param data original char array * @param beginIndex where to start * @param endIndex where to end (before this position) * @return the string with unreadable chars replaced * *

    Example: *
  • toReadable("\t¡Hola señor!\n".toCharArray(), 2, 12) * will return "..Hola se.or!.".
  • */ public static String toReadable(char[] data, int beginIndex, int endIndex) { StringBuffer buf = new StringBuffer(data.length); for (int i = beginIndex; i < data.length && i < endIndex; i++) { char c = data[i]; if (c < ' ' || c > 127) c = '.'; buf.append(c); } return buf.toString(); } /** * Converts a CharSequence to a readable string. * (By Replacing potentially unreadables characters with '.') * * @param s original CharSequence * @return the string with unreadable chars replaced * *

    Example: *
  • toReadable("\t¡Hola señor!\n") will return "..Hola se.or!.".
  • */ public static String toReadable(CharSequence s) { return toReadable(s.toString().toCharArray(), 0, s.length()); } /** * Hexadecimal dump of a byte array. * Produces neatly arranged lines of bot hex and ascii representation of bytes * from the array. * * @param data the data array * @return the hex dump string * *

    Example: *
  • hexDump(new byte[] {1, 'a', 'b', '\n', 'c'}) will return * "\r\n01 61 62 0a 63 | . a b . c\r\n".
  • */ public static String hexDump(byte[] data) { if (data == null || data.length == 0) return ""; StringBuffer out = new StringBuffer(); for (int i = 0; i < data.length; i+= 16) { out.append("\r\n"); out.append(toHex((byte)(i >> 8))); out.append(toHex((byte)(i ))); out.append(": "); for (int j = i; j < i + 16; j++) { out.append(j < data.length ? toHex(data[j]) : " "); out.append(" "); } out.append("| "); for (int j = i; j < i + 16 && j < data.length; j++) { byte b = data[j]; out.append(b >= ' ' ? (char)b : '\u00b7'); out.append(" "); } } out.append("\r\n"); return out.toString(); } /** * Hexadecimal dump of a char array * Produces neatly arranged lines of bot hex and ascii representation of bytes * from the array. * * @param data the data array * @return a string containing both hex and ascii representation of the data * *

    Example: *
  • hexDump(new char[] {1, 'a', 'b', '\n', 'c'}) will return
    * "\r\n0000: 0001 0061 0062 000a 0063 | .ab.c\r\n".
  • */ public static String hexDump(char[] data) { if (data == null || data.length == 0) return ""; StringBuffer out = new StringBuffer(); for (int i = 0; i < data.length; i+= 16) { out.append("\r\n"); out.append(i < 16 ? "000" : i < 256 ? "00" : i < 4096 ? "0" : ""); out.append(toHex(i)); out.append(": "); for (int j = i; j < i + 16; j++) { out.append(j >= data.length ? " " : toHex(data[j])); out.append(" "); } out.append("| "); out.append(toReadable(data, i, Math.min(i+16, data.length))); } out.append("\r\n"); return out.toString(); } /** * Hexadecimal dump of a CharSequence * Produces neatly arranged lines of bot hex and ascii representation of bytes * from the array. * * @param data the CharSequence * @return a string containing both hex and ascii representation of the data * *

    Example: *
  • hexDump("\u0001ab\nc") will return * "\r\n0001 0061 0062 000a 0063 | .ab.c".
  • */ public static String hexDump(CharSequence data) { return hexDump(data.toString().toCharArray()); } /** * Converts an array of chars to a readable hexadecimal form * * @param data the data array * @return a string that is basically a hex dump of the data * *

    Example: *
  • toHexReadable(new char[] {1, 'a', 'b', '\n', 'c'}) will return * "0001 0061 0062 000a 0063 \r\n".
  • */ public static String toHexReadable(char[] data) { if (data == null || data.length == 0) return ""; StringBuffer out = new StringBuffer(); for (int i = 0; i < data.length; i++) { out.append(toHex(data[i])); out.append(" "); if (i % 16 == 15 || i == data.length - 1) { out.append("\r\n"); } } return out.toString(); } /** * Converts an array of chars to a readable hexadecimal form * * @param data the data array * @param from beginning index * @param to ending index (not included) * @return a string that is basically a hex dump of the data * *

    Example: *
  • toHexReadable(new byte[] {1, 2, 48}, 1, 3) will return * "02 30 \r\n".
  • */ public static String toHexReadable(byte[] data, int from, int to) { if (data == null || data.length == 0) return ""; StringBuffer out = new StringBuffer(); int limit = Math.min(to, data.length); for (int i = from; i < limit; i++) { out.append(toHex(data[i])); out.append(" "); if (i % 16 == 15 || i == limit - 1) { out.append("\r\n"); } } return out.toString(); } /** * Converts an array of bytes to a readable hexadecimal form * * @param data the data array * @return a string that is basically a hex dump of the data * *

    Example: *
  • toHexReadable(new byte[] {1, 2, 48}) will return * "01 02 30 ".
  • */ public static String toHexReadable(byte[] data) { if (data == null) return ""; return toHexReadable(data, 0, data.length); } /** * Converts a CharSequence to a readable hexadecimal string * * @param s the data CharSequence * @return a string that is basically a hex dump of the data * *

    Example: *
  • toHexReadable("\u0001ab\nc") will return * "0001 0061 0062 000a 0063 \r\n".
  • */ public static String toHexReadable(CharSequence s) { if (isEmpty(s)) return ""; StringBuffer out = new StringBuffer(); for (int i = 0; i < s.length(); i++) { out.append(toHex(s.charAt(i))); out.append(" "); if (i % 16 == 15 || i == s.length() - 1) { out.append("\r\n"); } } return out.toString(); } /** * Perl operation join. * Concatenates a collection of (string representations of) objects * using a separator string to separate * * @param separator the separator CharSequence * @param collection the collection of objects to join * @return resulting string * *

    Examples:
    * * HashSet a = new HashSet();
    * List b = new ArrayList(); b.add("entry1"); b.add("entry2");
    *
  • join(", ", a) returns "";
  • *
  • join(", ", b) returns "entry1, entry2".
  • */ public static String join(CharSequence separator, Collection collection) { if (separator == null || collection == null) return ""; StringBuffer buf = new StringBuffer(); for (Object element : collection) { if (buf.length() > 0) buf.append(separator); buf.append(element); } return buf.toString(); } /** * Perl operation join. * Concatenates an array of (string representations of) objects * using a separator to separate * * @param separator the separator * @param what the array of objects to join * @return resulting string * *

    Examples:
    *
  • join(", ", new Long[] {1, 555}) * returns "1, 555";
  • *
  • join(" and ", new String[] {"Here", "there", "everywhere"}) * returns "Here and there and everywhere".
  • */ public static String join(CharSequence separator, T... what) { if (separator == null || what == null) return ""; StringBuffer buf = new StringBuffer(); for (T object : what) { if (object != null) { if (buf.length() > 0) { buf.append(separator); } buf.append(object.toString()); } } return buf.toString(); } /** * Perl operation split. * splits a source string into a collection of strings * * @param separator CharSequence separator character sequence * @param source CharSequence source character sequence * @return an Iterable<CharSequence> of extracted character sequences * * @see #join(CharSequence, Object[]) * see java.lang.String.split(String) * *

    Example:
    * *
  • split(":", "a:ab:abcde:") * returns a list containing four elements, "a", "ab", "abcde", "".
  • */ public static Iterable split(final CharSequence separator, final CharSequence source) { return new Iterable() { public Iterator iterator() { return new Iterator() { int pos = 0; public boolean hasNext() { return pos <= source.length(); } public void remove() { throw new UnsupportedOperationException(); } public CharSequence next() { int next = indexOf(source, separator, pos); if (next < 0) { next = source.length(); } CharSequence result = pos > next ? "" : source.subSequence(pos, next); pos = next + separator.length(); return result; } }; } }; } /** * Perl operation grep. * Extracts from a string array the strings that match a regexp * * @param source source array * @param regexp expression to match * @return a collection of matching character sequences from source * *

    Example:
    * *
  • grep(new String[] {"good", "bad", "ugly"}, "g.")) * returns a list containing two elements: "good", "ugly".
  • */ public static List grep(T[] source, CharSequence regexp) throws PatternSyntaxException { return grep(source, Pattern.compile(regexp.toString())); } /** * Perl operation grep. * Extracts from an array the char sequences that match a regexp * * @param source source array * @param regexp expression to match * @return a collection of matching character sequences * *

    Example:
    * *
  • grep(new String[] {"good", "bad", "ugly"}, Pattern.compile("g."))) * returns a list containing two elements: "good", "ugly".
  • */ public static List grep(T[] source, Pattern regexp) { ArrayList result = new ArrayList(); for (T element : source) { Matcher matcher = regexp.matcher(element); if (matcher.find()) { result.add(element); } } result.trimToSize(); return result; } /** * Replaces a subsequence in a char sequence with another subsequence * * @param where the string containing the substrings to replace * @param oldSubstring what to replace * @param newSubstring with what to replace * @param all if true, all (nonintersecting) substrings are replaced, * otherwise only one * @return resulting string * * @deprecated since 5.0; use replace() without boolean argument, or replaceAll() * * see java.lang.String.replaceAll(String,String) and java.lang.String.replaceFirst(String, String) * *

    Examples: *
  • replace("Bokonon loves you", "love", "hate", true) * returns "Bokonon hates you";
  • *
  • replace("All you need is love, love!", "me", false) * returns "All you need is me, love!".
  • */ public static String replace(CharSequence where, CharSequence oldSubstring, CharSequence newSubstring, boolean all) { if (where == null) return null; if (oldSubstring == null || newSubstring == null) return where.toString(); StringBuffer out = new StringBuffer(); int pos = 0; do { int newPos = indexOf(where, oldSubstring, pos); if (newPos < 0) break; out.append(where.subSequence(pos, newPos)); out.append(newSubstring); pos = newPos + oldSubstring.length(); } while (all); out.append(where.subSequence(pos, where.length())); return out.toString(); } /** * Replaces a subsequence in a char sequence with another subsequence * * @param where the string containing the substrings to replace * @param oldSubstring what to replace * @param newSubstring with what to replace * @return resulting string * * see java.lang.String.replaceAll(String,String) and java.lang.String.replaceFirst(String, String) * *

    Example: *
  • replace("All I need is love, love, love!", "You") * returns "All I need is You, You, You!".
  • */ public static String replaceAll(CharSequence where, CharSequence oldSubstring, CharSequence newSubstring) { return replace(where, oldSubstring, newSubstring, true); } /** * Replaces all instances of subsequence in a char sequence with another subsequence * * @param where the string containing the substrings to replace * @param oldSubstring what to replace * @param newSubstring with what to replace * @return resulting string * * see java.lang.String.replaceAll(String,String) and java.lang.String.replaceFirst(String, String) * *

    Example: *
  • replace("All you need is love, love!", "me") * returns "All you need is me, love!".
  • */ public static String replace(CharSequence where, CharSequence oldSubstring, CharSequence newSubstring) { return replace(where, oldSubstring, newSubstring, false); } /** * Extracts value from a char sequence of format NAME="VALUE" * * @param input sequence of the aforementioned format * @param name the name on the left side of '=' * @return the string value inside the quotes (quotes omitted) if the string * has the specified format; null utherwise * *

    Examples: *
  • extractValue("java.home=\"c:\\java\\jdk1.4.1\"\nx=\"abcd\"", "x") * returns "abcd";
  • *
  • extractValue("java.home=\|c:\\java\\jdk1.4.1\"\nx=\"abcd\"", "java.home") * returns "c:\\java\\jdk1.4.1".
  • */ public static String extractValue(CharSequence input, CharSequence name) { int iname = indexOf(input, name + "=\""); if (iname < 0) return null; int ivalue = iname + name.length() + 2; int ievalu = indexOf(input, '"', ivalue); if (ievalu < 0) return null; return input.subSequence(ivalue, ievalu).toString(); } /** * Packs bytes into a string * * @param from byte array * @return a string that consists of the same bytes, packed two per character * *

    Example: *
  • pack(new byte[] {0x23, 0x67, (byte)0xab, (byte)0xef}) * returns "\u2367\uabef".
  • */ public static String pack(byte[] from) { StringBuffer buffer = new StringBuffer((from.length + 1) / 2); char hibyte = 0; for (int i = 0; i < from.length / 2 * 2; i+=2) { buffer.append((char)((0xff00 & (from[i] << 8)) + ( 0xff & from[i+1]))); } if (from.length % 2 != 0) { buffer.append((char)(0xff & from[from.length - 1])); } return buffer.toString(); } /** * Unpacks bytes packed in the char sequence * * @see #pack(byte[]) * @param data the packed data * @return the unpacked data * *

    Example: *
  • unpack("\u2367\uabef") * returns new byte[] {0x23, 0x67, (byte)0xab, (byte)0xef}.
  • */ public static byte [] unpack(CharSequence data) { // The following method does not work for JDK 1.4; it seems like it replaces // "bad" UTF-16 characters with ff fe sequences. // return encode(string, "UTF-16BE"); byte[] result = new byte[data.length() * 2]; for (int i = 0; i < data.length(); i++) { int c = data.charAt(i); result[i * 2] = (byte)(c >> 8); result[i * 2 + 1] = (byte) c; } return result; } /** * Decodes (and unescapes) a Java string. * Replaces escape sequences with their corresponding character values * * @param string as presented in the source code * @return decoded string in "internal form" * *

    Examples: *
  • decodeJavaString("This is a string") returns "This is a string";
  • *
  • decodeJavaString("\\nFeliz \\u00A4o Nuevo\\n") * returns "\nFeliz Año Nuevo\n".
  • */ public static String decodeJavaString(CharSequence string) { StringBuffer output = new StringBuffer(string.length() * 2); if (indexOf(string, '\\') < 0) { return string.toString(); } for (int i=0; i < string.length(); i++) { char ch = string.charAt(i); if (ch == '\\' && i < string.length() - 1) { // So, we have a backslash... int escapeIdx = ESCAPED.indexOf(string.charAt(i+1)); if (escapeIdx >= 0) { i++; ch = ESCAPEE.charAt(escapeIdx); } else if (i < string.length() - 5 && string.charAt(i + 1) == 'u') { //possible escape try { ch = (char)Integer.parseInt(string.subSequence(i+2, i+6).toString(), 16); i += 5; } catch (NumberFormatException nfe) { // Okay, okay, not a hex number... } } } output.append(ch); } return output.toString(); } /** * Encodes a char sequence using specified encoding * * @see list of Java encodings * * @param s char sequence to encode * @param encoding the name of encoding * @return encoded array of bytes * @throws IOException when something goes wrong with bytearray streams * @throws UnsupportedEncodingException when encoding is unknown * *

    Examples: *
  • encode("Año Nuevo", "UTF8") * returns new byte[] {0x41, (byte)0xc3, (byte)0xb1, 0x6f, 0x20, 0x4e, 0x75, 0x65, 0x76, 0x6f};
  • *
  • encode("Año Nuevo", "MacRoman") * returns new byte[] {0x41, (byte)0x96, 0x6f, 0x20, 0x4e, 0x75, 0x65, 0x76, 0x6f}.
  • */ public static byte[] encode(CharSequence s, String encoding) throws IOException, UnsupportedEncodingException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); Writer osw = new OutputStreamWriter(bos, encoding); write(osw, s); osw.close(); return bos.toByteArray(); } /** * Decodes a stream using specified encoding * * @see list of Java encodings * * @param is stream to decode * @param encoding the name of encoding * @return data decoded from the stream * @throws IOException when something goes wrong with bytearray streams * @throws UnsupportedEncodingException when encoding is unknown * */ public static String decode(InputStream is, String encoding) throws IOException, UnsupportedEncodingException { Reader isr = new InputStreamReader(is, encoding); StringBuffer result = new StringBuffer(); char[] readBuffer = new char[4096]; while (isr.ready()) { int l = isr.read(readBuffer); result.append(readBuffer, 0, l); } return result.toString(); } /** * Decodes an array of bytes using specified encoding * * @see list of Java encodings * * @param bytes byte array * @param encoding the name of encoding * @return decoded string * @throws IOException when something goes wrong with bytearray streams * @throws UnsupportedEncodingException when encoding is unknown * *

    Examples: *
  • decode(new byte[] {0x41, (byte)0xc3, (byte)0xb1, 0x6f, 0x20, 0x4e, 0x75, 0x65, 0x76, 0x6f}, "UTF8") * returns "Año Nuevo";
  • *
  • encode( new byte[] {0x41, (byte)0x96, 0x6f, 0x20, 0x4e, 0x75, 0x65, 0x76, 0x6f}, "MacRoman") * returns "Año Nuevo".
  • */ public static String decode(byte[] bytes, String encoding) throws IOException, UnsupportedEncodingException { return decode(new ByteArrayInputStream(bytes), encoding); } /** * zip (like in zip files) a string producing an array of bytes * * @param source the string to zip * @return bytes representing zipped data * @throws IOException when something goes wrong with streams * @throws UnsupportedEncodingException when JDK forgets that it knows UTF8 * *

    Example: *
  • zip2bytes("Hello World") * returns new byte[] {0x78, (byte)0xda, (byte)0xf3, 0x48, (byte)0xcd, (byte)0xc9, (byte)0xc9, 0x57, (byte)0x08, (byte)0xcf, 0x2f, (byte)0xca, 0x49, 0x01, 0x00, 0x18, 0x0b, 0x04, 0x1d, 0x00}.
  • */ public static byte[] zip2bytes(CharSequence source) throws IOException, UnsupportedEncodingException { if (source == null) return null; ByteArrayOutputStream bos = new ByteArrayOutputStream(); DeflaterOutputStream dos = new DeflaterOutputStream(bos, new Deflater(Deflater.BEST_COMPRESSION)); Writer osw = new OutputStreamWriter(dos, "UTF-8"); write(osw, source); osw.flush(); dos.finish(); bos.write(0); // Just to pad in case of, you know, odd number of bytes. osw.close(); byte[] result = bos.toByteArray(); return result; } /** * zips a char sequence to a string of lower-byte chars. * Does this: CharSequence -> UTF8 bytes -> zip -> bytes -> String * @param source char sequence to zip * @return string with zipped data * @throws IOException when something goes wrong with streams * @throws UnsupportedEncodingException when JDK forgets that it knows UTF8 * *

    Example: *
  • zip8bit("Hello World") * returns "x\u00da\u00f3H\u00cd\u00c9\u00c9W\b\u00cf/\u00caI\u0001\u0000\u0018\u000b\u0004\u001d\u0000".
  • */ public static String zip8bit(CharSequence source) throws IOException, UnsupportedEncodingException { return new String(zip2bytes(source)); } /** * zips a char sequence to a string. * Does this: CharSequence -> UTF8 bytes -> zip -> bytes -> High Unicode -> String * * @param source char sequence to zip * @return string with zipped data * @throws IOException when something goes wrong with streams * @throws UnsupportedEncodingException when JDK forgets that it knows UTF8 * *

    Example: *
  • zip("Hello World") * returns "\u78da\uf348\ucdc9\uc957\u08cf\u2fca\u4901\u0018\u0b04\u1d00".
  • */ public static String zip(CharSequence source) throws IOException, UnsupportedEncodingException { return pack(zip2bytes(source)); } /** * Unzips a stream. * Does this: stream -> unzip -> bytes -> UTF8 -> String * * @param zippedStream * @return string with unzipped data * @throws IOException when something goes fishy * @throws UnsupportedEncodingException when JDK forgets that it knows UTF8 */ public static String unzip(InputStream zippedStream) throws IOException, UnsupportedEncodingException { return decode(new InflaterInputStream(zippedStream), "UTF-8"); } /** * Unzips an array of bytes. * Does this: bytes -> unzip -> bytes -> UTF8 -> String * * @param zippedBytes * @return string with unzipped data * @throws IOException when something goes fishy * @throws UnsupportedEncodingException when JDK forgets that it knows UTF8 * *

    Example: *
  • unzip(new byte[] {0x78, (byte)0xda, (byte)0xf3, 0x48, (byte)0xcd, (byte)0xc9, (byte)0xc9, 0x57, 0x08, (byte)0xcf, 0x2f, (byte)0xca, 0x49, 0x01, 0x00, 0x18, 0x0b, 0x04, 0x1d, 0x00}) * returns "Hello World".
  • */ public static String unzip(byte[] zippedBytes) throws IOException, UnsupportedEncodingException { return unzip(new ByteArrayInputStream(zippedBytes)); } /** * Unzips a char sequence * Does this: CharSequence -> High Unicode bytes -> unzip -> bytes -> UTF8 -> String * * @param zipped * @return string with unzipped data * @throws IOException when something goes fishy * @throws UnsupportedEncodingException when JDK forgets that it knows UTF8 * *

    Example: *
  • unzip("\u78da\uf348\ucdc9\uc957\u08cf\u2fca\u4901\u0018\u0b04\u1d00") * returns "Hello World".
  • */ public static String unzip(CharSequence zipped) throws IOException, UnsupportedEncodingException { return unzip(unpack(zipped)); } /** * Calculates crc32 on a char sequence * @param data source char sequence * @return its crc32 * @throws IOException when something goes wrong with streams * @throws UnsupportedEncodingException when JDK forgets that it knows UTF8 * *

    Example: *
  • crc32("Hello World") * returns 2178450716l.
  • */ public static long crc32(CharSequence data) throws IOException, UnsupportedEncodingException { return Bytes.crc32(unpack(data)); } /** * Converts a map to string array, "key=value" * * @param map Map<K,V> the map to stringify * @return array of strings * *

    Example: *
  • Map map = new HashMap(); * map.put("PATH", "c:\java\bin"); * map.put("CLASSPATH", "c:\java\lib"); * toStrings(map) * returns new String[] {"PATH=c:\java\bin", "CLASSPATH=c:\java\lib"}.
  • * */ public static String[] toStrings(Map map) { if (map == null) return null; String[] result = new String[map.size()]; Set> entrySet = map.entrySet(); int i = 0; for(Map.Entry entry : entrySet) { result[i++] = entry.getKey().toString() + "=" + entry.getValue().toString(); } return result; } /** * Converts a List to string array, per element * * @param list List the expected list * @return array of strings * *

    Example: *
  • toStrings(Arrays.toList(new Object[] { 22, false, "wow"})) * returns new String[] {"22", "false", "wow"}.
  • * */ public static String[] toStrings(List list) { String[] result = new String[list.size()]; for (int i = 0; i < list.size(); i++) { result[i] = list.get(i).toString(); } return result; } /** * Converts a Collection to string array, per element * * @param collection Collection the expected collection * @return array of strings * *

    Example: *
  • toStrings(Arrays.asList(22, false, "wow")) * returns new String[] {"22", "false", "wow"}.
  • * */ public static String[] toStrings(Collection collection) { String[] result = new String[collection.size()]; int i = 0; for (Object element : collection) { result[i++] = element.toString(); } return result; } /** * Converts an array to string array, per element * * @param array Object[] the expected array * @return array of strings, or null if input is not what expected * *

    Example: *
  • toStrings(new Object[] { new Integer(22), new Boolean(false), "wow"}) * returns new String[] {"22", "false", "wow"}.
  • * */ public static String[] toStrings(Object[] array) { String[] result = new String[array.length]; for (int i = 0; i < array.length; i++) { result[i] = array[i].toString(); } return result; } /** * Converts an array to string array, per element * * @param object the expected array * @return array of strings, or null if input is not what expected * @deprecated since 5.0; use typed versions * *

    Example: *
  • toStrings(new Object[] { new Integer(22), new Boolean(false), "wow"}) * returns new String[] {"22", "false", "wow"}.
  • * */ public static String[] toStrings(Object object) { if (object == null) return null; if (object instanceof Map) { return toStrings((Map)object); } else if (object instanceof List) { return toStrings((List)object); } else if (object instanceof Collection) { return toStrings((Collection)object); } else if (object instanceof O