Eric J. Bowersox 99f9d580f4 code now clean compiles using newer versions of various libraries - this will
all get documented properly soon, need to update this for the new server...
also changed all the E-mail addresses in the old java source to match present
reality
2006-01-25 08:13:41 +00:00

382 lines
12 KiB
Java

/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@users.sf.net>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.util;
import java.util.*;
/**
* A collection of string-related static methods which are useful in various contexts.
*
* @author Eric J. Bowersox &lt;erbo@users.sf.net&gt;
* @version X
*/
public class StringUtil
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final String VAR_START = "${";
private static final String VAR_END = "}";
private static final char[] HTML_ENCODE_CHARS = { '"', '&', '<', '>' };
private static final Set TRUE_STRINGS;
private static final Set FALSE_STRINGS;
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
*/
/**
* 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 <B><CODE>null</CODE></B>.
* @return The SQL-encoded equivalent of <CODE>str</CODE>. If <CODE>str</CODE> is
* <B><CODE>null</CODE></B>, returns <B><CODE>null</CODE></B>.
*/
public static final String encodeStringSQL(String str)
{
if (str==null)
return null; // safety feature
int ndx = str.indexOf('\'');
if (ndx<0)
return str;
StringBuffer buf = new StringBuffer();
while (ndx>=0)
{ // convert each single quote mark to a pair of them
if (ndx>0)
buf.append(str.substring(0,ndx));
buf.append("''");
str = str.substring(ndx+1);
ndx = str.indexOf('\'');
} // end while
buf.append(str);
return buf.toString();
} // end encodeStringSQL
/**
* Performs HTML encoding of an arbitrary string. When a string is HTML encoded, the double-quote (&quot;),
* ampersand (&amp;), less-than (&lt;), and greater-than (&gt;) characters are transformed to their HTML
* entity equivalents; all other characters are left untouched.
*
* @param str The string to be HTML-encoded. May be <B><CODE>null</CODE></B>.
* @return The HTML-encoded equivalent of <CODE>str</CODE>. If <CODE>str</CODE> is
* <B><CODE>null</CODE></B>, returns <B><CODE>null</CODE></B>.
*/
public static final String encodeHTML(String str)
{
if (str==null)
return null; // safety feature
AnyCharMatcher nhc = new AnyCharMatcher(HTML_ENCODE_CHARS);
int ndx = nhc.get(str);
if (ndx<0)
return str; // trivial short-circuit case
StringBuffer buf = new StringBuffer();
while (ndx>=0)
{ // append the matched "head" and then the encoded character
if (ndx>0)
buf.append(str.substring(0,ndx));
switch (str.charAt(ndx++))
{
case '"':
buf.append("&quot;");
break;
case '&':
buf.append("&amp;");
break;
case '<':
buf.append("&lt;");
break;
case '>':
buf.append("&gt;");
break;
} // end switch
if (ndx==str.length())
return buf.toString(); // munched the entire string - all done!
str = str.substring(ndx);
ndx = nhc.get(str);
} // end while
buf.append(str); // append the unmatched tail
return buf.toString();
} // end encodeHTML
/**
* Returns <B><CODE>true</CODE></B> if the given string is <B><CODE>null</CODE></B> or a string of
* length 0, <B><CODE>false</CODE></B> otherwise.
*
* @param s The string to be tested.
* @return <B><CODE>true</CODE></B> if the given string is <B><CODE>null</CODE></B> or a string of
* length 0, <B><CODE>false</CODE></B> otherwise.
*/
public static final 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:<P>
* <CODE>replaceAllInstances(&quot;blahdeeblah&quot;,&quot;blah&quot;,&quot;hoo&quot;)</CODE>
* returns <CODE>&quot;hoodeehoo&quot;</CODE><BR>
* <CODE>replaceAllInstances(&quot;blahdeebleh&quot;,&quot;blah&quot;,&quot;hoo&quot;)</CODE>
* returns <CODE>&quot;hoodeebleh&quot;</CODE>
*
* @param base The string to be operated on. If this parameter is <B><CODE>null</CODE></B>, the
* method will return <B><CODE>null</CODE></B>.
* @param find The substring to find in the <CODE>base</CODE> string. If this parameter is
* <B><CODE>null</CODE></B> or an empty string, no replacing will be done.
* @param replace The substring to replace instances of the <CODE>find</CODE> string with in the
* <CODE>base</CODE> string. If this parameter is <B><CODE>null</CODE></B>, instances
* of the <CODE>find</CODE> string will be deleted.
* @return The <CODE>base</CODE> string with all replacements made as detailed above.
*/
public static final String replaceAllInstances(String base, String find, String replace)
{
if ((base==null) || isStringEmpty(find))
return base; // safety feature
int ndx = base.indexOf(find);
if (ndx<0)
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(base.substring(0,ndx));
if (replace!=null)
b.append(replace);
// break off the tail end
ndx += find.length();
if (ndx==base.length())
return b.toString(); // entire string munched - we're done!
base = base.substring(ndx);
ndx = base.indexOf(find);
} // end while
// 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
* <CODE>${<EM>varname</EM>}</CODE>. The <EM>varname</EM> names are looked up in the supplied
* <CODE>Map</CODE>, and the values of variables in that map are substituted.<P>
* Only variable names that exist in the <CODE>Map</CODE> are replaced; other variable strings
* in the supplied string are left untouched. Variable substitution values may themselves contain
* variables; those variables are recursively replaced. (<B><EM>Caution:</EM></B> 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 <B><CODE>null</CODE></B>, the
* method will return <B><CODE>null</CODE></B>.
* @param vars The mapping of variable name to value substitutions. If this parameter is
* <B><CODE>null</CODE></B> or an empty map, no substitutions will be performed on
* <CODE>base</CODE>.
* @return The <CODE>base</CODE> string with all variable substitutions made as detailed above.
*/
public static final String replaceAllVariables(String base, Map vars)
{
if ((base==null) || (vars==null) || (vars.size()==0))
return base; // safety feature
String work = base;
boolean did_replace;
boolean retest = true;
do
{ // main loop for replacing all variables
did_replace = false;
Iterator it = vars.keySet().iterator();
while (it.hasNext())
{ // variable start is there...
if (retest)
{ // only perform this test on the first iteration and after we know we've replaced a variable
if (work.indexOf(VAR_START)<0)
return work; // no more variables in text - all done!
retest = false;
} // end if
// get variable name and see if it's present
String vname = it.next().toString();
if (work.indexOf(VAR_START + vname + VAR_END)>=0)
{ // OK, this variable is in place
work = replaceAllInstances(work,VAR_START + vname + VAR_END,vars.get(vname).toString());
did_replace = true;
retest = true;
} // end if
} // end while
} while (did_replace); // end do
return work; // all done!
} // end replaceAllVariables
public static final String join(Object[] arr, String separator)
{
StringBuffer buf = null;
for (int i=0; i<arr.length; i++)
{ // put it all together
if (buf==null)
buf = new StringBuffer(arr[i].toString());
else
buf.append(separator).append(arr[i].toString());
} // end for
return (buf==null) ? null : buf.toString();
} // end join
public static final String join(List l, String separator)
{
StringBuffer buf = null;
Iterator it = l.iterator();
while (it.hasNext())
{ // put it all together
Object o = it.next();
if (buf==null)
buf = new StringBuffer(o.toString());
else
buf.append(separator).append(o.toString());
} // end for
return (buf==null) ? null : buf.toString();
} // end join
public static final List splitList(String data, String delims)
{
if ((data==null) || (delims==null))
return Collections.EMPTY_LIST;
ArrayList rc = new ArrayList();
StringBuffer buf = new StringBuffer();
boolean accumulate = false;
for (int i=0; i<data.length(); i++)
{ // look at each character in turn
char ch = data.charAt(i);
if (delims.indexOf(ch)>=0)
{ // delimiter character - flush the string if we have one
if (accumulate)
{ // flush the buffer
rc.add(buf.toString());
buf.setLength(0);
accumulate = false;
} // end if
} // end if
else
{ // ordinary character - accumulate it
accumulate = true;
buf.append(ch);
} // end else
} // end for
if (accumulate)
rc.add(buf.toString());
if (rc.isEmpty())
return Collections.EMPTY_LIST;
else
return Collections.unmodifiableList(rc);
} // end splitList
public static final String[] splitArray(String data, String delims)
{
List tmp = splitList(data,delims);
return (String[])(tmp.toArray(new String[0]));
} // end splitArray
public static final boolean isBooleanTrue(String test)
{
if (test==null)
return false;
return TRUE_STRINGS.contains(test.trim().toLowerCase());
} // end isBooleanTrue
public static final boolean isBooleanFalse(String test)
{
if (test==null)
return false;
return FALSE_STRINGS.contains(test.trim().toLowerCase());
} // end isBooleanTrue
public static final boolean areEqual(String s1, String s2)
{
if (s1==null)
return (s2==null);
else if (s2==null)
return false;
else
return s1.equals(s2);
} // end areEqual
/*--------------------------------------------------------------------------------
* Static initializer
*--------------------------------------------------------------------------------
*/
static
{ // Initialize the TRUE set.
HashSet tmp = new HashSet();
tmp.add("1");
tmp.add("true");
tmp.add("yes");
tmp.add("on");
TRUE_STRINGS = Collections.unmodifiableSet(tmp);
// Initialize the FALSE set.
tmp = new HashSet();
tmp.add("0");
tmp.add("false");
tmp.add("no");
tmp.add("off");
FALSE_STRINGS = Collections.unmodifiableSet(tmp);
} // end static initializer
} // end class StringUtil