\r
package org.tianocore.build.global;\r
\r
+import java.io.BufferedReader;\r
+import java.io.BufferedWriter;\r
import java.io.File;\r
+import java.io.FileWriter;\r
+import java.io.IOException;\r
+import java.io.StringReader;\r
+import java.util.HashMap;\r
import java.util.List;\r
+import java.util.Map;\r
import java.util.Vector;\r
\r
+import org.apache.tools.ant.BuildEvent;\r
+import org.apache.tools.ant.BuildException;\r
+import org.apache.tools.ant.DefaultLogger;\r
import org.apache.tools.ant.Project;\r
import org.apache.tools.ant.Task;\r
+import org.apache.tools.ant.util.StringUtils;\r
\r
+import org.tianocore.build.id.Identification;\r
import org.tianocore.common.logger.EdkLog;\r
import org.tianocore.common.logger.LogMethod;\r
\r
-public class GenBuildLogger implements LogMethod {\r
+public class GenBuildLogger extends DefaultLogger implements LogMethod {\r
+ \r
private Project project = null;\r
\r
///\r
/// flag to present whether cache all msg or not\r
- /// true means not to cache.\r
+ /// true means to cache.\r
///\r
- private boolean flag = true;\r
+ private static boolean flag = false;\r
\r
- private List<String> v = null;\r
+ private static Map<Identification, List<String>> map = new HashMap<Identification, List<String> >(256);\r
+ \r
+ private Identification id = null;\r
+ \r
+ public GenBuildLogger () {\r
+ \r
+ }\r
\r
public GenBuildLogger (Project project) {\r
this.project = project;\r
}\r
\r
- public GenBuildLogger (Project project, boolean flag) {\r
+ public GenBuildLogger (Project project, Identification id) {\r
this.project = project;\r
- this.flag = flag;\r
-\r
- //\r
- // Only flag is false, v will be initialized and used.\r
- //\r
- if (!flag) {\r
- v = new Vector<String>(2048);\r
- }\r
+ this.id = id;\r
}\r
\r
/**\r
- Rules: flag = true: means no cache Action: Print it to console\r
+ Rules: flag = false: means no cache Action: Print it to console\r
\r
- flag = false: mean cache all msg exception some special Action: loglevel\r
+ flag = true: mean cache all msg exception some special Action: loglevel\r
is EDK_ALWAYS -- Print but no cache loglevel is EDK_ERROR -- Print and\r
cache the msg others -- No print and cache the msg\r
**/\r
- public synchronized void putMessage(Object msgSource, int msgLevel,\r
- String msg) {\r
+ public synchronized void putMessage(Object msgSource, int msgLevel, String msg) {\r
if (this.project == null) {\r
return;\r
}\r
//\r
switch (msgLevel) {\r
case EdkLog.EDK_ALWAYS:\r
- log(msgSource, msg, Project.MSG_INFO);\r
+ //\r
+ // Do some special\r
+ //\r
+ log(msgSource, msg, Project.MSG_ERR);\r
break;\r
case EdkLog.EDK_ERROR:\r
- if (flag) {\r
- log(msgSource, msg, Project.MSG_ERR);\r
- } else {\r
- log(msgSource, msg, Project.MSG_ERR);\r
- v.add(msg);\r
- }\r
+ log(msgSource, msg, Project.MSG_ERR);\r
break;\r
case EdkLog.EDK_WARNING:\r
- if (flag) {\r
- log(msgSource, msg, Project.MSG_WARN);\r
- } else {\r
- v.add(msg);\r
- }\r
+ log(msgSource, msg, Project.MSG_WARN);\r
break;\r
case EdkLog.EDK_INFO:\r
- if (flag) {\r
- log(msgSource, msg, Project.MSG_INFO);\r
- } else {\r
- v.add(msg);\r
- }\r
+ log(msgSource, msg, Project.MSG_INFO);\r
break;\r
case EdkLog.EDK_VERBOSE:\r
- if (flag) {\r
- log(msgSource, msg, Project.MSG_VERBOSE);\r
- } else {\r
- v.add(msg);\r
- }\r
+ log(msgSource, msg, Project.MSG_VERBOSE);\r
break;\r
case EdkLog.EDK_DEBUG:\r
- if (flag) {\r
- log(msgSource, msg, Project.MSG_DEBUG);\r
- } else {\r
- v.add(msg);\r
- }\r
+ log(msgSource, msg, Project.MSG_DEBUG);\r
break;\r
}\r
}\r
\r
public void flushToFile(File file) {\r
//\r
- // Sort msg and store to the file (TBD)\r
+ // Put all messages in map to file\r
//\r
-\r
+ String msg = "Writing log to file [" + file.getPath() + "]";\r
+ log("Logging", msg, Project.MSG_INFO);\r
+ try {\r
+ BufferedWriter bw = new BufferedWriter(new FileWriter(file));\r
+ List<String> allMessages = map.get(null);\r
+ for(int i = 0; i < allMessages.size(); i++) {\r
+ bw.write(allMessages.get(i));\r
+ bw.newLine();\r
+ }\r
+ bw.flush();\r
+ bw.close();\r
+ } catch (IOException e) {\r
+ new BuildException("Writing log error. " + e.getMessage());\r
+ }\r
+ \r
}\r
\r
private void log(Object msgSource, String msg, int level) {\r
if (msgSource instanceof Task) {\r
this.project.log((Task)msgSource, msg, level);\r
} else if (msgSource instanceof String){\r
- \r
//\r
- // Pad 12 space to keep message \r
+ // Pad 12 space to keep message in unify format\r
//\r
msg = msg.replaceAll("\n", "\n ");\r
this.project.log(String.format("%12s", "[" + msgSource + "] ") + msg, level);\r
this.project.log(msg, level);\r
}\r
}\r
+ public void targetStarted(BuildEvent event) {\r
+ if (!flag) {\r
+ super.targetStarted(event);\r
+ }\r
+ }\r
+ \r
+ public void messageLogged(BuildEvent event) {\r
+ int currentLevel = event.getPriority();\r
+ //\r
+ // If current level is upper than Ant Level, skip it\r
+ //\r
+ if (currentLevel <= this.msgOutputLevel) {\r
+ String originalMessage = event.getMessage();\r
+\r
+ StringBuffer message = new StringBuffer();\r
+ if (!emacsMode && event.getTask() != null) {\r
+ String label = String.format("%12s", "[" + event.getTask().getTaskName() + "] ");\r
+ //\r
+ // Append label first\r
+ //\r
+ message.append(label);\r
+ \r
+ //\r
+ // Format all output message's line separator\r
+ //\r
+ try {\r
+ BufferedReader r = new BufferedReader(new StringReader(originalMessage));\r
+ boolean ifFirstLine = true;\r
+ String line = null;\r
+ while ((line = r.readLine()) != null) {\r
+ if (!ifFirstLine) {\r
+ message.append(StringUtils.LINE_SEP);\r
+ }\r
+ ifFirstLine = false;\r
+ message.append(line);\r
+ }\r
+ } catch (IOException e) {\r
+ message.append(originalMessage);\r
+ }\r
+ } else {\r
+ message.append(originalMessage);\r
+ }\r
+\r
+ String msg = message.toString();\r
+ if (currentLevel == Project.MSG_ERR) {\r
+ printMessage(msg, err, currentLevel);\r
+ } else if(currentLevel == Project.MSG_WARN) {\r
+ printMessage(msg, out, currentLevel);\r
+ } else if(!flag) {\r
+ printMessage(msg, out, currentLevel);\r
+ } \r
+ \r
+ log(msg);\r
+ }\r
+ }\r
+ \r
+ public static void setCacheEnable(boolean enable) {\r
+ flag = enable;\r
+ }\r
+ \r
+ protected synchronized void log(String message) {\r
+ //\r
+ // cache log\r
+ //\r
+ if (map.containsKey(this.id)) {\r
+ map.get(this.id).add(message);\r
+ } else {\r
+ List<String> list = new Vector<String>(1024);\r
+ list.add(message);\r
+ map.put(this.id, list);\r
+ }\r
+ }\r
}
\ No newline at end of file