]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Java/Source/GenBuild/org/tianocore/build/global/GenBuildLogger.java
Support MSA build options. Now the build options from four places: 1. tools_def.txt
[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 /// flag to present whether cache all msg or not
50 /// true means to cache.
51 ///
52 private static boolean flag = false;
53
54 private static Map<FpdModuleIdentification, List<String>> map = new LinkedHashMap<FpdModuleIdentification, List<String> >(256);
55
56 private FpdModuleIdentification id = null;
57 //
58 // semaroph for multi thread
59 //
60 public static Object semaphore = new Object();
61
62 public GenBuildLogger () {
63
64 }
65
66 public GenBuildLogger (Project project) {
67 this.project = project;
68 }
69
70 /**
71 Rules: flag = false: means no cache Action: Print it to console
72
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
76 **/
77 public synchronized void putMessage(Object msgSource, int msgLevel, String msg) {
78 if (this.project == null) {
79 return;
80 }
81
82 //
83 // If msgLevel is always print, then print it
84 //
85 switch (msgLevel) {
86 case EdkLog.EDK_ALWAYS:
87 //
88 // Do some special
89 //
90 log(msgSource, msg, Project.MSG_ERR);
91 break;
92 case EdkLog.EDK_ERROR:
93 log(msgSource, msg, Project.MSG_ERR);
94 break;
95 case EdkLog.EDK_WARNING:
96 log(msgSource, msg, Project.MSG_WARN);
97 break;
98 case EdkLog.EDK_INFO:
99 log(msgSource, msg, Project.MSG_INFO);
100 break;
101 case EdkLog.EDK_VERBOSE:
102 log(msgSource, msg, Project.MSG_VERBOSE);
103 break;
104 case EdkLog.EDK_DEBUG:
105 log(msgSource, msg, Project.MSG_DEBUG);
106 break;
107 }
108 }
109
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));
116 }
117 }
118 }
119
120 public void flushToFile(File file) {
121 //
122 // Put all messages in map to file
123 //
124 String msg = "Writing log to file [" + file.getPath() + "]";
125 log("Logging", msg, Project.MSG_INFO);
126 try {
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();
132 if(item == null) {
133 mainLogs = map.get(item);
134 continue ;
135 }
136 bw.write(">>>>>>>>>>>>>");
137 bw.write(" " + item + " Build Log ");
138 bw.write(">>>>>>>>>>>>>");
139 bw.newLine();
140 List<String> allMessages = map.get(item);
141 for(int i = 0; i < allMessages.size(); i++) {
142 bw.write(allMessages.get(i));
143 bw.newLine();
144 }
145 }
146 if (mainLogs != null) {
147 bw.write(">>>>>>>>>>>>>");
148 bw.write(" Main Logs (already print to command) ");
149 bw.write(">>>>>>>>>>>>>");
150 bw.newLine();
151 for(int i = 0; i < mainLogs.size(); i++) {
152 bw.write(mainLogs.get(i));
153 bw.newLine();
154 }
155 }
156 bw.flush();
157 bw.close();
158 } catch (IOException e) {
159 new BuildException("Writing log error. " + e.getMessage());
160 }
161
162 }
163
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){
168 //
169 // Pad 12 space to keep message in unify format
170 //
171 msg = msg.replaceAll("\n", "\n ");
172 this.project.log(String.format("%12s", "[" + msgSource + "] ") + msg, level);
173 } else {
174 this.project.log(msg, level);
175 }
176 }
177 public void targetStarted(BuildEvent event) {
178 if (!flag) {
179 super.targetStarted(event);
180 }
181 }
182
183 public void messageLogged(BuildEvent event) {
184
185 int currentLevel = event.getPriority();
186 //
187 // If current level is upper than Ant Level, skip it
188 //
189 if (currentLevel <= this.msgOutputLevel) {
190 String originalMessage = event.getMessage();
191
192 StringBuffer message = new StringBuffer();
193 if (!emacsMode && event.getTask() != null) {
194 String label = String.format("%12s", "[" + event.getTask().getTaskName() + "] ");
195 //
196 // Append label first
197 //
198 message.append(label);
199
200 //
201 // Format all output message's line separator
202 //
203 try {
204 BufferedReader r = new BufferedReader(new StringReader(originalMessage));
205 boolean ifFirstLine = true;
206 String line = null;
207 while ((line = r.readLine()) != null) {
208 if (!ifFirstLine) {
209 message.append(StringUtils.LINE_SEP);
210 }
211 ifFirstLine = false;
212 message.append(line);
213 }
214 } catch (IOException e) {
215 message.append(originalMessage);
216 }
217 } else {
218 message.append(originalMessage);
219 }
220
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);
226 } else if(!flag) {
227 printMessage(msg, out, currentLevel);
228 }
229 log(msg);
230 }
231 }
232
233 public static void setCacheEnable(boolean enable) {
234 flag = enable;
235 }
236
237 protected synchronized void log(String message) {
238 //
239 // cache log
240 //
241 if (map.containsKey(this.id)) {
242 map.get(this.id).add(message);
243 } else {
244 List<String> list = new Vector<String>(1024);
245 list.add(message);
246 map.put(this.id, list);
247 }
248 }
249
250 public Object clone() {
251 GenBuildLogger newLogger = new GenBuildLogger();
252 //
253 // Transfer emacs mode, out, err, level to new Logger
254 //
255 newLogger.setEmacsMode(this.emacsMode);
256 newLogger.setOutputPrintStream(this.out);
257 newLogger.setErrorPrintStream(this.err);
258 newLogger.setMessageOutputLevel(this.msgOutputLevel);
259
260 //
261 // Transfer project
262 //
263 newLogger.project = this.project;
264 return newLogger;
265 }
266
267 public void setId(FpdModuleIdentification id) {
268 this.id = id;
269 }
270
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;
278 }
279 } else {
280 super.buildFinished(event);
281 }
282 }
283 }