package jadex.commons; import jadex.commons.collection.SCollection; import java.awt.Color; import java.awt.Font; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.lang.reflect.Array; import java.net.JarURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Random; import java.util.Set; import java.util.StringTokenizer; import java.util.UUID; import java.util.Vector; import java.util.jar.JarFile; /** * This class provides several useful static util methods. */ public class SUtil { /** Constant that indicates a conversion of all known characters. */ public static final int CONVERT_ALL = 1; /** Constant that indicates a conversion of all known characters except &. */ public static final int CONVERT_ALL_EXCEPT_AMP = 2; /** Constant that indicates a conversion of no characters. */ public static final int CONVERT_NONE = 3; /** A Null value. */ public static final String NULL = "NULL"; /** * Mapping from single characters to encoded version for displaying on * xml-style interfaces. */ protected static Map htmlwraps; /** Holds the single characters. */ protected static String seps; /** An empty enumeration. */ public static final Enumeration EMPTY_ENUMERATION = new Enumeration() { public boolean hasMoreElements() { return false; } public Object nextElement() { return null; } }; /** An empty string array. */ public static final String[] EMPTY_STRING_ARRAY = new String[0]; /** An empty class array. */ public static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; static { htmlwraps = new Hashtable(); htmlwraps.put("\"", """); htmlwraps.put("&", "&"); // Hmm??? htmlwraps.put("'", "'"); htmlwraps.put("<", "<"); htmlwraps.put(">", ">"); htmlwraps.put("�", "ä"); htmlwraps.put("�", "Ä"); htmlwraps.put("�", "ü"); htmlwraps.put("�", "Ü"); htmlwraps.put("�", "ö"); htmlwraps.put("�", "Ö"); htmlwraps.put("�", "´"); htmlwraps.put("�", "à"); htmlwraps.put("�", "å"); htmlwraps.put("�", "â"); htmlwraps.put("�", "&Acute;"); htmlwraps.put("�", "À"); htmlwraps.put("�", "Å"); htmlwraps.put("�", "Â"); htmlwraps.put("�", "&ecute;"); htmlwraps.put("�", "è"); htmlwraps.put("�", "ê"); htmlwraps.put("�", "&Ecute;"); htmlwraps.put("�", "È"); htmlwraps.put("�", "Ê"); htmlwraps.put("�", "&icute;"); htmlwraps.put("�", "ì"); htmlwraps.put("�", "î"); htmlwraps.put("�", "&Icute;"); htmlwraps.put("�", "Ì"); htmlwraps.put("�", "Î"); htmlwraps.put("�", "&ocute;"); htmlwraps.put("�", "ò"); htmlwraps.put("�", "ô"); htmlwraps.put("�", "õ"); htmlwraps.put("�", "&Ocute;"); htmlwraps.put("�", "Ò"); htmlwraps.put("�", "Ô"); htmlwraps.put("�", "Õ"); htmlwraps.put("�", "&ucute;"); htmlwraps.put("�", "ù"); htmlwraps.put("�", "û"); htmlwraps.put("�", "&Ucute;"); htmlwraps.put("�", "Ù"); htmlwraps.put("�", "Û"); htmlwraps.put("�", "&cccedil;"); htmlwraps.put("�", "Ç"); seps = ""; Iterator it = htmlwraps.keySet().iterator(); while(it.hasNext()) seps += (String)it.next(); } /** * Get a string array of properties that are separated by commas. * * @param key The key. * @param props The properties. * @return The strings. */ public static String[] getStringArray(String key, Properties props) { String[] ret = new String[0]; String os = props.getProperty(key); if(os != null) { StringTokenizer stok = new StringTokenizer(os, ","); ret = new String[stok.countTokens()]; for(int i = 0; stok.hasMoreTokens(); i++) { ret[i] = stok.nextToken().trim(); } } return ret; } /** * Joins two arrays of the same type. Creates a new array containing the * values of the first array followed by the values of the second. * * @param a1 The first array. * @param a2 The second array. * @return The joined array. */ public static Object joinArrays(Object a1, Object a2) { int l1 = Array.getLength(a1); int l2 = Array.getLength(a2); Object res = Array.newInstance(a1.getClass().getComponentType(), l1 + l2); System.arraycopy(a1, 0, res, 0, l1); System.arraycopy(a2, 0, res, l1, l2); return res; } /** * Joins any arrays of (possibly) different type. todo: Does not support * basic types yet. Problem basic type array and object arrays cannot be * mapped (except they are mapped). * * @param as The array of arrays to join.. * @return The joined array. */ public static Object[] joinArbitraryArrays(Object[] as) { int lsum = 0; for(int i = 0; i < as.length; i++) lsum += Array.getLength(as[i]); Object[] ret = new Object[lsum]; // Object ret = Array.newInstance(Object.class, lsum); int start = 0; for(int i = 0; i < as.length; i++) { int length = Array.getLength(as[i]); System.arraycopy(as[i], 0, ret, start, length); start += length; } return ret; } /** * Cut two arrays. * * @param a1 The first array. * @param a2 The second array. * @return The cutted array. */ public static Object cutArrays(Object a1, Object a2) { List ar1 = arrayToList(a1); List ar2 = arrayToList(a2); List ret = new ArrayList(); Object tmp; for(int i = 0; i < ar1.size(); i++) { tmp = ar1.get(i); if(ar2.contains(tmp)) { ret.add(tmp); } } return ret.toArray((Object[])Array.newInstance(a1.getClass() .getComponentType(), ret.size())); } /** * First array minus second array. * * @param a1 The first array. * @param a2 The second array. * @return The substracted array. */ public static Object substractArrays(Object a1, Object a2) { List ar1 = arrayToList(a1); List ar2 = arrayToList(a2); Object tmp; for(int i = 0; i < ar2.size(); i++) { tmp = ar2.get(i); if(ar1.contains(tmp)) { ar1.remove(tmp); } } return ar1.toArray((Object[])Array.newInstance(a1.getClass() .getComponentType(), ar1.size())); } /** * Transform an array to a vector. * * @param a The array. * @return The vector for the array. */ public static List arrayToList(Object a) { int l = Array.getLength(a); ArrayList ret = SCollection.createArrayList(); for(int i = 0; i < l; i++) { ret.add(Array.get(a, i)); } return ret; } /** * Transform an array to a vector. * * @param a The array. * @return The vector for the array. */ public static Set arrayToSet(Object a) { int l = Array.getLength(a); Set ret = SCollection.createHashSet(); for(int i = 0; i < l; i++) { ret.add(Array.get(a, i)); } return ret; } /** * Join two sets. * * @param a The first set. * @param b The second set. * @return A set with elements from a and b. / public static Set * joinSets(Set a, Set b) { Set ret = new HashSet(); ret.addAll(a); * ret.addAll(b); return ret; } */ /** * Transform an iterator to a list. */ public static List iteratorToList(Iterator it) { List ret = new ArrayList(); while(it.hasNext()) ret.add(it.next()); return ret; } /** * Transform an iterator to a list. */ public static List iteratorToList(Iterator it, List ret) { if(ret == null) ret = new ArrayList(); while(it.hasNext()) ret.add(it.next()); return ret; } /** * Transform an iterator to an array. */ public static Object[] iteratorToArray(Iterator it, Class clazz) { List list = iteratorToList(it); return list.toArray((Object[])Array.newInstance(clazz, list.size())); } /** * Check if an element is contained in an array. * * @param array The array. * @param value The value. */ public static boolean arrayContains(Object array, Object value) { int l = Array.getLength(array); boolean ret = false; for(int i = 0; !ret && i < l; i++) { ret = equals(Array.get(array, i), value); } return ret; } /** * Get the dimension of an array. * * @param array * @return The array dimension. */ public static int[] getArrayLengths(Object array) { List lens = new ArrayList(); Class cls = array.getClass(); while(cls.isArray()) { lens.add(new Integer(Array.getLength(array))); cls = cls.getComponentType(); } int[] ret = new int[lens.size()]; for(int i = 0; i < lens.size(); i++) ret[i] = ((Integer)lens.get(i)).intValue(); return ret; } /* * Test if two values are equal or both null. * @param val1 The first value. * @param val2 The second value. * @return True when the values are equal. */ public static boolean equals(Object val1, Object val2) { // Should try comparable first, for consistency??? return val1 == val2 || val1 != null && val1.equals(val2); } /** * Test if two arrays are content equal or both null. * * @param array1 The first array. * @param array2 The second array. * @return True when the arrays are content equal. */ public static boolean arrayEquals(Object array1, Object array2) { boolean ret = array1 == null && array2 == null; if(!ret && array1 != null && array2 != null) { int l1 = Array.getLength(array1); int l2 = Array.getLength(array2); if(l1 == l2) { ret = true; for(int i = 0; i < l1 && ret; i++) { if(!Array.get(array1, i).equals(Array.get(array2, i))) ret = false; } } } return ret; } /** * Calculate a hash code for an array. */ public static int arrayHashCode(Object a) { int ret = 1; for(int i = 0; i < Array.getLength(a); i++) { Object val = Array.get(a, i); ret = 31 * ret + (val != null ? val.hashCode() : 0); } return ret; } /** * Get a string representation for an array. * * @param array The array. * @return formatted string. */ public static String arrayToString(Object array) { String str = ""; if(array != null && array.getClass().getComponentType() != null) { // inside arrays. str += "["; for(int i = 0; i < Array.getLength(array); i++) { str += arrayToString(Array.get(array, i)); if(i < Array.getLength(array) - 1) { str += ", "; } } str += "]"; } else { // simple type str += "" + array; } return str; } /** * Get the singular of a word in plural. Does NOT find all correct singular. * * @param s The plural word. * @return The singular of this word. */ public static String getSingular(String s) { String sing = s; if(s.endsWith("shes") || s.endsWith("ches") || s.endsWith("xes") || s.endsWith("ses")) { sing = s.substring(0, s.length() - 2); } else if(s.endsWith("ies")) { sing = s.substring(0, s.length() - 3) + "y"; } else if(s.endsWith("s")) { sing = s.substring(0, s.length() - 1); } return sing; } /** * Get the plural of a word in singular. Does NOT find all correct plurals. * * @param s The word. * @return The plural of this word. */ public static String getPlural(String s) { String plu = s; if(s.endsWith("y")) { plu = s.substring(0, s.length() - 1) + "ies"; } else if(s.endsWith("s")) { plu = s + "es"; } else { plu = s + "s"; } return plu; } /** * Compares two strings, ignoring case. * * @param a The first string. * @param b The second string. * @return a<b => <0 */ public static int compareTo(String a, String b) { return a.toUpperCase().toLowerCase() .compareTo(b.toUpperCase().toLowerCase()); } /** * Test if the date is in the range. Start or end may null and will so not * be checked. * * @param date The date. * @param start The start. * @param end The end. * @return True, if date is in range. */ public static boolean isInRange(Date date, Date start, Date end) { boolean ret = true; if(start != null && date.before(start)) { ret = false; } if(ret && end != null && date.after(end)) { ret = false; } return ret; } /** * Remove file extension. * * @param fn The filename.. * @return filename without extension. */ public static String removeExtension(String fn) { int index = fn.lastIndexOf("."); if(index > -1) { fn = fn.substring(0, index); } return fn; } /** * Wrap a text at a given line length. Doesn't to word wrap, just inserts * linebreaks every nth character. If the string already contains * linebreaks, these are handled properly (extra linebreaks will only be * inserted when needed). * * @param text The text to wrap. */ public static String wrapText(String text) { return wrapText(text, 80); } /** * Wrap a text at a given line length. Doesn't to word wrap, just inserts * linebreaks every nth character. If the string already contains * linebreaks, these are handled properly (extra linebreaks will only be * inserted when needed). * * @param text The text to wrap. * @param wrap The column width. */ public static String wrapText(String text, int wrap) { StringBuffer buf = new StringBuffer(text); int i = 0; // Insert line breaks, while more than <wrap> characters to go. while(buf.length() > i + wrap) { // Find next line break. // int next = buf.indexOf("\n", i); // works for 1.4 only. int next = buf.substring(i).indexOf("\n"); // Skip line break, when in sight. if(next != -1 && next - i <= wrap) { i = i + next + 1; } // Otherwise, insert line break. else { buf.insert(i + wrap, '\n'); i = i + wrap + 1; } } return buf.toString(); } /** Constant for sorting up. */ public static final int SORT_UP = 0; /** Constant for sorting down. */ public static final int SORT_DOWN = 1; /** * Remove the least element form a collection. */ protected static int getExtremeElementIndex(Vector source, int direction) { String ret = (String)source.elementAt(0); int retidx = 0; int size = source.size(); for(int i = 0; i < size; i++) { String tmp = (String)source.elementAt(i); int res = tmp.compareTo(ret); if((res < 0 && direction == SORT_UP) || (res > 0 && direction == SORT_DOWN)) { ret = tmp; retidx = i; } } return retidx; } /** * Convert an output to html/wml conform presentation. * * @param input The input string. * @return The converted output string. */ public static String makeConform(String input) { return makeConform(input, CONVERT_ALL); } /** * Convert an output to html/wml conform presentation. * * @param input The input string. * @param flag CONVERT_ALL, CONVERT_NONE, CONVERT_ALL_EXCEPT_AMP; * @return The converted output string. */ public static String makeConform(String input, int flag) { String res = input; if(flag != CONVERT_NONE) { StringTokenizer stok = new StringTokenizer(input, seps, true); res = ""; while(stok.hasMoreTokens()) { String tmp = stok.nextToken(); String rep = null; if(!(tmp.equals("&") && flag == CONVERT_ALL_EXCEPT_AMP)) rep = (String)htmlwraps.get(tmp); if(rep != null) res += rep; else res += tmp; } } return res; } /** * Strip tags (e.g. html) from a string, leaving only the text content. */ public static String stripTags(String source) { int start, end; while((start = source.indexOf("<")) != -1 && (end = source.indexOf(">")) > start) { if(end == source.length() - 1) { source = source.substring(0, start); } else { source = source.substring(0, start) + source.substring(end + 1); } } return source; } /** * Convert an output readable in english. Therefore remove all äs, * ös, üs etc. * * @param input The input string. * @return The converted output string. */ public static String makeEnglishConform(String input) { StringTokenizer stok = new StringTokenizer(input, seps, true); String res = ""; while(stok.hasMoreTokens()) { String tmp = stok.nextToken(); if(htmlwraps.get(tmp) == null) res += tmp; } return res; } /** * Convert a color to an html representation. * * @param color The color. * @return The html string representing the color. */ public static String colorToHTML(Color color) { return "#" + Integer.toHexString(color.getRed()) + Integer.toHexString(color.getGreen()) + Integer.toHexString(color.getBlue()); } /** * Convert a font to an html representation. * * @param font The font. * @return The html string representing the font. */ public static String fontToHTML(Font font) { String style; if(font.isBold()) { style = font.isItalic() ? "bolditalic " : "bold "; } else { style = font.isItalic() ? "italic " : ""; } return style + font.getSize() + " " + font.getName(); } /** * Extract the values out of an sl message. * * @param message The sl message. * @return The extracted properties. / // obsolete ??? public static * Properties parseSLToPropertiesFast(String message) { Properties * props = new Properties(); int index = message.indexOf(':'); * while(index!=-1) { // Hack !!! Assume space separated slots. int * index2 = message.indexOf(' ', index); String name = * message.substring(index+1, index2); index = message.indexOf('"', * index2); index2 = message.indexOf('"', index+1); String value = * message.substring(index+1, index2); props.setProperty(name, * value); index = message.indexOf(':', index2); } return props; } */ /** * Extract the value(s) out of an sl message. * * @param message The sl message. * @return The extracted value(s) as string, index map or array list. * @see #toSLString(Object) / public static Object fromSLString(String * message) { Object ret; // Parse map. if(message.startsWith("(Map ") * && message.endsWith(")")) { message = message.substring(5, * message.length()-1); ExpressionTokenizer exto = new * ExpressionTokenizer(message, " \t\r\n", new String[]{"\"\"", "()"}); * Map map = new IndexMap().getAsMap(); // Hack??? * while(exto.hasMoreTokens()) { // Check for ":" as start of slot * name. String slot = exto.nextToken(); if(!slot.startsWith(":") || * !exto.hasMoreTokens()) throw new * RuntimeException("Invalid SL: "+message); slot = slot.substring(1); * //if(slot.equals("2")) // System.out.println("Da1!"); map.put(slot, * fromSLString(exto.nextToken())); } ret = map; } // Parse sequence to * collection object. else if(message.startsWith("(sequence ") && * message.endsWith(")")) { message = message.substring(10, * message.length()-1); ExpressionTokenizer exto2 = new * ExpressionTokenizer(message, " \t\r\n", new String[]{"\"\"", "()"}); * List list = new ArrayList(); while(exto2.hasMoreTokens()) { * list.add(fromSLString(exto2.nextToken())); } ret = list; } // Simple * slot message. else { // Remove quotes from message. * if(message.startsWith("\"") && message.endsWith("\"")) message = * message.substring(1, message.length()-1); // Replace escaped quotes. * message = SUtil.replace(message, "\\\"", "\""); ret = message; } * return ret; } */ /** * Convert an object to an SL string. When the value is of type * java.util.Map the key value pairs are extracted as slots. Keys must be * valid slot names. Values of type java.util.Collection are stored as * sequence. * * @return A string representation in SL. / public static String * toSLString(Object o) { StringBuffer sbuf = new StringBuffer(); * toSLString(o, sbuf); return sbuf.toString(); } */ /** * Convert an object to an SL string. When the value is of type * java.util.Map the key value pairs are extracted as slots. Keys must be * valid slot names. Values of type java.util.Collection are stored as * sequence. * * @param o The object to convert to SL. * @param sbuf The buffer to convert into. / public static void * toSLString(Object o, StringBuffer sbuf) { // Get mapo from * encodable object. /*if(o instanceof IEncodable) { o = * ((IEncodable)o).getEncodableRepresentation(); }* / // Write * contents as slot value pairs. if(o instanceof Map) { Map contents * = (Map)o; sbuf.append("(Map "); for(Iterator * i=contents.keySet().iterator(); i.hasNext();) { Object key = * i.next(); Object val = contents.get(key); if(val!=null && * !"null".equals(val)) // Hack ??? { // Check if key is valid slot * identifier. String keyval = key.toString(); * if(keyval.indexOf(' ')!=-1 || keyval.indexOf('\t')!=-1 || * keyval.indexOf('\r')!=-1 || keyval.indexOf('\n')!=-1) { throw new * RuntimeException("Encoding error: Invalid slot name "+keyval); } * sbuf.append(" :"); sbuf.append(keyval); sbuf.append(" "); * toSLString(val, sbuf); } } sbuf.append(")"); } // Write collection * value as sequence. else if(o instanceof Collection) { Collection * coll = (Collection)o; sbuf.append(" (sequence "); for(Iterator * j=coll.iterator(); j.hasNext(); ) { sbuf.append(" "); * toSLString(j.next(), sbuf); } sbuf.append(")"); } // Write normal * slot value as string. else { sbuf.append("\""); // Escape quotes * (directly writes to string buffer). SUtil.replace(""+o, sbuf, * "\"", "\\\""); sbuf.append("\""); } } */ /** * Parse a source string replacing occurrences and storing the result in the * given string buffer. This is a fast alternative to String.replaceAll(), * because it does not use regular expressions. * * @param source The source string. * @param dest The destination string buffer. * @param old The string to replace. * @param newstring The string to use as replacement. */ public static void replace(String source, StringBuffer dest, String old, String newstring) { int last = 0; int index; while((index = source.indexOf(old, last)) != -1) { dest.append(source.substring(last, index)); dest.append(newstring); last = index + old.length(); } dest.append(source.substring(last)); } /** * Parse a source string replacing occurrences and returning the result. * This is a fast alternative to String.replaceAll(), because it does not * use regular expressions. * * @param source The source string. * @param old The string to replace. * @param newstring The string to use as replacement. */ public static String replace(String source, String old, String newstring) { StringBuffer sbuf = new StringBuffer(); replace(source, sbuf, old, newstring); return sbuf.toString(); } /** * Get an input stream for whatever provided. 1. It is tried to load the * resource as file. 2. It is tried to load the resource via the * ClassLoader. 3. It is tried to load the resource as URL. * * @param name The resource description. * @return The input stream for the resource. * @throws IOException when the resource was not found. */ public static InputStream getResource(String name, ClassLoader classloader) throws IOException { InputStream is = getResource0(name, classloader); if(is == null) throw new IOException("Could not load file: " + name); return is; } /** * Get an input stream for whatever provided. 1. It is tried to load the * resource as file. 2. It is tried to load the resource via the * ClassLoader. 3. It is tried to load the resource as URL. * * @param name The resource description. * @return The input stream for the resource or null when the resource was * not found. */ public synchronized static InputStream getResource0(String name, ClassLoader classloader) { InputStream is = null; File file; if(classloader == null) classloader = SUtil.class.getClassLoader(); // File... // Hack!!! Might throw exception in applet / webstart. try { file = new File(name); if(file.exists()) { try { is = new FileInputStream(file); } catch(FileNotFoundException e) { // File is directory, or maybe locked... } } } catch(SecurityException e) { } // Classpath... if(is == null) { // is = getClassLoader().getResourceAsStream(name.startsWith("/") ? // name.substring(1) : name); is = classloader.getResourceAsStream(name.startsWith("/") ? name .substring(1) : name); } // URL... if(is == null) { try { is = new URL(name).openStream(); } catch(IOException le) { } } return is; } /** * Get an input stream for whatever provided. 1. It is tried to load the * resource as file. 2. It is tried to load the resource via the * ClassLoader. 3. It is tried to load the resource as URL. * * @param name The resource description. * @return The info object for the resource or null when the resource was * not found. */ public synchronized static ResourceInfo getResourceInfo0(String name, ClassLoader classloader) { ResourceInfo ret = null; File file; if(classloader == null) classloader = SUtil.class.getClassLoader(); // File... // Hack!!! Might throw exception in applet / webstart. try { file = new File(name); if(file.exists()) { if(file.isDirectory()) { ret = new ResourceInfo(file.getAbsolutePath(), null, file.lastModified()); } else { try { ret = new ResourceInfo(file.getAbsolutePath(), new FileInputStream(file), file.lastModified()); } catch(FileNotFoundException e) { // File is directory, or maybe locked... } } } } catch(SecurityException e) { } // Classpath... if(ret == null) { URL url = classloader.getResource(name.startsWith("/") ? name .substring(1) : name); // System.out.println("Classloader: "+classloader+" "+name+" "+url+" "+classloader.getParent()); // if(classloader instanceof URLClassLoader) // System.out.println("URLs: "+SUtil.arrayToString(((URLClassLoader)classloader).getURLs())); if(url != null) { // Local file from classpath. // Hack!!! Needed because of last-modified precision (argl). if(url.getProtocol().equals("file")) { // Find out default encoding (might fail in applets). String encoding = "ISO-8859-1"; try { encoding = System.getProperty("file.encoding"); } catch(SecurityException e) { } try { file = new File(URLDecoder.decode(url.getFile(), encoding)); // does only work since 1.4. // file = new File(URLDecoder.decode(url.getFile())); // // problem decode is deprecated. if(file.exists()) { if(file.isDirectory()) { ret = new ResourceInfo(file.getAbsolutePath(), null, file.lastModified()); } else { try { ret = new ResourceInfo( file.getAbsolutePath(), new FileInputStream(file), file.lastModified()); } catch(FileNotFoundException fnfe) { // File is directory, or maybe locked... } } } } catch(UnsupportedEncodingException e) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); throw new RuntimeException(sw.toString()); } } // Remote or jar file... else { try { url = classloader.getResource(name.startsWith("/") ? name.substring(1) : name); URLConnection con = url.openConnection(); con.setDefaultUseCaches(false); // See Java Bug ID // 4386865 long modified = con.getLastModified(); String filename = url.getFile(); if(con instanceof JarURLConnection) { JarURLConnection juc = (JarURLConnection)con; // System.out.println("Jar file: "+juc.getJarFile()); // System.out.println("Jar file url: "+juc.getJarFileURL()); // System.out.println("Jar entry: "+juc.getJarEntry()); // System.out.println("Entry name: "+juc.getEntryName()); // Add jar protocol to file (hack???). if(!filename.startsWith("jar:")) filename = "jar:" + filename; // Set modified date to time of entry (if // specified). if(juc.getJarEntry().getTime() != -1) modified = juc.getJarEntry().getTime(); try { ret = new ResourceInfo(filename, con.getInputStream(), modified); } catch(NullPointerException e) { // Workaround for Java bug #5093378 !? // Maybe this is only a race condition??? String jarfilename = juc.getJarFile().getName(); ret = new ResourceInfo(filename, new JarFile( jarfilename).getInputStream(juc .getJarEntry()), modified); // System.err.println("loaded with workaround: "+url); } // todo: what about jar directories?! } else { ret = new ResourceInfo(filename, con.getInputStream(), modified); } } catch(IOException e) { // System.err.println("Error loading: "+url); // e.printStackTrace(); } } } } // URL... if(ret == null) { try { URL url = new URL(name); URLConnection con = url.openConnection(); ret = new ResourceInfo(name, con.getInputStream(), con.getLastModified()); } catch(IOException le) { } } return ret; } /** * Encode an object into XML. * * @param ob The object. * @return The xml representation. / // Hack!!! has to be synchronized due * to bug in JDK 1.4 java.beans.Statement public synchronized static * String encodeXML(Object ob) { ByteArrayOutputStream bs = new * ByteArrayOutputStream(); XMLEncoder e = new XMLEncoder(bs); * e.setExceptionListener(new ExceptionListener() { public void * exceptionThrown(Exception e) { * System.out.println("XML encoding ERROR: "); e.printStackTrace(); * } }); e.writeObject(ob); e.close(); return bs.toString(); } */ /** * Decode an object from XML. * * @param xml_ob The xml representation. * @return The object. / // Hack!!! has to be synchronized due to bug in JDK * 1.4 java.beans.Statement public synchronized static Object * decodeXML(final String xml_ob) { ByteArrayInputStream bs = new * ByteArrayInputStream(xml_ob.getBytes()); XMLDecoder d = new * XMLDecoder(bs, null, new ExceptionListener() { public void * exceptionThrown(Exception e) { * System.out.println("XML decoding ERROR: "+xml_ob); * e.printStackTrace(); } }); Object ob = d.readObject(); d.close(); * return ob; } */ /** * Get a string representation for a duration. * * @param ms The duration in ms. * @return The string representation. */ public static String getDurationHMS(long ms) { long h = ms / 3600000; ms = ms - h * 3600000; long m = ms / 60000; ms = ms - m * 60000; long s = ms / 1000; ms = ms - s * 1000; StringBuffer ret = new StringBuffer(""); if(h > 0) { ret.append(h); ret.append("h "); } if(m > 0) { ret.append(m); ret.append("min "); } // if(s>0) // { ret.append(s); ret.append(","); ret.append(ms / 100); ret.append("s "); /* * } if(h==0 && m==0 && s==0) { ret.append(ms); ret.append("ms"); } */ return ret.toString(); } /** * Find a package name from a path. Searches the most specific classpath and * uses the rest of the pathname as package name. * * @param path The directory. * @return The package. */ public static String convertPathToPackage(String path, ClassLoader classloader) { String ret = null; File fpath = new File(path); if(!fpath.isDirectory()) path = fpath.getParent(); List cps = getClasspathURLs(classloader); java.util.List toks = SCollection.createArrayList(); StringTokenizer stok = new StringTokenizer(path, File.separator); while(stok.hasMoreTokens()) toks.add(stok.nextToken()); int quality = 0; for(int i = 0; i < cps.size(); i++) { String cp = ((URL)cps.get(i)).getFile(); stok = new StringTokenizer(cp, "/!"); // Exclamation mark to support // jar files. int cplen = stok.countTokens(); if(cplen <= toks.size()) { int j = 0; for(; stok.hasMoreTokens(); j++) { if(!stok.nextToken().equals(toks.get(j))) break; } if(j == cplen && cplen > quality) { ret = ""; for(int k = j; k < toks.size(); k++) { if(k > j && k < toks.size()) ret += "."; ret += "" + toks.get(k); } quality = cplen; } } } return ret; } // /** // * Get the classloader. // * Uses the context class loader, if available. // */ // public static ClassLoader getClassLoader() // { // ClassLoader ret = Thread.currentThread().getContextClassLoader(); // if(ret==null) // { // ret = SReflect.class.getClassLoader(); // } // return ret; // } /** * Get the current classpath as a list of URLs */ public static List getClasspathURLs(ClassLoader classloader) { if(classloader == null) classloader = SUtil.class.getClassLoader(); List cps = SCollection.createArrayList(); StringTokenizer stok = new StringTokenizer( System.getProperty("java.class.path"), System.getProperty("path.separator")); while(stok.hasMoreTokens()) { try { String entry = stok.nextToken(); File file = new File(entry); if(file.isDirectory() && !entry .endsWith(System.getProperty("file.separator"))) { // Normalize, that directories end with "/". entry += System.getProperty("file.separator"); } cps.add(new URL("file:///" + entry)); } catch(MalformedURLException e) { // Maybe invalid classpath entries --> just ignore. // Hack!!! Print warning? // e.printStackTrace(); } } if(classloader instanceof URLClassLoader) { URL[] urls = ((URLClassLoader)classloader).getURLs(); for(int i = 0; i < urls.length; i++) cps.add(urls[i]); } return cps; } /** * Calculate the cartesian product of parameters. Example: names = {"a", * "b"}, values = {{"1", "2"}, {"3", "4"}} result = {{"a"="1", "b"="3"}, * {"a"="2", "b"="3"}, {"a"="1", "b"="4"}, {"a=2", b="4"}} * * @param names The names. * @param values The values (must be some form of collection, i.e. array, * list, iterator etc.) */ public static List calculateCartesianProduct(String[] names, Object[] values) { ArrayList ret = SCollection.createArrayList(); if(names == null || values == null) return ret; if(names.length != values.length) throw new IllegalArgumentException("Must have same length: " + names.length + " " + values.length); HashMap binding = SCollection.createHashMap(); Iterator[] iters = new Iterator[values.length]; for(int i = 0; i < values.length; i++) { // When one collection is empty -> no binding at all. // First binding consists of all first elements. iters[i] = SReflect.getIterator(values[i]); if(!iters[i].hasNext()) { return ret; } else { binding.put(names[i], iters[i].next()); } } ret.add(binding); // Iterate through binding sets for subsequent bindings. while(true) { // Calculate next binding. // Copy old binding and change one value. binding = (HashMap)binding.clone(); int i = 0; for(; i < values.length && !iters[i].hasNext(); i++) { // Overflow: Re-init iterator. iters[i] = SReflect.getIterator(values[i]); binding.put(names[i], iters[i].next()); } if(i < iters.length) { binding.put(names[i], iters[i].next()); } else { // Overflow in last iterator: done. // Hack: Unnecessarily re-inits all iterators before break ? break; } ret.add(binding); } return ret; } /** * Test if a file is a Java source file. * * @param filename The filename. * @return True, if it is a Java source file. */ public static boolean isJavaSourceFilename(String filename) { return filename != null && filename.toLowerCase().endsWith(".java"); } /** * Create a hash map from keys and values. * * @param keys The keys. * @param values The values. * @return The map. */ public static Map createHashMap(Object[] keys, Object[] values) { HashMap ret = new HashMap(); for(int i = 0; i < keys.length; i++) { ret.put(keys[i], values[i]); } return ret; } /** * Create a hash set from values. * * @param values The values. * @return The map. */ public static Set createHashSet(Object[] values) { Set ret = new HashSet(); for(int i = 0; i < values.length; i++) { ret.add(values[i]); } return ret; } /** * Create an array list from values. * * @param values The values. * @return The map. */ public static List createArrayList(Object[] values) { List ret = new ArrayList(); for(int i = 0; i < values.length; i++) { ret.add(values[i]); } return ret; } /** The counter for conversation ids. */ protected static int convidcnt; /** * Create a globally unique conversation id. * * @return The conversation id. */ public static String createUniqueId(String name) { synchronized(SUtil.class) { // return // "id_"+name+"_"+System.currentTimeMillis()+"_"+Math.random()+"_"+(++convidcnt); // return "id_"+name+"_"+Math.random()+"_"+(++convidcnt); return name + "_" + Math.random() + "_" + (++convidcnt); } } /** * Create a globally unique conversation id. * * @return The conversation id. */ public static String createUniqueId(String name, int length) { UUID uuid = UUID.randomUUID(); String rand = uuid.toString(); return name + "_" + rand.substring(0, length); // String rand = ""+Math.random(); // rand = rand.substring(2, 2+Math.min(length-2, rand.length()-2)); // return name+"_"+rand+(++convidcnt%100); } /** * Main method for testing. */ public static void main(String[] args) { // System.out.println("Here: " + createUniqueId("test", 3)); testIntByteConversion(); } private static void testIntByteConversion() { Random rnd = new Random(123); for(int i=1; i<10000000; i++) { int val = rnd.nextInt(Integer.MAX_VALUE); if(i%2==0) // Test negative values too. { val = -val; } byte[] bytes = intToBytes(val); int val2 = bytesToInt(bytes); if(val!=val2) { throw new RuntimeException("Failed: "+val+", "+val2+", "+arrayToString(bytes)); } // System.out.println("Converted: "+val+", "+arrayToString(bytes)); } } /** * Convert an absolute path to a relative path based on the current user * directory. */ public static String convertPathToRelative(String absolute) { // Build path as list of files (directories). File basedir = new File(System.getProperty("user.dir")); List basedirs = new ArrayList(); while(basedir != null) { basedirs.add(0, basedir); basedir = basedir.getParentFile(); } // Build path as list of files (directories). File target = new File(absolute); List targets = new ArrayList(); while(target != null) { targets.add(0, target); target = target.getParentFile(); } // Find common path prefix int index = 0; while(index < basedirs.size() && index < targets.size() && basedirs.get(index).equals(targets.get(index))) { index++; } String ret; if(index > 0) { StringBuffer buf = new StringBuffer(); for(int i = index; i < basedirs.size(); i++) { buf.append(".."); buf.append(File.separatorChar); } for(int i = index; i < targets.size(); i++) { buf.append(((File)targets.get(i)).getName()); if(i != targets.size() - 1) buf.append(File.separatorChar); } ret = buf.toString(); } else { ret = absolute; } return ret; } /** * Main method for testing. / public static void main(String[] args) { * String res1 = getRelativePath("c:/a/b/c", "c:/a/d"); String res2 = * getRelativePath("c:/a/b/c", "c:/a/b/c"); //String res2 = * getRelativePath("c:/a/b/c", "d:/a/d"); String res3 = * getRelativePath("c:/a/b/c", "c:/a/b/c/d/e"); //String tst = * "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww" * ; //System.out.println(tst); //System.out.println(SUtil.wrapText(tst)); * /*String[] a = new String[]{"a1", "a2", "a3"}; Integer[] b = new * Integer[]{new Integer(1), new Integer(2), new Integer(3)}; * System.out.println(arrayToString(joinArbitraryArrays(new Object[]{a, * b}))); */ /* * try { URL target = new URL("file:///C:/projects/jadex/lib/examples.jar"); * DynamicURLClassLoader loader = new DynamicURLClassLoader(new URL[0]); try * { Class clazz = loader.loadClass("jadex.examples.ping.PingPlan"); * System.out.println("Loaded class: "+clazz); } * catch(ClassNotFoundException e){System.out.println(e);} * loader.addURL(target); try { Class clazz = * loader.loadClass("jadex.examples.ping.PingPlan"); * System.out.println("Loaded class: "+clazz); } * catch(ClassNotFoundException e){System.out.println(e);} } catch(Exception * e) { System.out.println(e); } } */ /** * Convert bytes to an integer. */ public static int bytesToInt(byte[] buffer) { if(buffer.length != 4) { throw new IllegalArgumentException("buffer length must be 4 bytes!"); } int value = (0xFF & buffer[0]) << 24; value |= (0xFF & buffer[1]) << 16; value |= (0xFF & buffer[2]) << 8; value |= (0xFF & buffer[3]); return value; } /** * Convert an integer to bytes. */ public static byte[] intToBytes(int val) { byte[] buffer = new byte[4]; buffer[0] = (byte)(val >>> 24); buffer[1] = (byte)(val >>> 16); buffer[2] = (byte)(val >>> 8); buffer[3] = (byte)val; return buffer; } /** * Convert an URL to a local file name. * @param url The url. * @return The absolute path to the url resource. */ public static String convertURLToString(URL url) { String file = url.getFile(); File f = new File(file); // Hack!!! Above code doesnt handle relative url paths. if(!f.exists()) { File newfile = new File(new File("."), file); if(newfile.exists()) { f = newfile; } } return f.getAbsolutePath(); } }