001package gu.sql2java;
002
003import java.io.PrintStream;
004import java.io.PrintWriter;
005import java.io.StringWriter;
006import java.util.regex.Matcher;
007import java.util.regex.Pattern;
008
009/**
010 * 简单日志输出工具类
011 * @author guyadong
012 *
013 */
014public class SimpleLog {
015        /** 占位符 */
016        private static final String DELIM_STR = "(\\{\\}|%s)";
017        private static final Object[] EMPTY_ARGS = new Object[0];
018        
019        private static void log(PrintStream printStream,int level, String format, Object ... args){
020                if(null == printStream || null == format){
021                        return;
022                }
023                if(null == args){
024                        args = EMPTY_ARGS;
025                }
026                StringBuilder buffer = new StringBuilder(format.length() + 64);
027                int beginIndex = 0,count = 0;
028                Pattern pattern = Pattern.compile(DELIM_STR);
029                Matcher matcher = pattern.matcher(format);
030                while(matcher.find()){
031                        buffer.append(format.substring(beginIndex,matcher.start()));
032                        try{
033                                buffer.append(args[count++]);
034                        }catch(IndexOutOfBoundsException e){
035                                // 数组越界时对应占位符填null
036                                buffer.append("null");
037                        }
038                        beginIndex = matcher.end();
039                }
040                buffer.append(format.substring(beginIndex,format.length()));
041
042                Thread currentThread = Thread.currentThread();
043                StackTraceElement stackTrace = currentThread.getStackTrace()[level];
044                printStream.printf("[%s] (%s:%d) %s\n",
045                                currentThread.getName(),
046                                stackTrace.getFileName(),
047                                stackTrace.getLineNumber(),
048                                buffer.toString());
049        }
050        /**
051         * 向{@code printStream}输出日志信息<br>
052         * example:
053         * <pre>
054         * log("name : {},age:{}","tom",23);
055         * </pre>
056         * @param printStream
057         * @param format 格式字符串,采用"{}"或"%s"为占位符,占位符个数要与{@code args}数组长度匹配
058         * @param args 填充占位符的参数列表,如果数量小于占位符个数则多出的占位符填充"null"
059         */
060        public static void log(PrintStream printStream,String format, Object ... args){
061                log(printStream,3,format,args); 
062        }
063        /**
064         * @param output 是否输出
065         * @param printStream
066         * @param format 格式字符串
067         * @param args 填充占位符的参数列表
068         * @see #log(PrintStream, String, Object...)
069         */
070        public static void log(boolean output,PrintStream printStream,String format, Object ... args){
071                if(output){
072                        log(printStream,3,format,args);
073                }
074        }
075        private static final String formatByCount(int c){
076                StringBuffer buffer = new StringBuffer();
077                for(int i=0;i<c;++i){
078                        if(i>0){
079                                buffer.append(",");
080                        }
081                        buffer.append("{}");
082                }
083                return buffer.toString();
084        }
085        /**
086         * 向控制台输出日志信息<br>
087         * @param output 是否输出
088         * @param arg
089         * @see #log(PrintStream, String, Object...)
090         */
091        public static void logObjects(Object arg){
092                log(System.out,3,formatByCount(1),new Object[]{arg});
093        }
094        /**
095         * 向控制台输出日志信息<br>
096         * @param output 是否输出
097         * @param args
098         * @see #log(PrintStream, String, Object...)
099         */
100        public static void logObjects(Object arg,Object ... args){
101                Object[] array = new Object[args.length+1];
102                array[0] = arg;
103                System.arraycopy(args, 0, array, 1, args.length);
104                log(System.out,3,formatByCount(args.length),array);
105        }
106        /**
107         * 向控制台输出日志信息<br>
108         * @param format 格式字符串,采用"{}"或"%s"为占位符
109         * @param args
110         * @see #log(PrintStream, String, Object...)
111         */
112        public static void log(String format, Object ... args){
113                log(System.out,3,format,args);
114        }
115        /**
116         * 向控制台输出日志信息<br>
117         * @param output 是否输出
118         * @param format 格式字符串,采用"{}"或"%s"为占位符
119         * @param args
120         * @see #log(PrintStream, String, Object...)
121         */
122        public static void log(boolean output,String format, Object ... args){
123                if(output){
124                        log(System.out,3,format,args);
125                }
126        }
127        
128        private static final String stackTraceOf(Throwable e){
129                if(e == null){                  
130                        e = new NullPointerException("e is null");
131                }
132                
133                StringWriter writer = new StringWriter();
134                PrintWriter pw = new PrintWriter(writer);
135                e.printStackTrace(pw);
136                return writer.toString();
137        }
138        public static void log(String msg,Throwable e){
139                log(System.out,3,"{}\n{}",msg,stackTraceOf(e));
140        }
141        public static void log(Throwable e){
142                log(System.out,3,"{}",stackTraceOf(e));
143        }
144}