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
382 lines
12 KiB
Java
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 <erbo@users.sf.net>
|
|
* @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 ("),
|
|
* 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 <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(""");
|
|
break;
|
|
|
|
case '&':
|
|
buf.append("&");
|
|
break;
|
|
|
|
case '<':
|
|
buf.append("<");
|
|
break;
|
|
|
|
case '>':
|
|
buf.append(">");
|
|
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("blahdeeblah","blah","hoo")</CODE>
|
|
* returns <CODE>"hoodeehoo"</CODE><BR>
|
|
* <CODE>replaceAllInstances("blahdeebleh","blah","hoo")</CODE>
|
|
* returns <CODE>"hoodeebleh"</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
|