String.indexOf(char)
, but using
+ * multiple characters. It locates the first instance within a string of any of
+ * the specified characters.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ * @see java.lang.String#indexOf(char)
+ * @see java.lang.String#lastIndexOf(char)
+ */
public final class AnyCharMatcher
{
/*--------------------------------------------------------------------------------
@@ -32,6 +42,11 @@ public final class AnyCharMatcher
*--------------------------------------------------------------------------------
*/
+ /**
+ * Creates a new character matcher that matches the specified characters.
+ *
+ * @param charset The set of characters to be matched by this object, expressed as a character array.
+ */
public AnyCharMatcher(char[] charset)
{
this.charset = charset;
@@ -39,6 +54,11 @@ public final class AnyCharMatcher
} // end constructor
+ /**
+ * Creates a new character matcher that matches the specified characters.
+ *
+ * @param charset The set of characters to be matched by this object, expressed as a string.
+ */
public AnyCharMatcher(String charset)
{
this.charset = charset.toCharArray();
@@ -51,8 +71,20 @@ public final class AnyCharMatcher
*--------------------------------------------------------------------------------
*/
+ /**
+ * Returns the offset within the string of the first instance of any character in this
+ * character set.
+ *
+ * @param str The string to look through. If this parameter is null
,
+ * the method returns -1.
+ * @return The 0-based index of the first instance of any character from this character
+ * matcher within str
. If str
contains no instances of
+ * any character from this character matcher, -1 is returned.
+ */
public final int get(String str)
{
+ if (str==null)
+ return -1;
int numindexes = 0;
int i;
for (i=0; inull
,
+ * the method returns -1.
+ * @return The 0-based index of the last instance of any character from this character
+ * matcher within str
. If str
contains no instances of
+ * any character from this character matcher, -1 is returned.
+ */
+ public final int getLast(String str)
+ {
+ if (str==null)
+ return -1;
+
+ int numindexes = 0;
+ int i;
+ for (i=0; i
+ * Some of the concepts in this class have been borrowed from Apache Jakarta Avalon Excalibur 4.0.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
public class IOUtil
{
/*--------------------------------------------------------------------------------
@@ -28,6 +33,9 @@ public class IOUtil
*--------------------------------------------------------------------------------
*/
+ /**
+ * The default buffer size to use for copying, if none is specified.
+ */
public static int DEFAULT_BUFSIZE = 4096;
/*--------------------------------------------------------------------------------
@@ -35,6 +43,11 @@ public class IOUtil
*--------------------------------------------------------------------------------
*/
+ /**
+ * Closes an input stream cleanly, without throwing an exception.
+ *
+ * @param stm The stream to be closed.
+ */
public static void shutdown(InputStream stm)
{
try
@@ -48,6 +61,11 @@ public class IOUtil
} // end shutdown
+ /**
+ * Closes an output stream cleanly, without throwing an exception.
+ *
+ * @param stm The stream to be closed.
+ */
public static void shutdown(OutputStream stm)
{
try
@@ -61,6 +79,11 @@ public class IOUtil
} // end shutdown
+ /**
+ * Closes an input reader cleanly, without throwing an exception.
+ *
+ * @param stm The stream to be closed.
+ */
public static void shutdown(Reader rdr)
{
try
@@ -74,6 +97,11 @@ public class IOUtil
} // end shutdown
+ /**
+ * Closes an output reader cleanly, without throwing an exception.
+ *
+ * @param stm The stream to be closed.
+ */
public static void shutdown(Writer wr)
{
try
@@ -87,6 +115,14 @@ public class IOUtil
} // end shutdown
+ /**
+ * Copies the contents of the given input stream to the given output stream.
+ *
+ * @param input The stream to copy binary data from.
+ * @param output The stream to copy binary data to.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @exception java.io.IOException If an exception occurred while reading or writing data.
+ */
public static void copy(InputStream input, OutputStream output, int bufsize) throws IOException
{
byte[] buffer = new byte[bufsize];
@@ -101,12 +137,113 @@ public class IOUtil
} // end copy
+ /**
+ * Copies the contents of the given input stream to the given output stream. Uses a default
+ * buffer size.
+ *
+ * @param input The stream to copy binary data from.
+ * @param output The stream to copy binary data to.
+ * @exception java.io.IOException If an exception occurred while reading or writing data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #copy(java.io.InputStream,java.io.OutputStream,int)
+ */
public static void copy(InputStream input, OutputStream output) throws IOException
{
copy(input,output,DEFAULT_BUFSIZE);
} // end copy
+ /**
+ * Takes the contents of an input stream and returns it as an array of bytes.
+ *
+ * @param input The stream to load binary data from.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @return A new byte array containing the contents of the specified input stream.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #copy(java.io.InputStream,java.io.OutputStream,int)
+ */
+ public static byte[] load(InputStream input, int bufsize) throws IOException
+ {
+ ByteArrayOutputStream stm = new ByteArrayOutputStream();
+ try
+ { // copy the data to the input stream
+ copy(input,stm,bufsize);
+ return stm.toByteArray();
+
+ } // end try
+ finally
+ { // close our byte array stream before we go
+ shutdown(stm);
+
+ } // end finally
+
+ } // end load
+
+ /**
+ * Takes the contents of an input stream and returns it as an array of bytes. Uses a default
+ * buffer size.
+ *
+ * @param input The stream to load binary data from.
+ * @return A new byte array containing the contents of the specified input stream.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #load(java.io.InputStream,int)
+ */
+ public static byte[] load(InputStream input) throws IOException
+ {
+ return load(input,DEFAULT_BUFSIZE);
+
+ } // end load
+
+ /**
+ * Takes the contents of a binary file and returns it as an array of bytes.
+ *
+ * @param file The file to load binary data from.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @return A new byte array containing the contents of the specified file.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #load(java.io.InputStream,int)
+ */
+ public static byte[] loadBinary(File file, int bufsize) throws IOException
+ {
+ FileInputStream stm = new FileInputStream(file);
+ try
+ { // now just load from the stream
+ return load(stm,bufsize);
+
+ } // end try
+ finally
+ { // close the file before we leave
+ shutdown(stm);
+
+ } // end finally
+
+ } // end loadBinary
+
+ /**
+ * Takes the contents of a binary file and returns it as an array of bytes. Uses a default
+ * buffer size.
+ *
+ * @param file The file to load binary data from.
+ * @return A new byte array containing the contents of the specified file.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #loadBinary(java.io.File,int)
+ */
+ public static byte[] loadBinary(File file) throws IOException
+ {
+ return loadBinary(file,DEFAULT_BUFSIZE);
+
+ } // end loadBinary
+
+ /**
+ * Copies the contents of the given input reader to the given output writer.
+ *
+ * @param input The reader to copy character data from.
+ * @param output The writer to copy character data to.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @exception java.io.IOException If an exception occurred while reading or writing data.
+ */
public static void copy(Reader input, Writer output, int bufsize) throws IOException
{
char[] buffer = new char[bufsize];
@@ -121,12 +258,31 @@ public class IOUtil
} // end copy
+ /**
+ * Copies the contents of the given input reader to the given output writer. Uses a default
+ * buffer size.
+ *
+ * @param input The reader to copy character data from.
+ * @param output The writer to copy character data to.
+ * @exception java.io.IOException If an exception occurred while reading or writing data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #copy(java.io.Reader,java.io.Writer,int)
+ */
public static void copy(Reader input, Writer output) throws IOException
{
copy(input,output,DEFAULT_BUFSIZE);
} // end copy
+ /**
+ * Takes the contents of an input reader and returns it as a StringBuffer
.
+ *
+ * @param input The reader to copy character data from.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @return A new StringBuffer
containing the contents of the specified reader.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #copy(java.io.Reader,java.io.Writer,int)
+ */
public static StringBuffer load(Reader input, int bufsize) throws IOException
{
StringWriter wr = new StringWriter();
@@ -144,13 +300,32 @@ public class IOUtil
} // end load
+ /**
+ * Takes the contents of an input reader and returns it as a StringBuffer
. Uses a
+ * default buffer size.
+ *
+ * @param input The reader to copy character data from.
+ * @return A new StringBuffer
containing the contents of the specified reader.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #load(java.io.Reader,int)
+ */
public static StringBuffer load(Reader input) throws IOException
{
return load(input,DEFAULT_BUFSIZE);
} // end load
- public static StringBuffer load(File file, int bufsize) throws IOException
+ /**
+ * Takes the contents of a text file and returns it as a StringBuffer
.
+ *
+ * @param file The file to copy text from.
+ * @param bufsize The size of the buffer to allocate for copying.
+ * @return A new StringBuffer
containing the contents of the specified text file.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #load(java.io.Reader,int)
+ */
+ public static StringBuffer loadText(File file, int bufsize) throws IOException
{
FileReader rdr = new FileReader(file);
try
@@ -166,9 +341,18 @@ public class IOUtil
} // end load
- public static StringBuffer load(File file) throws IOException
+ /**
+ * Takes the contents of a text file and returns it as a StringBuffer
.
+ *
+ * @param file The file to copy text from.
+ * @return A new StringBuffer
containing the contents of the specified text file.
+ * @exception java.io.IOException If an exception occurred while reading data.
+ * @see #DEFAULT_BUFSIZE
+ * @see #loadText(java.io.File,int)
+ */
+ public static StringBuffer loadText(File file) throws IOException
{
- return load(file,DEFAULT_BUFSIZE);
+ return loadText(file,DEFAULT_BUFSIZE);
} // end load
diff --git a/src/com/silverwrist/util/ServletMultipartHandler.java b/src/com/silverwrist/util/ServletMultipartHandler.java
index 4862389..d0e631f 100644
--- a/src/com/silverwrist/util/ServletMultipartHandler.java
+++ b/src/com/silverwrist/util/ServletMultipartHandler.java
@@ -84,8 +84,6 @@ public class ServletMultipartHandler
static class MultipartDataValue implements Blob
{
- private static final int BLKSIZE = 4096;
-
private byte[] actual_data; // the actual data we contain
public MultipartDataValue(MimeBodyPart part) throws MessagingException, IOException
@@ -93,26 +91,8 @@ public class ServletMultipartHandler
if (logger.isDebugEnabled())
logger.debug("creating new MultipartDataValue");
- // set up the streams to copy between
- InputStream in = part.getInputStream();
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- byte[] copybuf = new byte[BLKSIZE];
-
- // begin the copy loop
- int ct = in.read(copybuf,0,BLKSIZE);
- while (ct>=0)
- { // do a simple read and write
- if (logger.isDebugEnabled())
- logger.debug("read blksize = " + ct);
- if (ct>0)
- out.write(copybuf,0,ct);
- ct = in.read(copybuf,0,BLKSIZE);
-
- } // end while
-
- in.close();
- actual_data = out.toByteArray();
- out.close();
+ // load actual data
+ actual_data = IOUtil.load(part.getInputStream());
if (logger.isDebugEnabled())
logger.debug("finished copying, " + actual_data.length + " bytes transferred");
diff --git a/src/com/silverwrist/util/StringUtil.java b/src/com/silverwrist/util/StringUtil.java
index 583421d..5b4cc9c 100644
--- a/src/com/silverwrist/util/StringUtil.java
+++ b/src/com/silverwrist/util/StringUtil.java
@@ -19,6 +19,12 @@ package com.silverwrist.util;
import java.util.*;
+/**
+ * A collection of string-related static methods which are useful in various contexts.
+ *
+ * @author Eric J. Bowersox <erbo@silcom.com>
+ * @version X
+ */
public class StringUtil
{
/*--------------------------------------------------------------------------------
@@ -35,10 +41,18 @@ public class StringUtil
*--------------------------------------------------------------------------------
*/
+ /**
+ * Performs SQL encoding of an arbitrary string. When a string is SQL-encoded, all single-quote
+ * characters are doubled, and all other characters are left untouched.
+ *
+ * @param str The string to be SQL-encoded. May be null
.
+ * @return The SQL-encoded equivalent of str
. If str
is
+ * null
, returns null
.
+ */
public static String encodeStringSQL(String str)
{
if (str==null)
- return null;
+ return null; // safety feature
int ndx = str.indexOf('\'');
if (ndx<0)
return str;
@@ -58,10 +72,19 @@ public class StringUtil
} // end encodeStringSQL
+ /**
+ * Performs HTML encoding of an arbitrary string. When a string is HTML encoded, the double-quote ("),
+ * ampersand (&), less-than (<), and greater-than (>) characters are transformed to their HTML
+ * entity equivalents; all other characters are left untouched.
+ *
+ * @param str The string to be HTML-encoded. May be null
.
+ * @return The HTML-encoded equivalent of str
. If str
is
+ * null
, returns null
.
+ */
public static String encodeHTML(String str)
{
if (str==null)
- return null;
+ return null; // safety feature
AnyCharMatcher nhc = new AnyCharMatcher(HTML_ENCODE_CHARS);
int ndx = nhc.get(str);
if (ndx<0)
@@ -103,46 +126,92 @@ public class StringUtil
} // end encodeHTML
+ /**
+ * Returns true
if the given string is null
or a string of
+ * length 0, false
otherwise.
+ *
+ * @param s The string to be tested.
+ * @return true
if the given string is null
or a string of
+ * length 0, false
otherwise.
+ */
public static boolean isStringEmpty(String s)
{
return ((s==null) || (s.length()==0));
} // end isStringEmpty
+ /**
+ * Replaces all instances of a particular substring within a string with another substring.
+ * For example:
+ * replaceAllInstances("blahdeeblah","blah","hoo")
+ * returns "hoodeehoo"
+ * replaceAllInstances("blahdeebleh","blah","hoo")
+ * returns "hoodeebleh"
+ *
+ * @param base The string to be operated on. If this parameter is null
, the
+ * method will return null
.
+ * @param find The substring to find in the base
string. If this parameter is
+ * null
or an empty string, no replacing will be done.
+ * @param replace The substring to replace instances of the find
string with in the
+ * base
string. If this parameter is null
, instances
+ * of the find
string will be deleted.
+ * @return The base
string with all replacements made as detailed above.
+ */
public static String replaceAllInstances(String base, String find, String replace)
{
- String work = base;
- int ndx = work.indexOf(find);
+ if ((base==null) || isStringEmpty(find))
+ return base; // safety feature
+ int ndx = base.indexOf(find);
if (ndx<0)
- return work; // trivial case
+ return base; // trivial case
StringBuffer b = new StringBuffer();
while (ndx>=0)
{ // break off the first part of the string, then insert the replacement
if (ndx>0)
- b.append(work.substring(0,ndx));
- b.append(replace);
+ b.append(base.substring(0,ndx));
+ if (replace!=null)
+ b.append(replace);
// break off the tail end
ndx += find.length();
- if (ndx==work.length())
+ if (ndx==base.length())
return b.toString(); // entire string munched - we're done!
- work = work.substring(ndx);
- ndx = work.indexOf(find);
+ base = base.substring(ndx);
+ ndx = base.indexOf(find);
} // end while
- // append the unmatched "tail" of the work string and then return result
- b.append(work);
+ // append the unmatched "tail" of the string and then return result
+ b.append(base);
return b.toString();
} // end replaceAllInstances
+ /**
+ * Replaces variable substitutions in a string. Variable substitutions are strings of the form
+ * ${varname}
. The varname names are looked up in the supplied
+ * Map
, and the values of variables in that map are substituted.
+ * Only variable names that exist in the Map
are replaced; other variable strings
+ * in the supplied string are left untouched. Variable substitution values may themselves contain
+ * variables; those variables are recursively replaced. (Caution: The code cannot
+ * detect variable substitutions that contain themselves, or two variables that contain each other.
+ * Avoid these situations.)
+ *
+ * @param base The string to be operated on. If this parameter is null
, the
+ * method will return null
.
+ * @param vars The mapping of variable name to value substitutions. If this parameter is
+ * null
or an empty map, no substitutions will be performed on
+ * base
.
+ * @return The base
string with all variable substitutions made as detailed above.
+ */
public static String replaceAllVariables(String base, Map vars)
{
- String work = base;
- boolean did_replace, retest;
+ if ((base==null) || (vars==null) || (vars.size()==0))
+ return base; // safety feature
- retest = true;
+ String work = base;
+ boolean did_replace;
+ boolean retest = true;
do
{ // main loop for replacing all variables
did_replace = false;
diff --git a/src/com/silverwrist/util/package.html b/src/com/silverwrist/util/package.html
new file mode 100644
index 0000000..1cc2c7d
--- /dev/null
+++ b/src/com/silverwrist/util/package.html
@@ -0,0 +1,27 @@
+
+
+
+