1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.databinding.tool.util;
18 
19 import android.databinding.tool.processing.ScopedErrorReport;
20 import android.databinding.tool.processing.ScopedException;
21 import android.databinding.tool.processing.scopes.LocationScopeProvider;
22 
23 import java.io.PrintWriter;
24 import java.io.StringWriter;
25 
26 import javax.lang.model.element.Element;
27 import javax.tools.Diagnostic;
28 import javax.tools.Diagnostic.Kind;
29 
30 public class L {
31     private static boolean sEnableDebug = false;
32     private static final Client sSystemClient = new Client() {
33         @Override
34         public void printMessage(Kind kind, String message, Element element) {
35             if (kind == Kind.ERROR) {
36                 System.err.println(message);
37             } else {
38                 System.out.println(message);
39             }
40         }
41     };
42 
43     private static Client sClient = sSystemClient;
44 
setClient(Client systemClient)45     public static void setClient(Client systemClient) {
46         sClient = systemClient;
47     }
48 
setDebugLog(boolean enabled)49     public static void setDebugLog(boolean enabled) {
50         sEnableDebug = enabled;
51     }
52 
d(String msg, Object... args)53     public static void d(String msg, Object... args) {
54         if (sEnableDebug) {
55             printMessage(null, Diagnostic.Kind.NOTE, String.format(msg, args));
56         }
57     }
58 
d(Element element, String msg, Object... args)59     public static void d(Element element, String msg, Object... args) {
60         if (sEnableDebug) {
61             printMessage(element, Diagnostic.Kind.NOTE, String.format(msg, args));
62         }
63     }
64 
d(Throwable t, String msg, Object... args)65     public static void d(Throwable t, String msg, Object... args) {
66         if (sEnableDebug) {
67             printMessage(null, Diagnostic.Kind.NOTE,
68                     String.format(msg, args) + " " + getStackTrace(t));
69         }
70     }
71 
w(String msg, Object... args)72     public static void w(String msg, Object... args) {
73         printMessage(null, Kind.WARNING, String.format(msg, args));
74     }
75 
w(Element element, String msg, Object... args)76     public static void w(Element element, String msg, Object... args) {
77         printMessage(element, Kind.WARNING, String.format(msg, args));
78     }
79 
w(Throwable t, String msg, Object... args)80     public static void w(Throwable t, String msg, Object... args) {
81         printMessage(null, Kind.WARNING,
82                 String.format(msg, args) + " " + getStackTrace(t));
83     }
84 
tryToThrowScoped(Throwable t, String fullMessage)85     private static void tryToThrowScoped(Throwable t, String fullMessage) {
86         if (t instanceof ScopedException) {
87             ScopedException ex = (ScopedException) t;
88             if (ex.isValid()) {
89                 throw ex;
90             }
91         }
92         ScopedException ex = new ScopedException(fullMessage);
93         if (ex.isValid()) {
94             throw ex;
95         }
96     }
97 
e(String msg, Object... args)98     public static void e(String msg, Object... args) {
99         String fullMsg = String.format(msg, args);
100         tryToThrowScoped(null, fullMsg);
101         printMessage(null, Diagnostic.Kind.ERROR, fullMsg);
102     }
103 
e(Element element, String msg, Object... args)104     public static void e(Element element, String msg, Object... args) {
105         String fullMsg = String.format(msg, args);
106         tryToThrowScoped(null, fullMsg);
107         printMessage(element, Diagnostic.Kind.ERROR, fullMsg);
108     }
109 
e(Throwable t, String msg, Object... args)110     public static void e(Throwable t, String msg, Object... args) {
111         String fullMsg = String.format(msg, args);
112         tryToThrowScoped(t, fullMsg);
113         printMessage(null, Diagnostic.Kind.ERROR,
114                 fullMsg + " " + getStackTrace(t));
115     }
116 
printMessage(Element element, Diagnostic.Kind kind, String message)117     private static void printMessage(Element element, Diagnostic.Kind kind, String message) {
118         if (kind == Kind.WARNING) {
119             // try to convert it to a scoped message
120             ScopedException ex = new ScopedException(message);
121             if (ex.isValid()) {
122                 sClient.printMessage(kind, ex.createHumanReadableMessage(), element);
123                 return;
124             }
125         }
126         sClient.printMessage(kind, message, element);
127         if (kind == Diagnostic.Kind.ERROR) {
128             throw new RuntimeException("failure, see logs for details.\n" + message);
129         }
130     }
131 
isDebugEnabled()132     public static boolean isDebugEnabled() {
133         return sEnableDebug;
134     }
135 
136     public interface Client {
printMessage(Diagnostic.Kind kind, String message, Element element)137         void printMessage(Diagnostic.Kind kind, String message, Element element);
138     }
139 
getStackTrace(Throwable t)140     private static String getStackTrace(Throwable t) {
141         StringWriter sw = new StringWriter();
142         PrintWriter pw = new PrintWriter(sw);
143         try {
144             t.printStackTrace(pw);
145         } finally {
146             pw.close();
147         }
148         return sw.toString();
149     }
150 }
151