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
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.
19 package org
.tianocore
.build
.global
;
21 import java
.io
.BufferedReader
;
22 import java
.io
.BufferedWriter
;
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
;
31 import java
.util
.Vector
;
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
;
40 import org
.tianocore
.build
.id
.FpdModuleIdentification
;
41 import org
.tianocore
.common
.logger
.EdkLog
;
42 import org
.tianocore
.common
.logger
.LogMethod
;
44 public class GenBuildLogger
extends DefaultLogger
implements LogMethod
{
46 Project project
= null;
49 /// Time of the start of the build
51 private long startTime
= System
.currentTimeMillis();
54 /// flag to present whether cache all msg or not
55 /// true means to cache.
57 private static boolean flag
= false;
59 private static Map
<FpdModuleIdentification
, List
<String
>> map
= new LinkedHashMap
<FpdModuleIdentification
, List
<String
> >(256);
61 private FpdModuleIdentification id
= null;
63 public GenBuildLogger () {
67 public GenBuildLogger (Project project
) {
68 this.project
= project
;
72 Rules: flag = false: means no cache Action: Print it to console
74 flag = true: mean cache all msg exception some special Action: loglevel
75 is EDK_ALWAYS -- Print but no cache loglevel is EDK_ERROR -- Print and
76 cache the msg others -- No print and cache the msg
78 public synchronized void putMessage(Object msgSource
, int msgLevel
, String msg
) {
79 if (this.project
== null) {
84 // If msgLevel is always print, then print it
87 case EdkLog
.EDK_ALWAYS
:
91 log(msgSource
, msg
, Project
.MSG_ERR
);
93 case EdkLog
.EDK_ERROR
:
94 log(msgSource
, msg
, Project
.MSG_ERR
);
96 case EdkLog
.EDK_WARNING
:
97 log(msgSource
, msg
, Project
.MSG_WARN
);
100 log(msgSource
, msg
, Project
.MSG_INFO
);
102 case EdkLog
.EDK_VERBOSE
:
103 log(msgSource
, msg
, Project
.MSG_VERBOSE
);
105 case EdkLog
.EDK_DEBUG
:
106 log(msgSource
, msg
, Project
.MSG_DEBUG
);
111 public static void flushErrorModuleLog(FpdModuleIdentification errorModuleId
) {
112 List
<String
> errorLogs
= map
.get(errorModuleId
);
113 if (errorLogs
!= null) {
114 EdkLog
.log("ErrorLog", EdkLog
.EDK_ERROR
, errorModuleId
+ " error logs: ");
115 for(int i
= 0; i
< errorLogs
.size(); i
++) {
116 EdkLog
.log(EdkLog
.EDK_ERROR
, errorLogs
.get(i
));
121 public void flushToFile(File file
) {
123 // Put all messages in map to file
125 String msg
= "Writing log to file [" + file
.getPath() + "]";
126 log("Logging", msg
, Project
.MSG_INFO
);
128 BufferedWriter bw
= new BufferedWriter(new FileWriter(file
));
129 Iterator
<FpdModuleIdentification
> iter
= map
.keySet().iterator();
130 List
<String
> mainLogs
= null;
131 while (iter
.hasNext()) {
132 FpdModuleIdentification item
= iter
.next();
134 mainLogs
= map
.get(item
);
137 bw
.write(">>>>>>>>>>>>>");
138 bw
.write(" " + item
+ " Build Log ");
139 bw
.write(">>>>>>>>>>>>>");
141 List
<String
> allMessages
= map
.get(item
);
142 for(int i
= 0; i
< allMessages
.size(); i
++) {
143 bw
.write(allMessages
.get(i
));
147 if (mainLogs
!= null) {
148 bw
.write(">>>>>>>>>>>>>");
149 bw
.write(" Main Logs (already print to command) ");
150 bw
.write(">>>>>>>>>>>>>");
152 for(int i
= 0; i
< mainLogs
.size(); i
++) {
153 bw
.write(mainLogs
.get(i
));
159 } catch (IOException e
) {
160 new BuildException("Writing log error. " + e
.getMessage());
165 private void log(Object msgSource
, String msg
, int level
) {
166 if (msgSource
instanceof Task
) {
167 ((Task
)msgSource
).getProject().log((Task
)msgSource
, msg
, level
);
168 } else if (msgSource
instanceof String
){
170 // Pad 12 space to keep message in unify format
172 msg
= msg
.replaceAll("\n", "\n ");
173 this.project
.log(String
.format("%12s", "[" + msgSource
+ "] ") + msg
, level
);
175 this.project
.log(msg
, level
);
178 public void targetStarted(BuildEvent event
) {
180 super.targetStarted(event
);
184 public void messageLogged(BuildEvent event
) {
186 int currentLevel
= event
.getPriority();
188 // If current level is upper than Ant Level, skip it
190 if (currentLevel
<= this.msgOutputLevel
) {
191 String originalMessage
= event
.getMessage();
193 StringBuffer message
= new StringBuffer();
194 if (!emacsMode
&& event
.getTask() != null) {
195 String label
= String
.format("%12s", "[" + event
.getTask().getTaskName() + "] ");
197 // Append label first
199 message
.append(label
);
202 // Format all output message's line separator
205 BufferedReader r
= new BufferedReader(new StringReader(originalMessage
));
206 boolean ifFirstLine
= true;
208 while ((line
= r
.readLine()) != null) {
210 message
.append(StringUtils
.LINE_SEP
);
213 message
.append(line
);
215 } catch (IOException e
) {
216 message
.append(originalMessage
);
219 message
.append(originalMessage
);
222 String msg
= message
.toString();
223 if (currentLevel
== Project
.MSG_ERR
) {
224 printMessage(msg
, err
, currentLevel
);
225 } else if(currentLevel
== Project
.MSG_WARN
) {
226 printMessage(msg
, out
, currentLevel
);
228 printMessage(msg
, out
, currentLevel
);
234 public static void setCacheEnable(boolean enable
) {
238 protected synchronized void log(String message
) {
242 if (map
.containsKey(this.id
)) {
243 map
.get(this.id
).add(message
);
245 List
<String
> list
= new Vector
<String
>(1024);
247 map
.put(this.id
, list
);
251 public Object
clone() {
252 GenBuildLogger newLogger
= new GenBuildLogger();
254 // Transfer emacs mode, out, err, level to new Logger
256 newLogger
.setEmacsMode(this.emacsMode
);
257 newLogger
.setOutputPrintStream(this.out
);
258 newLogger
.setErrorPrintStream(this.err
);
259 newLogger
.setMessageOutputLevel(this.msgOutputLevel
);
264 newLogger
.project
= this.project
;
268 public void setId(FpdModuleIdentification id
) {
272 public void buildFinished(BuildEvent event
) {
273 Throwable error
= event
.getException();
274 StringBuffer message
= new StringBuffer();
277 message
.append(StringUtils
.LINE_SEP
);
278 message
.append("BUILD SUCCESSFUL");
280 message
.append(StringUtils
.LINE_SEP
);
281 message
.append("BUILD FAILED");
282 message
.append(StringUtils
.LINE_SEP
);
284 if (Project
.MSG_DEBUG
<= msgOutputLevel
285 || !(error
instanceof BuildException
)) {
286 message
.append(StringUtils
.getStackTrace(error
));
288 if (error
instanceof BuildException
) {
289 message
.append(error
.toString()).append(lSep
);
291 message
.append(error
.getMessage()).append(lSep
);
295 message
.append(StringUtils
.LINE_SEP
);
296 message
.append("Total time: ");
297 message
.append(formatTime(System
.currentTimeMillis() - startTime
));
299 String msg
= message
.toString();
301 printMessage(msg
, out
, Project
.MSG_VERBOSE
);
303 printMessage(msg
, err
, Project
.MSG_ERR
);