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