Debug now automatically figures out which class it was called from, so all methods passing in the calling class are deprecated.
The defaults are to print all messages to stderr with class and method name.
Should be called like this:
if (Debug.debug) Debug.print(Debug.INFO, "Debug Message");*/ public class Debug { /** This interface can be used to provide custom printing filters for certain classes. */ public static interface FilterCommand { /** Called to print debug messages with a custom filter. @param output The PrintStream to output to. @param level The debug level of this message. @param location The textual location of the message. @param extra Extra information such as timing details. @param message The debug message. @param lines Other lines of a multiple-line debug message. */ public void filter(PrintStream output, int level, String location, String extra, String message, String[] lines); } /** Highest priority messages */ public static final int CRIT = 1; /** Error messages */ public static final int ERR = 2; /** Warnings */ public static final int WARN = 3; /** Information */ public static final int INFO = 4; /** Debug messages */ public static final int DEBUG = 5; /** Verbose debug messages */ public static final int VERBOSE = 6; /** Set this to false to disable compilation of Debug statements */ public static final boolean debug = false; /** The current output stream (defaults to System.err) */ public static PrintStream debugout = System.err; private static Properties prop = null; private static boolean timing = false; private static boolean ttrace = false; private static boolean lines = false; private static boolean hexdump = false; private static long last = 0; private static int balen = 36; private static int bawidth = 80; private static Class saveclass = null; //TODO: 1.5 private static Map
cx.ath.matthew.io.TeeOutputStream = INFO cx.ath.matthew.io.DOMPrinter = DEBUGThe debug level can be one of CRIT, ERR, WARN, INFO, DEBUG or VERBOSE which correspond to all messages up to that level. The special words YES, ALL and TRUE cause all messages to be printed regardless of level. All other terms disable messages for that class. CRIT and ERR messages are always printed if debugging is enabled unless explicitly disabled. The special class name ALL can be used to set the default level for all classes. @param prop Properties object to use. */ public static void setProperties(Properties prop) { Debug.prop = prop; } /** Read which class to debug on at which level from the given File. Syntax the same as Java Properties files:
<class> = <debuglevel>E.G.
cx.ath.matthew.io.TeeOutputStream = INFO cx.ath.matthew.io.DOMPrinter = DEBUGThe debug level can be one of CRIT, ERR, WARN, INFO, DEBUG or VERBOSE which correspond to all messages up to that level. The special words YES, ALL and TRUE cause all messages to be printed regardless of level. All other terms disable messages for that class. CRIT and ERR messages are always printed if debugging is enabled unless explicitly disabled. The special class name ALL can be used to set the default level for all classes. @param f File to read from. */ public static void loadConfig(File f) throws IOException { prop = new Properties(); prop.load(new FileInputStream(f)); } /** @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static boolean debugging(Class c, int loglevel) { if (debug) { if (null == c) return true; return debugging(c.getName(), loglevel); } return false; } public static boolean debugging(String s, int loglevel) { if (debug) { try { if (null == s) return true; if (null == prop) return loglevel <= DEBUG; String d = prop.getProperty(s); if (null == d || "".equals(d)) d = prop.getProperty("ALL"); if (null == d) return loglevel <= ERR; if ("".equals(d)) return loglevel <= ERR; d = d.toLowerCase(); if ("true".equals(d)) return true; if ("yes".equals(d)) return true; if ("all".equals(d)) return true; if ("verbose".equals(d)) return loglevel <= VERBOSE; if ("debug".equals(d)) return loglevel <= DEBUG; if ("info".equals(d)) return loglevel <= INFO; if ("warn".equals(d)) return loglevel <= WARN; if ("err".equals(d)) return loglevel <= ERR; if ("crit".equals(d)) return loglevel <= CRIT; int i = Integer.parseInt(d); return i >= loglevel; } catch (Exception e) { return false; } } return false; } /** Output to the given Stream */ public static void setOutput(PrintStream p) throws IOException { debugout = p; } /** Output to the given file */ public static void setOutput(String filename) throws IOException { debugout = new PrintStream(new FileOutputStream(filename, true)); } /** Output to the default debug.log */ public static void setOutput() throws IOException { setOutput("./debug.log"); } /** Log at DEBUG @param d The object to log */ public static void print(Object d) { if (debug) { if (d instanceof String) print(DEBUG, (String) d); else if (d instanceof Throwable) print(DEBUG, (Throwable) d); else if (d instanceof byte[]) print(DEBUG, (byte[]) d); else if (d instanceof Map) printMap(DEBUG, (Map) d); else print(DEBUG, d); } } /** Log at DEBUG @param o The object doing the logging @param d The object to log @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Object o, Object d) { if (debug) { if (o instanceof Class) saveclass = (Class) o; else saveclass = o.getClass(); print(d); } } /** Log an Object @param o The object doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param d The object to log with d.toString() @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Object o, int loglevel, Object d) { if (debug) { if (o instanceof Class) saveclass = (Class) o; else saveclass = o.getClass(); print(loglevel, d); } } /** Log a String @param o The object doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param s The log message @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Object o, int loglevel, String s) { if (debug) { if (o instanceof Class) saveclass = (Class) o; else saveclass = o.getClass(); print(loglevel, s); } } /** Log a Throwable @param o The object doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param t The throwable to log with .toString and .printStackTrace @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Object o, int loglevel, Throwable t) { if (debug) { if (o instanceof Class) saveclass = (Class) o; else saveclass = o.getClass(); print(loglevel, t); } } /** Log a Throwable @param c The class doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param t The throwable to log with .toString and .printStackTrace @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Class c, int loglevel, Throwable t) { if (debug) { saveclass = c; print(loglevel, t); } } /** Log a Throwable @param loglevel The level to log at (DEBUG, WARN, etc) @param t The throwable to log with .toString and .printStackTrace @see #setThrowableTraces to turn on stack traces. */ public static void print(int loglevel, Throwable t) { if (debug) { String timestr = ""; String[] data = getTraceElements(); if (debugging(data[0], loglevel)) { if (timing) { long now = System.currentTimeMillis(); timestr = "{" + (now-last) + "} "; last = now; } String[] lines = null; if (ttrace) { StackTraceElement[] ste = t.getStackTrace(); lines = new String[ste.length]; for (int i = 0; i < ste.length; i++) lines[i] = "\tat "+ste[i].toString(); } _print(t.getClass(), loglevel, data[0]+"."+data[1]+"()" + data[2], timestr, t.toString(), lines); } } } /** Log a byte array @param loglevel The level to log at (DEBUG, WARN, etc) @param b The byte array to print. @see #setHexDump to enable hex dumping. @see #setByteArrayCount to change how many bytes are printed. @see #setByteArrayWidth to change the formatting width of hex. */ public static void print(int loglevel, byte[] b) { if (debug) { String timestr = ""; String[] data = getTraceElements(); if (debugging(data[0], loglevel)) { if (timing) { long now = System.currentTimeMillis(); timestr = "{" + (now-last) + "} "; last = now; } String[] lines = null; if (hexdump) { if (balen >= b.length) lines = Hexdump.format(b, bawidth).split("\n"); else { byte[] buf = new byte[balen]; System.arraycopy(b, 0, buf, 0, balen); lines = Hexdump.format(buf, bawidth).split("\n"); } } _print(b.getClass(), loglevel, data[0]+"."+data[1]+"()" + data[2], timestr, b.length+" bytes", lines); } } } /** Log a String @param loglevel The level to log at (DEBUG, WARN, etc) @param s The string to log with d.toString() */ public static void print(int loglevel, String s) { if (debug) print(loglevel, (Object) s); } /** Log an Object @param c The class doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param d The object to log with d.toString() @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Class c, int loglevel, Object d) { if (debug) { saveclass = c; print(loglevel, d); } } /** Log a String @param c The class doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param s The log message @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Class c, int loglevel, String s) { if (debug) { saveclass = c; print(loglevel, s); } } private static String[] getTraceElements() { String[] data = new String[] { "", "", "" }; try { Method m = Thread.class.getMethod("getStackTrace", new Class[0]); StackTraceElement[] stes = (StackTraceElement[]) m.invoke(Thread.currentThread(), new Object[0]); for (StackTraceElement ste: stes) { if (Debug.class.getName().equals(ste.getClassName())) continue; if (Thread.class.getName().equals(ste.getClassName())) continue; if (Method.class.getName().equals(ste.getClassName())) continue; if (ste.getClassName().startsWith("sun.reflect")) continue; data[0] = ste.getClassName(); data[1] = ste.getMethodName(); if (lines) data[2] = " "+ste.getFileName()+":"+ste.getLineNumber(); break; } } catch (NoSuchMethodException NSMe) { if (null != saveclass) data[0] = saveclass.getName(); } catch (IllegalAccessException IAe) { } catch (InvocationTargetException ITe) { } return data; } /** Log an Object @param loglevel The level to log at (DEBUG, WARN, etc) @param o The object to log */ public static void print(int loglevel, Object o) { if (debug) { String timestr = ""; String[] data = getTraceElements(); if (debugging(data[0], loglevel)) { if (timing) { long now = System.currentTimeMillis(); timestr = "{" + (now-last) + "} "; last = now; } _print(o.getClass(), loglevel, data[0]+"."+data[1]+"()" + data[2], timestr, o.toString(), null); } } } /** Log a Map @param o The object doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param m The Map to print out @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void printMap(Object o, int loglevel, Map m) { if (debug) { if (o instanceof Class) saveclass = (Class) o; else saveclass = o.getClass(); printMap(loglevel, m); } } /** Log a Map @param c The class doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param m The Map to print out @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void printMap(Class c, int loglevel, Map m) { if (debug) { saveclass = c; printMap(loglevel, m); } } /** Log a Map at DEBUG log level @param m The Map to print out */ public static void printMap(Map m) { printMap(DEBUG, m); } /** Log a Map @param loglevel The level to log at (DEBUG, WARN, etc) @param m The Map to print out */ public static void printMap(int loglevel, Map m) { if (debug) { String timestr = ""; String[] data = getTraceElements(); if (debugging(data[0], loglevel)) { if (timing) { long now = System.currentTimeMillis(); timestr = "{" + (now-last) + "} "; last = now; } Iterator i = m.keySet().iterator(); String[] lines = new String[m.size()]; int j = 0; while (i.hasNext()) { Object key = i.next(); lines[j++] = "\t\t- "+key+" => "+m.get(key); } _print(m.getClass(), loglevel, data[0]+"."+data[1]+"()" + data[2], timestr, "Map:", lines); } } } /** Enable or disable stack traces in Debuging throwables. */ public static void setThrowableTraces(boolean ttrace) { Debug.ttrace = ttrace; } /** Enable or disable timing in Debug messages. */ public static void setTiming(boolean timing) { Debug.timing = timing; } /** Enable or disable line numbers. */ public static void setLineNos(boolean lines) { Debug.lines = lines; } /** Enable or disable hexdumps. */ public static void setHexDump(boolean hexdump) { Debug.hexdump = hexdump; } /** Set the size of hexdumps. (Default: 36) */ public static void setByteArrayCount(int count) { Debug.balen = count; } /** Set the formatted width of hexdumps. (Default: 80 chars) */ public static void setByteArrayWidth(int width) { Debug.bawidth = width; } /** Add a filter command for a specific type. This command will be called with the output stream and the text to be sent. It should perform any changes necessary to the text and then print the result to the output stream. */ public static void addFilterCommand(Class c, FilterCommand f) //TODO 1.5: public static void addFilterCommand(Class extends Object> c, FilterCommand f) { filterMap.put(c, f); } private static void _print(Class c, int level, String loc, String extra, String message, String[] lines) { //TODO 1.5: FilterCommand f = filterMap.get(c); FilterCommand f = (FilterCommand) filterMap.get(c); if (null == f) { debugout.println("["+loc+"] " +extra + message); if (null != lines) for (String s: lines) debugout.println(s); } else f.filter(debugout, level, loc, extra, message, lines); } } libmatthew-java-0.8.1/cx/ath/matthew/debug/Debug.jpp 0000644 0001750 0001750 00000047102 13273414417 020747 0 ustar mjj29 mjj29 /* * Java Debug Library * * Copyright (c) Matthew Johnson 2005 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * To Contact the author, please email src@matthew.ath.cx * */ package cx.ath.matthew.debug; import cx.ath.matthew.utils.Hexdump; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.PrintStream; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; /** Add debugging to your program, has support for large projects with multiple classes and debug levels per class. Supports optional enabling of debug per-level per-class and debug targets of files, Streams or stderr. Also supports timing between debug outputs, printing of stack traces for Throwables and files/line numbers on each message.
Debug now automatically figures out which class it was called from, so all methods passing in the calling class are deprecated.
The defaults are to print all messages to stderr with class and method name.
Should be called like this:
if (Debug.debug) Debug.print(Debug.INFO, "Debug Message");*/ public class Debug { /** This interface can be used to provide custom printing filters for certain classes. */ public static interface FilterCommand { /** Called to print debug messages with a custom filter. @param output The PrintStream to output to. @param level The debug level of this message. @param location The textual location of the message. @param extra Extra information such as timing details. @param message The debug message. @param lines Other lines of a multiple-line debug message. */ public void filter(PrintStream output, int level, String location, String extra, String message, String[] lines); } /** Highest priority messages */ public static final int CRIT = 1; /** Error messages */ public static final int ERR = 2; /** Warnings */ public static final int WARN = 3; /** Information */ public static final int INFO = 4; /** Debug messages */ public static final int DEBUG = 5; /** Verbose debug messages */ public static final int VERBOSE = 6; /** Set this to false to disable compilation of Debug statements */ public static final boolean debug = DEBUGSETTING; /** The current output stream (defaults to System.err) */ public static PrintStream debugout = System.err; private static Properties prop = null; private static boolean timing = false; private static boolean ttrace = false; private static boolean lines = false; private static boolean hexdump = false; private static long last = 0; private static int balen = 36; private static int bawidth = 80; private static Class saveclass = null; //TODO: 1.5 private static Map
cx.ath.matthew.io.TeeOutputStream = INFO cx.ath.matthew.io.DOMPrinter = DEBUGThe debug level can be one of CRIT, ERR, WARN, INFO, DEBUG or VERBOSE which correspond to all messages up to that level. The special words YES, ALL and TRUE cause all messages to be printed regardless of level. All other terms disable messages for that class. CRIT and ERR messages are always printed if debugging is enabled unless explicitly disabled. The special class name ALL can be used to set the default level for all classes. @param prop Properties object to use. */ public static void setProperties(Properties prop) { Debug.prop = prop; } /** Read which class to debug on at which level from the given File. Syntax the same as Java Properties files:
<class> = <debuglevel>E.G.
cx.ath.matthew.io.TeeOutputStream = INFO cx.ath.matthew.io.DOMPrinter = DEBUGThe debug level can be one of CRIT, ERR, WARN, INFO, DEBUG or VERBOSE which correspond to all messages up to that level. The special words YES, ALL and TRUE cause all messages to be printed regardless of level. All other terms disable messages for that class. CRIT and ERR messages are always printed if debugging is enabled unless explicitly disabled. The special class name ALL can be used to set the default level for all classes. @param f File to read from. */ public static void loadConfig(File f) throws IOException { prop = new Properties(); prop.load(new FileInputStream(f)); } /** @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static boolean debugging(Class c, int loglevel) { if (debug) { if (null == c) return true; return debugging(c.getName(), loglevel); } return false; } public static boolean debugging(String s, int loglevel) { if (debug) { try { if (null == s) return true; if (null == prop) return loglevel <= DEBUG; String d = prop.getProperty(s); if (null == d || "".equals(d)) d = prop.getProperty("ALL"); if (null == d) return loglevel <= ERR; if ("".equals(d)) return loglevel <= ERR; d = d.toLowerCase(); if ("true".equals(d)) return true; if ("yes".equals(d)) return true; if ("all".equals(d)) return true; if ("verbose".equals(d)) return loglevel <= VERBOSE; if ("debug".equals(d)) return loglevel <= DEBUG; if ("info".equals(d)) return loglevel <= INFO; if ("warn".equals(d)) return loglevel <= WARN; if ("err".equals(d)) return loglevel <= ERR; if ("crit".equals(d)) return loglevel <= CRIT; int i = Integer.parseInt(d); return i >= loglevel; } catch (Exception e) { return false; } } return false; } /** Output to the given Stream */ public static void setOutput(PrintStream p) throws IOException { debugout = p; } /** Output to the given file */ public static void setOutput(String filename) throws IOException { debugout = new PrintStream(new FileOutputStream(filename, true)); } /** Output to the default debug.log */ public static void setOutput() throws IOException { setOutput("./debug.log"); } /** Log at DEBUG @param d The object to log */ public static void print(Object d) { if (debug) { if (d instanceof String) print(DEBUG, (String) d); else if (d instanceof Throwable) print(DEBUG, (Throwable) d); else if (d instanceof byte[]) print(DEBUG, (byte[]) d); else if (d instanceof Map) printMap(DEBUG, (Map) d); else print(DEBUG, d); } } /** Log at DEBUG @param o The object doing the logging @param d The object to log @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Object o, Object d) { if (debug) { if (o instanceof Class) saveclass = (Class) o; else saveclass = o.getClass(); print(d); } } /** Log an Object @param o The object doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param d The object to log with d.toString() @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Object o, int loglevel, Object d) { if (debug) { if (o instanceof Class) saveclass = (Class) o; else saveclass = o.getClass(); print(loglevel, d); } } /** Log a String @param o The object doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param s The log message @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Object o, int loglevel, String s) { if (debug) { if (o instanceof Class) saveclass = (Class) o; else saveclass = o.getClass(); print(loglevel, s); } } /** Log a Throwable @param o The object doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param t The throwable to log with .toString and .printStackTrace @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Object o, int loglevel, Throwable t) { if (debug) { if (o instanceof Class) saveclass = (Class) o; else saveclass = o.getClass(); print(loglevel, t); } } /** Log a Throwable @param c The class doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param t The throwable to log with .toString and .printStackTrace @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Class c, int loglevel, Throwable t) { if (debug) { saveclass = c; print(loglevel, t); } } /** Log a Throwable @param loglevel The level to log at (DEBUG, WARN, etc) @param t The throwable to log with .toString and .printStackTrace @see #setThrowableTraces to turn on stack traces. */ public static void print(int loglevel, Throwable t) { if (debug) { String timestr = ""; String[] data = getTraceElements(); if (debugging(data[0], loglevel)) { if (timing) { long now = System.currentTimeMillis(); timestr = "{" + (now-last) + "} "; last = now; } String[] lines = null; if (ttrace) { StackTraceElement[] ste = t.getStackTrace(); lines = new String[ste.length]; for (int i = 0; i < ste.length; i++) lines[i] = "\tat "+ste[i].toString(); } _print(t.getClass(), loglevel, data[0]+"."+data[1]+"()" + data[2], timestr, t.toString(), lines); } } } /** Log a byte array @param loglevel The level to log at (DEBUG, WARN, etc) @param b The byte array to print. @see #setHexDump to enable hex dumping. @see #setByteArrayCount to change how many bytes are printed. @see #setByteArrayWidth to change the formatting width of hex. */ public static void print(int loglevel, byte[] b) { if (debug) { String timestr = ""; String[] data = getTraceElements(); if (debugging(data[0], loglevel)) { if (timing) { long now = System.currentTimeMillis(); timestr = "{" + (now-last) + "} "; last = now; } String[] lines = null; if (hexdump) { if (balen >= b.length) lines = Hexdump.format(b, bawidth).split("\n"); else { byte[] buf = new byte[balen]; System.arraycopy(b, 0, buf, 0, balen); lines = Hexdump.format(buf, bawidth).split("\n"); } } _print(b.getClass(), loglevel, data[0]+"."+data[1]+"()" + data[2], timestr, b.length+" bytes", lines); } } } /** Log a String @param loglevel The level to log at (DEBUG, WARN, etc) @param s The string to log with d.toString() */ public static void print(int loglevel, String s) { if (debug) print(loglevel, (Object) s); } /** Log an Object @param c The class doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param d The object to log with d.toString() @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Class c, int loglevel, Object d) { if (debug) { saveclass = c; print(loglevel, d); } } /** Log a String @param c The class doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param s The log message @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void print(Class c, int loglevel, String s) { if (debug) { saveclass = c; print(loglevel, s); } } private static String[] getTraceElements() { String[] data = new String[] { "", "", "" }; try { Method m = Thread.class.getMethod("getStackTrace", new Class[0]); StackTraceElement[] stes = (StackTraceElement[]) m.invoke(Thread.currentThread(), new Object[0]); for (StackTraceElement ste: stes) { if (Debug.class.getName().equals(ste.getClassName())) continue; if (Thread.class.getName().equals(ste.getClassName())) continue; if (Method.class.getName().equals(ste.getClassName())) continue; if (ste.getClassName().startsWith("sun.reflect")) continue; data[0] = ste.getClassName(); data[1] = ste.getMethodName(); if (lines) data[2] = " "+ste.getFileName()+":"+ste.getLineNumber(); break; } } catch (NoSuchMethodException NSMe) { if (null != saveclass) data[0] = saveclass.getName(); } catch (IllegalAccessException IAe) { } catch (InvocationTargetException ITe) { } return data; } /** Log an Object @param loglevel The level to log at (DEBUG, WARN, etc) @param o The object to log */ public static void print(int loglevel, Object o) { if (debug) { String timestr = ""; String[] data = getTraceElements(); if (debugging(data[0], loglevel)) { if (timing) { long now = System.currentTimeMillis(); timestr = "{" + (now-last) + "} "; last = now; } _print(o.getClass(), loglevel, data[0]+"."+data[1]+"()" + data[2], timestr, o.toString(), null); } } } /** Log a Map @param o The object doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param m The Map to print out @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void printMap(Object o, int loglevel, Map m) { if (debug) { if (o instanceof Class) saveclass = (Class) o; else saveclass = o.getClass(); printMap(loglevel, m); } } /** Log a Map @param c The class doing the logging @param loglevel The level to log at (DEBUG, WARN, etc) @param m The Map to print out @deprecated In Java 1.5 calling class is automatically identified, no need to pass it in. */ //TODO: 1.5 @Deprecated() public static void printMap(Class c, int loglevel, Map m) { if (debug) { saveclass = c; printMap(loglevel, m); } } /** Log a Map at DEBUG log level @param m The Map to print out */ public static void printMap(Map m) { printMap(DEBUG, m); } /** Log a Map @param loglevel The level to log at (DEBUG, WARN, etc) @param m The Map to print out */ public static void printMap(int loglevel, Map m) { if (debug) { String timestr = ""; String[] data = getTraceElements(); if (debugging(data[0], loglevel)) { if (timing) { long now = System.currentTimeMillis(); timestr = "{" + (now-last) + "} "; last = now; } Iterator i = m.keySet().iterator(); String[] lines = new String[m.size()]; int j = 0; while (i.hasNext()) { Object key = i.next(); lines[j++] = "\t\t- "+key+" => "+m.get(key); } _print(m.getClass(), loglevel, data[0]+"."+data[1]+"()" + data[2], timestr, "Map:", lines); } } } /** Enable or disable stack traces in Debuging throwables. */ public static void setThrowableTraces(boolean ttrace) { Debug.ttrace = ttrace; } /** Enable or disable timing in Debug messages. */ public static void setTiming(boolean timing) { Debug.timing = timing; } /** Enable or disable line numbers. */ public static void setLineNos(boolean lines) { Debug.lines = lines; } /** Enable or disable hexdumps. */ public static void setHexDump(boolean hexdump) { Debug.hexdump = hexdump; } /** Set the size of hexdumps. (Default: 36) */ public static void setByteArrayCount(int count) { Debug.balen = count; } /** Set the formatted width of hexdumps. (Default: 80 chars) */ public static void setByteArrayWidth(int width) { Debug.bawidth = width; } /** Add a filter command for a specific type. This command will be called with the output stream and the text to be sent. It should perform any changes necessary to the text and then print the result to the output stream. */ public static void addFilterCommand(Class c, FilterCommand f) //TODO 1.5: public static void addFilterCommand(Class extends Object> c, FilterCommand f) { filterMap.put(c, f); } private static void _print(Class c, int level, String loc, String extra, String message, String[] lines) { //TODO 1.5: FilterCommand f = filterMap.get(c); FilterCommand f = (FilterCommand) filterMap.get(c); if (null == f) { debugout.println("["+loc+"] " +extra + message); if (null != lines) for (String s: lines) debugout.println(s); } else f.filter(debugout, level, loc, extra, message, lines); } } libmatthew-java-0.8.1/cx/ath/matthew/utils/ 0000755 0001750 0001750 00000000000 13273414417 017254 5 ustar mjj29 mjj29 libmatthew-java-0.8.1/cx/ath/matthew/utils/Hexdump.java 0000644 0001750 0001750 00000011154 13273414417 021533 0 ustar mjj29 mjj29 /* * Java Hexdump Library * * Copyright (c) Matthew Johnson 2005 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * To Contact the author, please email src@matthew.ath.cx * */ package cx.ath.matthew.utils; import java.io.PrintStream; public class Hexdump { public static final char[] hexchars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; public static String toHex(byte[] buf) { return toHex(buf, 0, buf.length); } public static String toHex(byte[] buf, int ofs, int len) { StringBuffer sb = new StringBuffer(); int j = ofs+len; for (int i = ofs; i < j; i++) { if (i < buf.length) { sb.append(hexchars[(buf[i] & 0xF0) >> 4]); sb.append(hexchars[buf[i] & 0x0F]); sb.append(' '); } else { sb.append(' '); sb.append(' '); sb.append(' '); } } return sb.toString(); } public static String toAscii(byte[] buf) { return toAscii(buf, 0, buf.length); } public static String toAscii(byte[] buf, int ofs, int len) { StringBuffer sb = new StringBuffer(); int j = ofs+len; for (int i = ofs; i < j ; i++) { if (i < buf.length) { if (20 <= buf[i] && 126 >= buf[i]) sb.append((char) buf[i]); else sb.append('.'); } else sb.append(' '); } return sb.toString(); } public static String format(byte[] buf) { return format(buf, 80); } public static String format(byte[] buf, int width) { int bs = (width - 8) / 4; int i = 0; StringBuffer sb = new StringBuffer(); do { for (int j = 0; j < 6; j++) { sb.append(hexchars[(i << (j*4) & 0xF00000) >> 20]); } sb.append('\t'); sb.append(toHex(buf, i, bs)); sb.append(' '); sb.append(toAscii(buf, i, bs)); sb.append('\n'); i += bs; } while (i < buf.length); return sb.toString(); } public static void print(byte[] buf) { print(buf, System.err); } public static void print(byte[] buf, int width) { print(buf, width, System.err); } public static void print(byte[] buf, int width, PrintStream out) { out.print(format(buf, width)); } public static void print(byte[] buf, PrintStream out) { out.print(format(buf)); } /** * Returns a string which can be written to a Java source file as part * of a static initializer for a byte array. * Returns data in the format 0xAB, 0xCD, .... * use like: * javafile.print("byte[] data = {") * javafile.print(Hexdump.toByteArray(data)); * javafile.println("};"); */ public static String toByteArray(byte[] buf) { return toByteArray(buf, 0, buf.length); } /** * Returns a string which can be written to a Java source file as part * of a static initializer for a byte array. * Returns data in the format 0xAB, 0xCD, .... * use like: * javafile.print("byte[] data = {") * javafile.print(Hexdump.toByteArray(data)); * javafile.println("};"); */ public static String toByteArray(byte[] buf, int ofs, int len) { StringBuffer sb = new StringBuffer(); for (int i = ofs; i < len && i < buf.length; i++) { sb.append('0'); sb.append('x'); sb.append(hexchars[(buf[i] & 0xF0) >> 4]); sb.append(hexchars[buf[i] & 0x0F]); if ((i+1) < len && (i+1) < buf.length) sb.append(','); } return sb.toString(); } } libmatthew-java-0.8.1/cx/ath/matthew/io/ 0000755 0001750 0001750 00000000000 13273414417 016523 5 ustar mjj29 mjj29 libmatthew-java-0.8.1/cx/ath/matthew/io/test2.java 0000644 0001750 0001750 00000003070 13273414417 020427 0 ustar mjj29 mjj29 /* * Java IO Library * * Copyright (c) Matthew Johnson 2005 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * To Contact the author, please email src@matthew.ath.cx * */ package cx.ath.matthew.io; import java.io.BufferedReader; import java.io.InputStreamReader; class test2 { public static void main(String[] args) throws Exception { BufferedReader in = new BufferedReader(new InputStreamReader(new ExecInputStream(System.in, "xsltproc mcr.xsl -"))); String s; while (null != (s = in.readLine())) System.out.println(s); } } libmatthew-java-0.8.1/cx/ath/matthew/io/TeeOutputStream.java 0000644 0001750 0001750 00000010214 13273414417 022476 0 ustar mjj29 mjj29 /* * Java Tee Stream Library * * Copyright (c) Matthew Johnson 2005 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * To Contact the author, please email src@matthew.ath.cx * */ package cx.ath.matthew.io; import java.io.File; import java.io.FileOutputStream; import java.io.FilterOutputStream; import java.io.OutputStream; import java.io.IOException; /** * Class to copy a stream to another stream or file as it is being sent through a stream pipe * E.g. *
* PrintWriter r = new PrintWriter(new TeeOutputStream(new FileOutputStream("file"), new File("otherfile"))); **/ public class TeeOutputStream extends FilterOutputStream { private File f; private OutputStream out; private OutputStream fos; /** * Create a new TeeOutputStream on the given OutputStream * and copy the stream to the other OuputStream. * @param os Writes to this OutputStream * @param tos Write to this OutputStream */ public TeeOutputStream(OutputStream os, OutputStream tos) throws IOException { super(os); this.out = os; this.fos = tos; } /** * Create a new TeeOutputStream on the given OutputStream * and copy the stream to the given File. * @param os Writes to this OutputStream * @param f Write to this File * @param append Append to file not overwrite */ public TeeOutputStream(OutputStream os, File f, boolean append) throws IOException { super(os); this.out = os; this.fos = new FileOutputStream(f, append); } /** * Create a new TeeOutputStream on the given OutputStream * and copy the stream to the given File. * @param os Writes to this OutputStream * @param f Write to this File */ public TeeOutputStream(OutputStream os, File f) throws IOException { super(os); this.out = os; this.fos = new FileOutputStream(f); } /** * Create a new TeeOutputStream on the given OutputStream * and copy the stream to the given File. * @param os Writes to this OutputStream * @param f Write to this File * @param append Append to file not overwrite */ public TeeOutputStream(OutputStream os, String f, boolean append) throws IOException { this(os, new File(f), append); } /** * Create a new TeeOutputStream on the given OutputStream * and copy the stream to the given File. * @param os Writes to this OutputStream * @param f Write to this File */ public TeeOutputStream(OutputStream os, String f) throws IOException { this(os, new File(f)); } public void close() throws IOException { out.close(); fos.close(); } public void flush() throws IOException { fos.flush(); out.flush(); } public void write(int b) throws IOException { fos.write(b); out.write(b); } public void write(byte[] b) throws IOException { fos.write(b); out.write(b); } public void write(byte[] b, int off, int len) throws IOException { fos.write(b, off, len); out.write(b, off, len); } public void finalize() { try { close(); } catch (Exception e) {} } } libmatthew-java-0.8.1/cx/ath/matthew/io/test3.java 0000644 0001750 0001750 00000003264 13273414417 020435 0 ustar mjj29 mjj29 /* * Java IO Library * * Copyright (c) Matthew Johnson 2005 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * To Contact the author, please email src@matthew.ath.cx * */ package cx.ath.matthew.io; import java.io.PrintWriter; import java.io.BufferedReader; import java.io.InputStreamReader; class test3 { public static void main(String[] args) throws Exception { String file = args[0]; PrintWriter p = new PrintWriter(new TeeOutputStream(System.out, file)); BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); String s; while (null != (s = r.readLine())) p.println(s); p.close(); r.close(); } } libmatthew-java-0.8.1/cx/ath/matthew/io/ExecInputStream.java 0000644 0001750 0001750 00000011464 13273414417 022454 0 ustar mjj29 mjj29 /* * Java Exec Pipe Library * * Copyright (c) Matthew Johnson 2005 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * To Contact the author, please email src@matthew.ath.cx * */ package cx.ath.matthew.io; import java.io.FilterInputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; /** * Class to pipe an InputStream through a command using stdin/stdout. * E.g. *
* Reader r = new InputStreamReader(new ExecInputStream(new FileInputStream("file"), "command")); **/ public class ExecInputStream extends FilterInputStream { private Process proc; private InputStream stdout; private OutputStream stdin; private InOutCopier copy; /** * Create a new ExecInputStream on the given InputStream * using the process to filter the stream. * @param is Reads from this InputStream * @param p Filters data through stdin/out on this Process */ public ExecInputStream(InputStream is, Process p) throws IOException { super(is); proc = p; stdin = p.getOutputStream(); stdout = p.getInputStream(); copy = new InOutCopier(in, stdin); copy.start(); } /** * Create a new ExecInputStream on the given InputStream * using the process to filter the stream. * @param is Reads from this InputStream * @param cmd Creates a Process from this string to filter data through stdin/out */ public ExecInputStream(InputStream is, String cmd) throws IOException { this(is, Runtime.getRuntime().exec(cmd)); } /** * Create a new ExecInputStream on the given InputStream * using the process to filter the stream. * @param is Reads from this InputStream * @param cmd Creates a Process from this string array (command, arg, ...) to filter data through stdin/out */ public ExecInputStream(InputStream is, String[] cmd) throws IOException { this(is, Runtime.getRuntime().exec(cmd)); } /** * Create a new ExecInputStream on the given InputStream * using the process to filter the stream. * @param is Reads from this InputStream * @param cmd Creates a Process from this string to filter data through stdin/out * @param env Setup the environment for the command */ public ExecInputStream(InputStream is, String cmd, String[] env) throws IOException { this(is, Runtime.getRuntime().exec(cmd, env)); } /** * Create a new ExecInputStream on the given InputStream * using the process to filter the stream. * @param is Reads from this InputStream * @param cmd Creates a Process from this string array (command, arg, ...) to filter data through stdin/out * @param env Setup the environment for the command */ public ExecInputStream(InputStream is, String[] cmd, String[] env) throws IOException { this(is, Runtime.getRuntime().exec(cmd, env)); } public void close() throws IOException { try { proc.waitFor(); } catch (InterruptedException Ie) {} //copy.close(); try { copy.join(); } catch (InterruptedException Ie) {} stdin.close(); in.close(); stdout.close(); } public void flush() throws IOException { copy.flush(); } public int available() throws IOException { return stdout.available(); } public int read() throws IOException { return stdout.read(); } public int read(byte[] b) throws IOException { return stdout.read(b); } public int read(byte[] b, int off, int len) throws IOException { return stdout.read(b, off, len); } public long skip(long n) throws IOException { return stdout.skip(n); } public void mark(int readlimit) {} public boolean markSupported() { return false; } public void reset() {} public void finalize() { try { close(); } catch (Exception e) {} } } libmatthew-java-0.8.1/cx/ath/matthew/io/TeeInputStream.java 0000644 0001750 0001750 00000010773 13273414417 022307 0 ustar mjj29 mjj29 /* * Java Tee Stream Library * * Copyright (c) Matthew Johnson 2005 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * To Contact the author, please email src@matthew.ath.cx * */ package cx.ath.matthew.io; import java.io.File; import java.io.FileOutputStream; import java.io.FilterInputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; /** * Class to copy a stream to a file or another stream as it is being sent through a stream pipe * E.g. *
* Reader r = new InputStreamReader(new TeeInputStream(new FileInputStream("file"), new File("otherfile"))); **/ public class TeeInputStream extends FilterInputStream { private InputStream in; private OutputStream fos; /** * Create a new TeeInputStream on the given InputStream * and copy the stream to the given File. * @param is Reads from this InputStream * @param tos Write to this OutputStream */ public TeeInputStream(InputStream is, OutputStream tos) throws IOException { super(is); this.in = is; this.fos = tos; } /** * Create a new TeeInputStream on the given InputStream * and copy the stream to the given File. * @param is Reads from this InputStream * @param f Write to this File * @param append Append to file not overwrite */ public TeeInputStream(InputStream is, File f, boolean append) throws IOException { super(is); this.in = is; this.fos = new FileOutputStream(f, append); } /** * Create a new TeeInputStream on the given InputStream * and copy the stream to the given File. * @param is Reads from this InputStream * @param f Write to this File */ public TeeInputStream(InputStream is, File f) throws IOException { super(is); this.in = is; this.fos = new FileOutputStream(f); } /** * Create a new TeeInputStream on the given InputStream * and copy the stream to the given File. * @param is Reads from this InputStream * @param f Write to this File * @param append Append to file not overwrite */ public TeeInputStream(InputStream is, String f, boolean append) throws IOException { this(is, new File(f), append); } /** * Create a new TeeInputStream on the given InputStream * and copy the stream to the given File. * @param is Reads from this InputStream * @param f Write to this File */ public TeeInputStream(InputStream is, String f) throws IOException { this(is, new File(f)); } public void close() throws IOException { in.close(); fos.close(); } public void flush() throws IOException { fos.flush(); } public int available() throws IOException { return in.available(); } public int read() throws IOException { int i = in.read(); if (-1 != i) fos.write(i); return i; } public int read(byte[] b) throws IOException { int c = in.read(b); if (-1 != c) fos.write(b, 0, c); return c; } public int read(byte[] b, int off, int len) throws IOException { int c = in.read(b, off, len); if (-1 != c) fos.write(b, off, c); return c; } public long skip(long n) throws IOException { return in.skip(n); } public void mark(int readlimit) {} public boolean markSupported() { return false; } public void reset() throws IOException { in.reset(); } public void finalize() { try { close(); } catch (Exception e) {} } } libmatthew-java-0.8.1/cx/ath/matthew/io/InOutCopier.java 0000644 0001750 0001750 00000006441 13273414417 021573 0 ustar mjj29 mjj29 /* * Java Exec Pipe Library * * Copyright (c) Matthew Johnson 2005 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * To Contact the author, please email src@matthew.ath.cx * */ package cx.ath.matthew.io; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * Copies from an input stream to an output stream using a Thread. * example: * *
* InputStream a = getInputStream(); * OutputStream b = getOutputStream(); * InOutCopier copier = new InOutCopier(a, b); * copier.start(); * <do stuff that writes to the inputstream> **/ public class InOutCopier extends Thread { private static final int BUFSIZE=1024; private static final int POLLTIME=100; private BufferedInputStream is; private OutputStream os; private boolean enable; /** * Create a copier from an inputstream to an outputstream * @param is The stream to copy from * @param os the stream to copy to */ public InOutCopier(InputStream is, OutputStream os) throws IOException { this.is = new BufferedInputStream(is); this.os = os; this.enable = true; } /** * Force close the stream without waiting for EOF on the source */ public void close() { enable = false; interrupt(); } /** * Flush the outputstream */ public void flush() throws IOException { os.flush(); } /** Start the thread and wait to make sure its really started */ public synchronized void start() { super.start(); try { wait(); } catch (InterruptedException Ie) {} } /** * Copies from the inputstream to the outputstream * until EOF on the inputstream or explicitly closed * @see #close() */ public void run() { byte[] buf = new byte[BUFSIZE]; synchronized (this) { notifyAll(); } while (enable) try { int n = is.read(buf); if (0 > n) break; if (0 < n) { os.write(buf, 0, (n> BUFSIZE? BUFSIZE:n)); os.flush(); } } catch (IOException IOe) { break; } try { os.close(); } catch (IOException IOe) {} } } libmatthew-java-0.8.1/cx/ath/matthew/io/ExecOutputStream.java 0000644 0001750 0001750 00000011156 13273414417 022653 0 ustar mjj29 mjj29 /* * Java Exec Pipe Library * * Copyright (c) Matthew Johnson 2005 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * To Contact the author, please email src@matthew.ath.cx * */ package cx.ath.matthew.io; import java.io.FilterOutputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; /** * Class to pipe an OutputStream through a command using stdin/stdout. * E.g. *
* Writer w = new OutputStreamWriter(new ExecOutputStream(new FileOutputStream("file"), "command")); **/ public class ExecOutputStream extends FilterOutputStream { private Process proc; private InputStream stdout; private OutputStream stdin; private InOutCopier copy; /** * Create a new ExecOutputStream on the given OutputStream * using the process to filter the stream. * @param os Writes to this OutputStream * @param p Filters data through stdin/out on this Process */ public ExecOutputStream(OutputStream os, Process p) throws IOException { super(os); proc = p; stdin = p.getOutputStream(); stdout = p.getInputStream(); copy = new InOutCopier(stdout, out); copy.start(); } /** * Create a new ExecOutputStream on the given OutputStream * using the process to filter the stream. * @param os Writes to this OutputStream * @param cmd Creates a Process from this string to filter data through stdin/out */ public ExecOutputStream(OutputStream os, String cmd) throws IOException { this(os, Runtime.getRuntime().exec(cmd)); } /** * Create a new ExecOutputStream on the given OutputStream * using the process to filter the stream. * @param os Writes to this OutputStream * @param cmd Creates a Process from this string array (command, arg, ...) to filter data through stdin/out */ public ExecOutputStream(OutputStream os, String[] cmd) throws IOException { this(os, Runtime.getRuntime().exec(cmd)); } /** * Create a new ExecOutputStream on the given OutputStream * using the process to filter the stream. * @param os Writes to this OutputStream * @param cmd Creates a Process from this string to filter data through stdin/out * @param env Setup the environment for the command */ public ExecOutputStream(OutputStream os, String cmd, String[] env) throws IOException { this(os, Runtime.getRuntime().exec(cmd, env)); } /** * Create a new ExecOutputStream on the given OutputStream * using the process to filter the stream. * @param os Writes to this OutputStream * @param cmd Creates a Process from this string array (command, arg, ...) to filter data through stdin/out * @param env Setup the environment for the command */ public ExecOutputStream(OutputStream os, String[] cmd, String[] env) throws IOException { this(os, Runtime.getRuntime().exec(cmd, env)); } public void close() throws IOException { stdin.close(); try { proc.waitFor(); } catch (InterruptedException Ie) {} //copy.close(); try { copy.join(); } catch (InterruptedException Ie) {} stdout.close(); out.close(); } public void flush() throws IOException { stdin.flush(); copy.flush(); out.flush(); } public void write(byte[] b) throws IOException { stdin.write(b); } public void write(byte[] b, int off, int len) throws IOException { stdin.write(b, off, len); } public void write(int b) throws IOException { stdin.write(b); } public void finalize() { try { close(); } catch (Exception e) {} } } libmatthew-java-0.8.1/cx/ath/matthew/io/test.java 0000644 0001750 0001750 00000004012 13273414417 020342 0 ustar mjj29 mjj29 /* * Java IO Library * * Copyright (c) Matthew Johnson 2005 * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * To Contact the author, please email src@matthew.ath.cx * */ package cx.ath.matthew.io; import java.io.PrintWriter; import java.io.OutputStreamWriter; class test { public static void main(String[] args) throws Exception { PrintWriter out = new PrintWriter(new OutputStreamWriter(new ExecOutputStream(System.out, "xsltproc mcr.xsl -")));///java cx.ath.matthew.io.findeof"))); out.println(""); out.println(" "); out.println("