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