// Copyright (c) 1999 Dustin Sallings <dustin@spy.net> package net.spy.util; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.SecureRandom; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.StringTokenizer; import net.spy.log.LoggerFactory; /** * Miscellaneous utilities. */ public class SpyUtil { // Do not instantiate private SpyUtil() { super(); } /** * Shuffle (unsort) an array. * * @param in The array of objects to shuffle. */ public static Object[] shuffle(Object in[]) { Object tmp; Object[] ret = new Object[in.length]; System.arraycopy(in, 0, ret, 0, in.length); SecureRandom r = new SecureRandom(); int i; for(i=0; i<ret.length; i++) { // Get a random number the size of the length int n = r.nextInt(); if(n<0) { n=-n; } n=n%ret.length; tmp=ret[i]; ret[i]=ret[n]; ret[n]=tmp; } return(ret); } /** * Split a string based on a tokenizer. * * @param on the string to split on (from StringTokenizer) * * @param input the string that needs to be split * * @see StringTokenizer */ public static String[] split(String on, String input) { StringTokenizer st = new StringTokenizer(input, on); String[] ret=new String[st.countTokens()]; int i=0; while(st.hasMoreTokens()) { ret[i++]=st.nextToken(); } return(ret); } /** * Load the contents of the given reader as a String. * * @param r a reader * @return a String with the contents of the reader */ public static String getReaderAsString(Reader r) throws IOException { char[] c=new char[8192]; StringBuilder rv=new StringBuilder(8192); int size; while((size=r.read(c)) >=0) { String tmp = new String(c); // Substring to get rid of all the damned nulls rv.append(tmp.substring(0, size)); } return(rv.toString()); } /** * Return the contents of a file as a string. * * @param file File to read. * * @exception IOException Thrown if the file cannot be opened. */ public static String getFileData(File file) throws IOException { FileReader f = new FileReader(file); String rv=null; try { rv=getReaderAsString(f); } finally { CloseUtil.close(f); } return(rv); } /** * Join an Enumeration of Strings on a join string. * @param e The enumeration * @param on the join string * @return a new String with all of the elements joined */ public static <T> String join(Enumeration<T> e, String on) { return(join(new Enumeriterator<T>(e), on)); } /** * Join an Iterator of Objects on a join string. Each object's * toString() method will be used for stringification. * * @param i the iterator of Objects * @param on the join string * @return a new String with all of the elements joined */ public static String join(Iterator<?> i, String on) { StringBuilder sb=new StringBuilder(256); while(i.hasNext()) { Object o=i.next(); sb.append(o); if(i.hasNext()) { sb.append(on); } } return(sb.toString()); } /** * Join a Collection of Objects on a join string. Each object's * toString() method will be used for stringification. * * @param c the collection * @param on the join string * @return a String with all the elements joined */ public static String join(Collection<?> c, String on) { return(join(c.iterator(), on)); } /** * Get a string representing the hexidecimal value of the given byte * array. * * @param me the byte array that needs hexified. */ public static String byteAToHexString(byte me[]) { StringBuilder sb=new StringBuilder(me.length*2); for(byte b : me) { int bai=b & 0xff; if(bai<0x10) { sb.append('0'); } sb.append(Integer.toHexString(bai)); } return(sb.toString()); } /** * Class invoker (runs main(String[]) from a String array. */ public static void runClass(String classname, String args[]) throws Exception { // If no classloader is given, use the classloader that loaded this // class. runClass(SpyUtil.class.getClassLoader(), classname, args); } /** * Class invoker (runs main(String[]) from a String array. */ public static void runClass(ClassLoader cl, String classname, String args[]) throws Exception { // Load the class. Class<?> tclass=Class.forName(classname, true, cl); // Find the method Class<?>[] paramtypes = new Class[1]; String[] tmp=new String[0]; paramtypes[0]=tmp.getClass(); Method m = tclass.getMethod("main", paramtypes); // Set the arguments. Object[] params=new Object[1]; params[0]=args; // Run it! try { m.invoke(tclass, params); } catch(InvocationTargetException ite) { ite.printStackTrace(); Throwable t=ite.getTargetException(); if(t instanceof Exception) { throw (Exception)t; } else { t.printStackTrace(); } } } /** * Returns a Boolean with a value represented by the specified String. * The Boolean returned represents the value true if the string * argument is not null and is equal, ignoring case, to the string * "true". * * @param s the string * @return the Boolean instance */ public static Boolean getBoolean(String s) { Boolean rv=Boolean.FALSE; if(s != null && s.equalsIgnoreCase("true")) { rv=Boolean.TRUE; } return(rv); } /** * Remove HTML tags from a string. * * @param contents the string whose HTML tags need removed. * @return the deHTMLed string */ public static String deHTML(String contents) { int inTag=0; StringBuilder sb=new StringBuilder(contents.length()); char[] chars=contents.toCharArray(); for(char c : chars) { if(c == '<') { inTag++; } else if( c == '>' && inTag>0) { if(inTag>=1) { inTag--; } } else { if(inTag==0) { sb.append(c); } } } return(sb.toString()); } /** * Recursively remove a path. */ public static void rmDashR(File tmp) { File[] f=tmp.listFiles(); if(f!=null) { for(int i=0; i<f.length; i++) { if(f[i].isDirectory()) { rmDashR(f[i]); } else { if(!f[i].delete()) { LoggerFactory.getLogger(SpyUtil.class).warn( "Couldn't delete " + f[i]); } } } } if(!tmp.delete()) { LoggerFactory.getLogger(SpyUtil.class).warn( "Couldn't delete " + tmp); } } }