1package com.xtremelabs.robolectric.shadows;
2
3import android.util.Log;
4import com.xtremelabs.robolectric.internal.Implementation;
5import com.xtremelabs.robolectric.internal.Implements;
6
7import java.io.PrintStream;
8import java.util.ArrayList;
9import java.util.List;
10
11@Implements(Log.class)
12public class ShadowLog {
13    private static List<LogItem> logs = new ArrayList<LogItem>();
14    public static PrintStream stream;
15
16    @Implementation
17    public static void e(String tag, String msg) {
18        e(tag, msg, null);
19    }
20
21    @Implementation
22    public static void e(String tag, String msg, Throwable throwable) {
23        addLog(Log.ERROR, tag, msg, throwable);
24    }
25
26    @Implementation
27    public static void d(String tag, String msg) {
28        d(tag, msg, null);
29    }
30
31    @Implementation
32    public static void d(String tag, String msg, Throwable throwable) {
33        addLog(Log.DEBUG, tag, msg, throwable);
34    }
35
36    @Implementation
37    public static void i(String tag, String msg) {
38        i(tag, msg, null);
39    }
40
41    @Implementation
42    public static void i(String tag, String msg, Throwable throwable) {
43        addLog(Log.INFO, tag, msg, throwable);
44    }
45
46    @Implementation
47    public static void v(String tag, String msg) {
48        v(tag, msg, null);
49    }
50
51    @Implementation
52    public static void v(String tag, String msg, Throwable throwable) {
53        addLog(Log.VERBOSE, tag, msg, throwable);
54    }
55
56    @Implementation
57    public static void w(String tag, String msg) {
58        w(tag, msg, null);
59    }
60
61    @Implementation
62    public static void w(String tag, Throwable throwable) {
63        w(tag, null, throwable);
64    }
65
66
67    @Implementation
68    public static void w(String tag, String msg, Throwable throwable) {
69        addLog(Log.WARN, tag, msg, throwable);
70    }
71
72    @Implementation
73    public static void wtf(String tag, String msg) {
74        wtf(tag, msg, null);
75    }
76
77    @Implementation
78    public static void wtf(String tag, String msg, Throwable throwable) {
79        addLog(Log.ASSERT, tag, msg, throwable);
80    }
81
82    @Implementation
83    public static boolean isLoggable(String tag, int level) {
84        return stream != null || level >= Log.INFO;
85    }
86
87    private static void addLog(int level, String tag, String msg, Throwable throwable) {
88        if (stream != null) {
89            logToStream(stream, level, tag, msg, throwable);
90        }
91        logs.add(new LogItem(level, tag, msg, throwable));
92    }
93
94
95    private static void logToStream(PrintStream ps, int level, String tag, String msg, Throwable throwable) {
96        final char c;
97        switch (level) {
98            case Log.ASSERT: c = 'A'; break;
99            case Log.DEBUG:  c = 'D'; break;
100            case Log.ERROR:  c = 'E'; break;
101            case Log.WARN:   c = 'W'; break;
102            case Log.INFO:   c = 'I'; break;
103            case Log.VERBOSE:c = 'V'; break;
104            default:         c = '?';
105        }
106        ps.println(c + "/" + tag + ": " + msg);
107        if (throwable != null) {
108            throwable.printStackTrace(ps);
109        }
110    }
111
112    public static List<LogItem> getLogs() {
113        return logs;
114    }
115
116    public static void reset() {
117        logs.clear();
118    }
119
120    public static class LogItem {
121        public final int type;
122        public final String tag;
123        public final String msg;
124        public final Throwable throwable;
125
126        public LogItem(int type, String tag, String msg, Throwable throwable) {
127            this.type = type;
128            this.tag = tag;
129            this.msg = msg;
130            this.throwable = throwable;
131        }
132    }
133}
134