/* * 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 . * * 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 , * 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 null. * @return The SQL-encoded equivalent of str. If str is * null, returns null. */ 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 null. * @return The HTML-encoded equivalent of str. If str is * null, returns null. */ 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 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 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:

* 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 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 * ${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 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=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