]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - Tools/Java/Source/GenBuild/org/tianocore/build/global/GenBuildLogger.java
Fixed EDKT370&372
[mirror_edk2.git] / Tools / Java / Source / GenBuild / org / tianocore / build / global / GenBuildLogger.java
... / ...
CommitLineData
1/*++\r
2\r
3 Copyright (c) 2006, Intel Corporation\r
4 All rights reserved. This program and the accompanying materials\r
5 are licensed and made available under the terms and conditions of the BSD License\r
6 which accompanies this distribution. The full text of the license may be found at\r
7 http://opensource.org/licenses/bsd-license.php\r
8\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12 Module Name:\r
13 GenBuildLogger.java\r
14\r
15 Abstract:\r
16\r
17 --*/\r
18\r
19package org.tianocore.build.global;\r
20\r
21import java.io.BufferedReader;\r
22import java.io.BufferedWriter;\r
23import java.io.File;\r
24import java.io.FileWriter;\r
25import java.io.IOException;\r
26import java.io.StringReader;\r
27import java.util.Iterator;\r
28import java.util.LinkedHashMap;\r
29import java.util.List;\r
30import java.util.Map;\r
31import java.util.Vector;\r
32\r
33import org.apache.tools.ant.BuildEvent;\r
34import org.apache.tools.ant.BuildException;\r
35import org.apache.tools.ant.DefaultLogger;\r
36import org.apache.tools.ant.Project;\r
37import org.apache.tools.ant.Task;\r
38import org.apache.tools.ant.util.StringUtils;\r
39\r
40import org.tianocore.build.id.FpdModuleIdentification;\r
41import org.tianocore.common.logger.EdkLog;\r
42import org.tianocore.common.logger.LogMethod;\r
43\r
44public class GenBuildLogger extends DefaultLogger implements LogMethod {\r
45 \r
46 Project project = null;\r
47 ///\r
48 /// Time of the start of the build \r
49 /// \r
50 private long startTime = System.currentTimeMillis();\r
51 ///\r
52 /// flag to present whether cache all msg or not\r
53 /// true means to cache.\r
54 ///\r
55 private static boolean flag = false;\r
56 \r
57 private static boolean enableFlag = true;\r
58\r
59 private static Map<FpdModuleIdentification, List<String>> map = new LinkedHashMap<FpdModuleIdentification, List<String> >(256);\r
60 \r
61 private FpdModuleIdentification id = null;\r
62 \r
63 public GenBuildLogger () {\r
64 \r
65 }\r
66\r
67 public GenBuildLogger (Project project) {\r
68 this.project = project;\r
69 }\r
70\r
71 /**\r
72 Rules: flag = false: means no cache Action: Print it to console\r
73 \r
74 flag = true: mean cache all msg exception some special Action: loglevel\r
75 is EDK_ALWAYS -- Print but no cache loglevel is EDK_ERROR -- Print and\r
76 cache the msg others -- No print and cache the msg\r
77 **/\r
78 public synchronized void putMessage(Object msgSource, int msgLevel, String msg) {\r
79 if (this.project == null) {\r
80 return;\r
81 }\r
82 //\r
83 // If msgLevel is always print, then print it\r
84 //\r
85 switch (msgLevel) {\r
86 case EdkLog.EDK_ALWAYS:\r
87 //\r
88 // Do some special\r
89 //\r
90 log(msgSource, msg, Project.MSG_ERR);\r
91 break;\r
92 case EdkLog.EDK_ERROR:\r
93 log(msgSource, msg, Project.MSG_ERR);\r
94 break;\r
95 case EdkLog.EDK_WARNING:\r
96 log(msgSource, msg, Project.MSG_WARN);\r
97 break;\r
98 case EdkLog.EDK_INFO:\r
99 log(msgSource, msg, Project.MSG_INFO);\r
100 break;\r
101 case EdkLog.EDK_VERBOSE:\r
102 log(msgSource, msg, Project.MSG_VERBOSE);\r
103 break;\r
104 case EdkLog.EDK_DEBUG:\r
105 log(msgSource, msg, Project.MSG_DEBUG);\r
106 break;\r
107 }\r
108 }\r
109 \r
110 public static void flushErrorModuleLog(FpdModuleIdentification errorModuleId) {\r
111 List<String> errorLogs = map.get(errorModuleId);\r
112 if (errorLogs != null) {\r
113 EdkLog.log("ErrorLog", EdkLog.EDK_ERROR, errorModuleId + " error logs: ");\r
114 for(int i = 0; i < errorLogs.size(); i++) {\r
115 EdkLog.log(EdkLog.EDK_ERROR, errorLogs.get(i));\r
116 }\r
117 }\r
118 }\r
119\r
120 public void flushToFile(File file) {\r
121 //\r
122 // Put all messages in map to file\r
123 //\r
124 String msg = "Writing log to file [" + file.getPath() + "]";\r
125 log("Logging", msg, Project.MSG_INFO);\r
126 try {\r
127 BufferedWriter bw = new BufferedWriter(new FileWriter(file));\r
128 Iterator<FpdModuleIdentification> iter = map.keySet().iterator();\r
129 List<String> mainLogs = null;\r
130 while (iter.hasNext()) {\r
131 FpdModuleIdentification item = iter.next();\r
132 if(item == null) {\r
133 mainLogs = map.get(item);\r
134 continue ;\r
135 }\r
136 bw.write(">>>>>>>>>>>>>");\r
137 bw.write(" " + item + " Build Log ");\r
138 bw.write(">>>>>>>>>>>>>");\r
139 bw.newLine();\r
140 List<String> allMessages = map.get(item);\r
141 for(int i = 0; i < allMessages.size(); i++) {\r
142 bw.write(allMessages.get(i));\r
143 bw.newLine();\r
144 }\r
145 }\r
146 if (mainLogs != null) {\r
147 bw.write(">>>>>>>>>>>>>");\r
148 bw.write(" Main Logs (already print to command) ");\r
149 bw.write(">>>>>>>>>>>>>");\r
150 bw.newLine();\r
151 for(int i = 0; i < mainLogs.size(); i++) {\r
152 bw.write(mainLogs.get(i));\r
153 bw.newLine();\r
154 }\r
155 }\r
156 bw.flush();\r
157 bw.close();\r
158 } catch (IOException e) {\r
159 new BuildException("Writing log error. " + e.getMessage());\r
160 }\r
161 \r
162 }\r
163 \r
164 private void log(Object msgSource, String msg, int level) {\r
165 if (msgSource instanceof Task) {\r
166 ((Task)msgSource).getProject().log((Task)msgSource, msg, level);\r
167 } else if (msgSource instanceof String){\r
168 //\r
169 // Pad 12 space to keep message in unify format\r
170 //\r
171 msg = msg.replaceAll("\n", "\n ");\r
172 this.project.log(String.format("%12s", "[" + msgSource + "] ") + msg, level);\r
173 } else {\r
174 this.project.log(msg, level);\r
175 }\r
176 }\r
177 public void targetStarted(BuildEvent event) {\r
178 if (!flag) {\r
179 super.targetStarted(event);\r
180 }\r
181 }\r
182 \r
183 public void messageLogged(BuildEvent event) {\r
184 int currentLevel = event.getPriority();\r
185 //\r
186 // If current level is upper than Ant Level, skip it\r
187 //\r
188 if (currentLevel <= this.msgOutputLevel) {\r
189 String originalMessage = event.getMessage();\r
190\r
191 StringBuffer message = new StringBuffer();\r
192 if (!emacsMode && event.getTask() != null) {\r
193 String label = String.format("%12s", "[" + event.getTask().getTaskName() + "] ");\r
194 //\r
195 // Append label first\r
196 //\r
197 message.append(label);\r
198 \r
199 //\r
200 // Format all output message's line separator\r
201 //\r
202 try {\r
203 BufferedReader r = new BufferedReader(new StringReader(originalMessage));\r
204 boolean ifFirstLine = true;\r
205 String line = null;\r
206 while ((line = r.readLine()) != null) {\r
207 if (!ifFirstLine) {\r
208 message.append(StringUtils.LINE_SEP);\r
209 }\r
210 ifFirstLine = false;\r
211 message.append(line);\r
212 }\r
213 } catch (IOException e) {\r
214 message.append(originalMessage);\r
215 }\r
216 } else {\r
217 message.append(originalMessage);\r
218 }\r
219\r
220 String msg = message.toString();\r
221 if (currentLevel == Project.MSG_ERR) {\r
222 printMessage(msg, err, currentLevel);\r
223 } else if(currentLevel == Project.MSG_WARN) {\r
224 printMessage(msg, out, currentLevel);\r
225 } else if(!flag) {\r
226 printMessage(msg, out, currentLevel);\r
227 } \r
228 log(msg);\r
229 }\r
230 }\r
231 \r
232 public static void setCacheEnable(boolean enable) {\r
233 flag = enable;\r
234 }\r
235 \r
236 public static void maskAllLog(boolean enable) {\r
237 enableFlag = !enable;\r
238 }\r
239 \r
240 protected synchronized void log(String message) {\r
241 //\r
242 // cache log\r
243 //\r
244 if (map.containsKey(this.id)) {\r
245 map.get(this.id).add(message);\r
246 } else {\r
247 List<String> list = new Vector<String>(1024);\r
248 list.add(message);\r
249 map.put(this.id, list);\r
250 }\r
251 }\r
252 \r
253 public Object clone() {\r
254 GenBuildLogger newLogger = new GenBuildLogger();\r
255 //\r
256 // Transfer emacs mode, out, err, level to new Logger\r
257 //\r
258 newLogger.setEmacsMode(this.emacsMode);\r
259 newLogger.setOutputPrintStream(this.out);\r
260 newLogger.setErrorPrintStream(this.err);\r
261 newLogger.setMessageOutputLevel(this.msgOutputLevel);\r
262 \r
263 //\r
264 // Transfer project\r
265 //\r
266 newLogger.project = this.project;\r
267 return newLogger;\r
268 }\r
269\r
270 public void setId(FpdModuleIdentification id) {\r
271 this.id = id;\r
272 }\r
273\r
274 public void buildFinished(BuildEvent event) {\r
275 Throwable error = event.getException();\r
276 StringBuffer message = new StringBuffer();\r
277\r
278 if (error == null) {\r
279 message.append(StringUtils.LINE_SEP);\r
280 message.append("BUILD SUCCESSFUL");\r
281 } else {\r
282 message.append(StringUtils.LINE_SEP);\r
283 message.append("BUILD FAILED");\r
284 message.append(StringUtils.LINE_SEP);\r
285\r
286 if (Project.MSG_DEBUG <= msgOutputLevel\r
287 || !(error instanceof BuildException)) {\r
288 message.append(StringUtils.getStackTrace(error));\r
289 } else {\r
290 if (error instanceof BuildException) {\r
291 message.append(error.toString()).append(lSep);\r
292 } else {\r
293 message.append(error.getMessage()).append(lSep);\r
294 }\r
295 }\r
296 }\r
297 message.append(StringUtils.LINE_SEP);\r
298 message.append("Total time: ");\r
299 message.append(formatTime(System.currentTimeMillis() - startTime));\r
300\r
301 String msg = message.toString();\r
302 if (error == null) {\r
303 printMessage(msg, out, Project.MSG_VERBOSE);\r
304 } else {\r
305 printMessage(msg, err, Project.MSG_ERR);\r
306 }\r
307 log(msg);\r
308 }\r
309}