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 * *toBytes(new char[] {0x0123, 0x4567, 0x89ab, 0xcdef})
* returns {0x23, 0x67, (byte)0xab, (byte)0xef}.toChars(new byte[] {0x23, 0x67, (byte)0xab, (byte)0xef})
* returns new char[] {0x23, 0x67, 0xab, 0xef}.crc32(new byte[] {1, 2, 3})
* returns 1438416925.crc32(new byte[] {0, 1, 2, 3, 4}, 1, 3)
* returns 1438416925.toBytes(0x0123456789abcdefl)
* returns {(byte)0xef, (byte)0xcd, (byte)0xab, (byte)0x89, 0x67, 0x45, 0x23, 0x01}.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 * *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".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".splitPath("/home/zaphod/jbuilder8/samples/welcome") returns {"/home/zaphod/jbuilder8/samples", "welcome"};splitPath("src.java") returns {".", "src.java"};splitPath("MyHome\\dev") returns {"MyHome", "dev"}.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".dirname("/home/zaphod/jbuilder11/samples/welcome") returns "/home/zaphod/jbuilder8/samples";dirname("src.java") returns ".";dirname("MyHome\\dev") returns "MyHome".filename("/home/zaphod/jbuilder11/samples/welcome") returns "welcome".find(new File("."), Pattern.compile(".*les\\.java$"))) returns
* Arrays.asList(new String[] {new File("Files.java").getCanonicalPath()}).find(".", Pattern.compile(".*les\\.java$"))) returns
* Arrays.asList(new String[] {"Files.java"}).find(".", ".*les\\.java$") returns
* Arrays.asList(new String[] {"Files.java"}).lastModified(new File("src/com/javatools/util/Objects.java")) returns
* "something".deleteFile("/etc") returns true if the program runs as root.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
*
* readStringFromFile("../src/com/myjavatools/utils/Files.java")
* returns a string starting with "/**\r\n * <p>Title: MyJavaTools: Files handling Tools</p>\r\n*".readStringFromFile("../src/com/myjavatools/utils/Files.java")
* returns a string starting with "/**\r\n * <p>Title: MyJavaTools: Files handling Tools</p>\r\n*".readBytesFromStream(new ByteArrayInputStream(new byte[] {1, 2, 3, 4, 5}))
* returns new byte[] {1, 2, 3, 4, 5}.readBytesFromFile("../src/com/myjavatools/utils/Files.java")
* returns a byte array starting with {51, 50, 50, 13, 10, 32, 50}.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.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")copy(new File(myHomeDir, "dev"), new File(myHomeDir, "rtm"), "contents.xml")copy("c:\\home\\vlad\\dev\\contents.xml", "c:\\home\\vlad\\rtm\\contents.rss")copy(new File(myHomeDir, "contents.xml"), new File(mySite, "contents.rss")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()) {
Setcopy(new File(myHomeDir, "contents.xml"), new File(mySite, "contents.rss");
* compare(new File(myHomeDir, "contents.xml"), new File(mySite, "contents.rss") returns -1
* 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 " ".
*/
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 "悫" (that is, Numeric Character Reference);
* sgmlEntity('<') returns "<" (that is, Predefined Entity);
* sgmlEntity('&') returns "<" (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 "<i>Feliz A¤o Nuevo</i>\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¤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