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;
48 /// Time of the start of the build
50 private long startTime
= System
.currentTimeMillis();
52 /// flag to present whether cache all msg or not
53 /// true means to cache.
55 private static boolean flag
= false;
57 private static boolean enableFlag
= true;
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) {
83 // If msgLevel is always print, then print it
86 case EdkLog
.EDK_ALWAYS
:
90 log(msgSource
, msg
, Project
.MSG_ERR
);
92 case EdkLog
.EDK_ERROR
:
93 log(msgSource
, msg
, Project
.MSG_ERR
);
95 case EdkLog
.EDK_WARNING
:
96 log(msgSource
, msg
, Project
.MSG_WARN
);
99 log(msgSource
, msg
, Project
.MSG_INFO
);
101 case EdkLog
.EDK_VERBOSE
:
102 log(msgSource
, msg
, Project
.MSG_VERBOSE
);
104 case EdkLog
.EDK_DEBUG
:
105 log(msgSource
, msg
, Project
.MSG_DEBUG
);
110 public static void flushErrorModuleLog(FpdModuleIdentification errorModuleId
) {
111 List
<String
> errorLogs
= map
.get(errorModuleId
);
112 if (errorLogs
!= null) {
113 EdkLog
.log("ErrorLog", EdkLog
.EDK_ERROR
, errorModuleId
+ " error logs: ");
114 for(int i
= 0; i
< errorLogs
.size(); i
++) {
115 EdkLog
.log(EdkLog
.EDK_ERROR
, errorLogs
.get(i
));
120 public void flushToFile(File file
) {
122 // Put all messages in map to file
124 String msg
= "Writing log to file [" + file
.getPath() + "]";
125 log("Logging", msg
, Project
.MSG_INFO
);
127 BufferedWriter bw
= new BufferedWriter(new FileWriter(file
));
128 Iterator
<FpdModuleIdentification
> iter
= map
.keySet().iterator();
129 List
<String
> mainLogs
= null;
130 while (iter
.hasNext()) {
131 FpdModuleIdentification item
= iter
.next();
133 mainLogs
= map
.get(item
);
136 bw
.write(">>>>>>>>>>>>>");
137 bw
.write(" " + item
+ " Build Log ");
138 bw
.write(">>>>>>>>>>>>>");
140 List
<String
> allMessages
= map
.get(item
);
141 for(int i
= 0; i
< allMessages
.size(); i
++) {
142 bw
.write(allMessages
.get(i
));
146 if (mainLogs
!= null) {
147 bw
.write(">>>>>>>>>>>>>");
148 bw
.write(" Main Logs (already print to command) ");
149 bw
.write(">>>>>>>>>>>>>");
151 for(int i
= 0; i
< mainLogs
.size(); i
++) {
152 bw
.write(mainLogs
.get(i
));
158 } catch (IOException e
) {
159 new BuildException("Writing log error. " + e
.getMessage());
164 private void log(Object msgSource
, String msg
, int level
) {
165 if (msgSource
instanceof Task
) {
166 ((Task
)msgSource
).getProject().log((Task
)msgSource
, msg
, level
);
167 } else if (msgSource
instanceof String
){
169 // Pad 12 space to keep message in unify format
171 msg
= msg
.replaceAll("\n", "\n ");
172 this.project
.log(String
.format("%12s", "[" + msgSource
+ "] ") + msg
, level
);
174 this.project
.log(msg
, level
);
177 public void targetStarted(BuildEvent event
) {
179 super.targetStarted(event
);
183 public void messageLogged(BuildEvent event
) {
184 int currentLevel
= event
.getPriority();
186 // If current level is upper than Ant Level, skip it
188 if (currentLevel
<= this.msgOutputLevel
) {
189 String originalMessage
= event
.getMessage();
191 StringBuffer message
= new StringBuffer();
192 if (!emacsMode
&& event
.getTask() != null) {
193 String label
= String
.format("%12s", "[" + event
.getTask().getTaskName() + "] ");
195 // Append label first
197 message
.append(label
);
200 // Format all output message's line separator
203 BufferedReader r
= new BufferedReader(new StringReader(originalMessage
));
204 boolean ifFirstLine
= true;
206 while ((line
= r
.readLine()) != null) {
208 message
.append(StringUtils
.LINE_SEP
);
211 message
.append(line
);
213 } catch (IOException e
) {
214 message
.append(originalMessage
);
217 message
.append(originalMessage
);
220 String msg
= message
.toString();
221 if (currentLevel
== Project
.MSG_ERR
) {
222 printMessage(msg
, err
, currentLevel
);
223 } else if(currentLevel
== Project
.MSG_WARN
) {
224 printMessage(msg
, out
, currentLevel
);
226 printMessage(msg
, out
, currentLevel
);
232 public static void setCacheEnable(boolean enable
) {
236 public static void maskAllLog(boolean enable
) {
237 enableFlag
= !enable
;
240 protected synchronized void log(String message
) {
244 if (map
.containsKey(this.id
)) {
245 map
.get(this.id
).add(message
);
247 List
<String
> list
= new Vector
<String
>(1024);
249 map
.put(this.id
, list
);
253 public Object
clone() {
254 GenBuildLogger newLogger
= new GenBuildLogger();
256 // Transfer emacs mode, out, err, level to new Logger
258 newLogger
.setEmacsMode(this.emacsMode
);
259 newLogger
.setOutputPrintStream(this.out
);
260 newLogger
.setErrorPrintStream(this.err
);
261 newLogger
.setMessageOutputLevel(this.msgOutputLevel
);
266 newLogger
.project
= this.project
;
270 public void setId(FpdModuleIdentification id
) {
274 public void buildFinished(BuildEvent event
) {
275 Throwable error
= event
.getException();
276 StringBuffer message
= new StringBuffer();
279 message
.append(StringUtils
.LINE_SEP
);
280 message
.append("BUILD SUCCESSFUL");
282 message
.append(StringUtils
.LINE_SEP
);
283 message
.append("BUILD FAILED");
284 message
.append(StringUtils
.LINE_SEP
);
286 if (Project
.MSG_DEBUG
<= msgOutputLevel
287 || !(error
instanceof BuildException
)) {
288 message
.append(StringUtils
.getStackTrace(error
));
290 if (error
instanceof BuildException
) {
291 message
.append(error
.toString()).append(lSep
);
293 message
.append(error
.getMessage()).append(lSep
);
297 message
.append(StringUtils
.LINE_SEP
);
298 message
.append("Total time: ");
299 message
.append(formatTime(System
.currentTimeMillis() - startTime
));
301 String msg
= message
.toString();
303 printMessage(msg
, out
, Project
.MSG_VERBOSE
);
305 printMessage(msg
, err
, Project
.MSG_ERR
);