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 // semaroph for multi thread
65 public static Object semaphore
= new Object();
67 public GenBuildLogger () {
71 public GenBuildLogger (Project project
) {
72 this.project
= project
;
76 Rules: flag = false: means no cache Action: Print it to console
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
82 public synchronized void putMessage(Object msgSource
, int msgLevel
, String msg
) {
83 if (this.project
== null) {
88 // If msgLevel is always print, then print it
91 case EdkLog
.EDK_ALWAYS
:
95 log(msgSource
, msg
, Project
.MSG_ERR
);
97 case EdkLog
.EDK_ERROR
:
98 log(msgSource
, msg
, Project
.MSG_ERR
);
100 case EdkLog
.EDK_WARNING
:
101 log(msgSource
, msg
, Project
.MSG_WARN
);
103 case EdkLog
.EDK_INFO
:
104 log(msgSource
, msg
, Project
.MSG_INFO
);
106 case EdkLog
.EDK_VERBOSE
:
107 log(msgSource
, msg
, Project
.MSG_VERBOSE
);
109 case EdkLog
.EDK_DEBUG
:
110 log(msgSource
, msg
, Project
.MSG_DEBUG
);
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
));
125 public void flushToFile(File file
) {
127 // Put all messages in map to file
129 String msg
= "Writing log to file [" + file
.getPath() + "]";
130 log("Logging", msg
, Project
.MSG_INFO
);
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();
138 mainLogs
= map
.get(item
);
141 bw
.write(">>>>>>>>>>>>>");
142 bw
.write(" " + item
+ " Build Log ");
143 bw
.write(">>>>>>>>>>>>>");
145 List
<String
> allMessages
= map
.get(item
);
146 for(int i
= 0; i
< allMessages
.size(); i
++) {
147 bw
.write(allMessages
.get(i
));
151 if (mainLogs
!= null) {
152 bw
.write(">>>>>>>>>>>>>");
153 bw
.write(" Main Logs (already print to command) ");
154 bw
.write(">>>>>>>>>>>>>");
156 for(int i
= 0; i
< mainLogs
.size(); i
++) {
157 bw
.write(mainLogs
.get(i
));
163 } catch (IOException e
) {
164 new BuildException("Writing log error. " + e
.getMessage());
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
){
174 // Pad 12 space to keep message in unify format
176 msg
= msg
.replaceAll("\n", "\n ");
177 this.project
.log(String
.format("%12s", "[" + msgSource
+ "] ") + msg
, level
);
179 this.project
.log(msg
, level
);
182 public void targetStarted(BuildEvent event
) {
184 super.targetStarted(event
);
188 public void messageLogged(BuildEvent event
) {
190 int currentLevel
= event
.getPriority();
192 // If current level is upper than Ant Level, skip it
194 if (currentLevel
<= this.msgOutputLevel
) {
195 String originalMessage
= event
.getMessage();
197 StringBuffer message
= new StringBuffer();
198 if (!emacsMode
&& event
.getTask() != null) {
199 String label
= String
.format("%12s", "[" + event
.getTask().getTaskName() + "] ");
201 // Append label first
203 message
.append(label
);
206 // Format all output message's line separator
209 BufferedReader r
= new BufferedReader(new StringReader(originalMessage
));
210 boolean ifFirstLine
= true;
212 while ((line
= r
.readLine()) != null) {
214 message
.append(StringUtils
.LINE_SEP
);
217 message
.append(line
);
219 } catch (IOException e
) {
220 message
.append(originalMessage
);
223 message
.append(originalMessage
);
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
);
232 printMessage(msg
, out
, currentLevel
);
238 public static void setCacheEnable(boolean enable
) {
242 protected synchronized void log(String message
) {
246 if (map
.containsKey(this.id
)) {
247 map
.get(this.id
).add(message
);
249 List
<String
> list
= new Vector
<String
>(1024);
251 map
.put(this.id
, list
);
255 public Object
clone() {
256 GenBuildLogger newLogger
= new GenBuildLogger();
258 // Transfer emacs mode, out, err, level to new Logger
260 newLogger
.setEmacsMode(this.emacsMode
);
261 newLogger
.setOutputPrintStream(this.out
);
262 newLogger
.setErrorPrintStream(this.err
);
263 newLogger
.setMessageOutputLevel(this.msgOutputLevel
);
268 newLogger
.project
= this.project
;
272 public void setId(FpdModuleIdentification id
) {
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
;
285 super.buildFinished(event
);