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 /// flag to present whether cache all msg or not
50 /// true means to cache.
52 private static boolean flag
= false;
54 private static Map
<FpdModuleIdentification
, List
<String
>> map
= new LinkedHashMap
<FpdModuleIdentification
, List
<String
> >(256);
56 private FpdModuleIdentification id
= null;
58 // semaroph for multi thread
60 public static Object semaphore
= new Object();
62 public GenBuildLogger () {
66 public GenBuildLogger (Project project
) {
67 this.project
= project
;
71 Rules: flag = false: means no cache Action: Print it to console
73 flag = true: mean cache all msg exception some special Action: loglevel
74 is EDK_ALWAYS -- Print but no cache loglevel is EDK_ERROR -- Print and
75 cache the msg others -- No print and cache the msg
77 public synchronized void putMessage(Object msgSource
, int msgLevel
, String msg
) {
78 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
) {
185 int currentLevel
= event
.getPriority();
187 // If current level is upper than Ant Level, skip it
189 if (currentLevel
<= this.msgOutputLevel
) {
190 String originalMessage
= event
.getMessage();
192 StringBuffer message
= new StringBuffer();
193 if (!emacsMode
&& event
.getTask() != null) {
194 String label
= String
.format("%12s", "[" + event
.getTask().getTaskName() + "] ");
196 // Append label first
198 message
.append(label
);
201 // Format all output message's line separator
204 BufferedReader r
= new BufferedReader(new StringReader(originalMessage
));
205 boolean ifFirstLine
= true;
207 while ((line
= r
.readLine()) != null) {
209 message
.append(StringUtils
.LINE_SEP
);
212 message
.append(line
);
214 } catch (IOException e
) {
215 message
.append(originalMessage
);
218 message
.append(originalMessage
);
221 String msg
= message
.toString();
222 if (currentLevel
== Project
.MSG_ERR
) {
223 printMessage(msg
, err
, currentLevel
);
224 } else if(currentLevel
== Project
.MSG_WARN
) {
225 printMessage(msg
, out
, currentLevel
);
227 printMessage(msg
, out
, currentLevel
);
233 public static void setCacheEnable(boolean enable
) {
237 protected synchronized void log(String message
) {
241 if (map
.containsKey(this.id
)) {
242 map
.get(this.id
).add(message
);
244 List
<String
> list
= new Vector
<String
>(1024);
246 map
.put(this.id
, list
);
250 public Object
clone() {
251 GenBuildLogger newLogger
= new GenBuildLogger();
253 // Transfer emacs mode, out, err, level to new Logger
255 newLogger
.setEmacsMode(this.emacsMode
);
256 newLogger
.setOutputPrintStream(this.out
);
257 newLogger
.setErrorPrintStream(this.err
);
258 newLogger
.setMessageOutputLevel(this.msgOutputLevel
);
263 newLogger
.project
= this.project
;
267 public void setId(FpdModuleIdentification id
) {
271 public void buildFinished(BuildEvent event
) {
272 if (this.msgOutputLevel
>= Project
.MSG_VERBOSE
) {
273 int level
= this.msgOutputLevel
;
274 synchronized(semaphore
){
275 this.msgOutputLevel
= this.msgOutputLevel
- 1;
276 super.buildFinished(event
);
277 this.msgOutputLevel
= level
;
280 super.buildFinished(event
);