/* [The "BSD licence"] Copyright (c) 2003 Terence Parr, jGuru.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.foo.support; import org.foo.lib.html.HTMLUtils; import java.io.*; import java.security.*; import java.util.*; public class Utils { /** Apply a code chunk to every element of a list. I'm sorry but I don't * want to write the bookkeeping for a for-loop etc... when I mean "apply * to list". I must be a SmallTalk guy. ;) The anonymous code block * subclasses needed to use this effectively are uglier but * I'd rather say what I mean! */ public static void applyToList(List list, ListApplicator applicator) { ListIterator iterator = list.listIterator(); while ( iterator.hasNext() ) { Object e = iterator.next(); applicator.apply(e); } } public static List toArrayList(Object[] array) { if ( array==null ) { return null; } List list = new ArrayList(array.length); for (int i = 0; i < array.length; i++) { Object o = array[i]; list.add(i, o); } return list; } public static String[] toStringArray(List list) { if ( list==null || list.size()==0 ) { return null; } String[] r = new String[list.size()]; for (int i = 0; i < list.size(); i++) { String s = (String) list.get(i); r[i] = s; } return r; } /** return a new vector pointing to same elements as v from * index start to end inclusive. Index 0 in new vector * contains element v.elementAt(start). */ public static Vector subvector(Vector v, int start, int end) { if ( v==null || v.size()==0 || start<0 || end<0 || start>end || start>=v.size() ) { return null; } if ( end>=v.size() ) { end = v.size()-1; // prune to end if necessary } Vector subv = new Vector(end-start+1); for (int i = start; i <= end; i++) { Object o = (Object) v.elementAt(i); subv.addElement(o); } return subv; } public static int string2int(String str, int defaultVal) { int intval = defaultVal; try { intval = Integer.valueOf(str).intValue(); } catch (NumberFormatException nfe) { } return intval; } public static String array2str(Object[] array) { StringBuffer buff = new StringBuffer(200); buff.append("["); for(int i = 0; i < array.length; i++) { buff.append(array[i].toString()); if(i < array.length - 1) buff.append(", "); } buff.append("]"); return buff.toString(); } /** convert an array to a comma-delimited list, w/o any ['s */ public static String array2Paramstr(Object[] array) { StringBuffer buff = new StringBuffer(200); for(int i = 0; i < array.length; i++) { buff.append(array[i].toString()); if(i < array.length - 1) buff.append(", "); } return buff.toString(); } public static String printStackTrace(Throwable t) { if ( t==null ) { return ""; } CharArrayWriter caw = new CharArrayWriter(1000); PrintWriter writer = new PrintWriter(caw,true); t.printStackTrace(writer); return caw.toString(); } /** Capitalize a word; e.g., "article"->"Article" */ public static String capitalize(String word) { if ( word==null ) { return null; } if ( word.length()==1 ) { return String.valueOf(Character.toUpperCase(word.charAt(0))); } return Character.toUpperCase(word.charAt(0))+ word.substring(1,word.length()); } /** Given a source string, src, a string to replace, replacee, and a string to replace with, replacer, return a new string w/ the replacing done. This replacement is now case insensitive. You can use replacer==null to remove replacee from the string. */ public static String replace(String src, String replacee, String replacer) { StringBuffer result = new StringBuffer(src.length() + 50); int startIndex = 0; int endIndex = indexOfTextIgnoreCase(src, replacee); while(endIndex != -1) { result.append(src.substring(startIndex,endIndex)); if ( replacer!=null ) { result.append(replacer); } startIndex = endIndex + replacee.length(); endIndex = indexOfTextIgnoreCase(src, replacee,startIndex); } result.append(src.substring(startIndex,src.length())); return result.toString(); } public static String[] splitIntoLines(StringBuffer contents) { return splitIntoLines(contents.toString()); } public static String[] splitIntoLines(String contents) { if ( contents==null ) { return null; } List lines = new LinkedList(); try { StringReader sr = new StringReader(contents); BufferedReader br = new BufferedReader(sr); String line = br.readLine(); while ( line!=null ) { lines.add(line); line = br.readLine(); } br.close(); } catch (IOException ioe) { // can't be called since strings aren't doing IO // better print a warning anyhoo System.err.println("error in splitIntoLines: "+ioe); } return toStringArray(lines); } /** Find the first occurrence of t in src beginning at index 0 */ public static int indexOfTextIgnoreCase(String src, String t) { return indexOfTextIgnoreCase(src, t, 0); } /** Find the first occurrence of t in src beginning at index offset */ public static int indexOfTextIgnoreCase(String src, String t, int offset) { if(src.length() == 0 || t.length() == 0) { return -1; } if ( offset>=src.length() ) { return -1; } int tIndex=0; int srcIndex=offset; char tCh = Character.toLowerCase( t.charAt(0) ); do { char ch = Character.toLowerCase( src.charAt(srcIndex) ); if (tCh==ch) { if ( (srcIndex+t.length()) > src.length() ) { // current index plus length of t is bigger than src return -1; } if ( src.substring(srcIndex,srcIndex+t.length()) .equalsIgnoreCase( t ) ) { return srcIndex; } } srcIndex++; } while (srcIndex < src.length()); return -1; } /** Shorten a string, that may contain HTML, into a "safe" version. It processes the string like this: -- strip HTML tags -- shortens the string and appends "..." (if necessary) It tries to chop the string at a space, use the margin arg to give it a chance to find one. The result string will be at most length+margin+3 chars long. */ public static String abbrevString(String s, int length, int margin) { String result = HTMLUtils.stripHTML(s); if(result.length() < length) return HTMLUtils.stripHTML(result); int index = result.indexOf(" ", length); if(index == -1 || index > (length + margin)) { result = result.substring(0,length); } else { result = result.substring(0,index); } return result+"..."; } public static String stripPunct(String text) { StringBuffer buf = new StringBuffer(); int i = 0; while ( i < text.length() ) { if ( Character.isLetterOrDigit(text.charAt(i)) || Character.isWhitespace(text.charAt(i)) ) { buf.append(text.charAt(i)); } i++; } return buf.toString(); } /** Do a simple normalization: lowercase hostname and remove trailing '/' * if no GET parameters. Basically, have URL object pull string apart * and then rebuild the way we want. */ public static String getNormalizedURL(String url) throws java.net.MalformedURLException { // Allow news protocol to pass this method. if (url.startsWith("news://")) { return url; } java.net.URL u = new java.net.URL(url); StringBuffer result = new StringBuffer(100); result.append(u.getProtocol()); result.append(":"); String host = u.getHost().toLowerCase(); int port = u.getPort(); String anchor = u.getRef(); String file = u.getFile(); if ( host!=null && host.length()>0 ) { result.append("//"); result.append(host); if ( port != -1 ) { result.append(":"); result.append(port); } } if ( file.endsWith("/") ) { result.append(file.substring(0,file.length()-1)); } else { result.append(file); } if ( anchor!=null ) { result.append("#"); result.append(anchor); } return result.toString(); } /** Compute a unique "one-way" hash code for a bunch of text. * See http://java.sun.com/products/jdk/1.1/docs/api/ * java.security.MessageDigest.html * For more info. Code examples pointed to from getInstance() * method. */ public static String computeHash(String message) { // Get hash code generator MessageDigest md = null; try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException nsae) { System.err.println("no MD5 algorithm!!!!!!!"); return null; } // get message into a Byte array byte[] messageInBytes = new byte[message.length()]; for (int i=0; i= 0) ? digest[i] : (digest[i]+256); int hi = b >> 8; // shift upper 8 into lower 8 shift in 0's int lo = b & 0x0F; // lop off top byte String chi = Integer.toHexString(hi); String clo = Integer.toHexString(lo); buf.append(chi); buf.append(clo); } if ( buf.length()==0 ) { return null; } return buf.toString(); } /** Change a url parameter to a new value. Append if parameter does not * exist in the URL. If value is null, delete the parameter from the url. */ public static String replaceURLParameter(String url, String parameter, String value) { if ( url.indexOf("?")<0 ) { // no args if ( value!=null ) { // add to end return url+"?"+parameter+"="+value; } return url; } int begin = url.indexOf(parameter+"="); if ( begin<0 ) { // no parameter, append if ( value==null ) { // nothing to remove return url; } if ( url.indexOf('?')<0 ) { return url+"?"+parameter+"="+value; } return url+"&"+parameter+"="+value; } int end = begin+(parameter+"=").length(); // find end of parameter while ( end