Initial pass of an xml log file writer
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformLogWriter.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformLogWriter.java new file mode 100644 index 0000000..3ee2118 --- /dev/null +++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/PlatformLogWriter.java
@@ -0,0 +1,238 @@ +package org.eclipse.core.internal.runtime; + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + +import java.io.*; +import java.util.*; + +import org.apache.xml.serialize.XMLSerializer; +import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +class PlatformLogWriter implements ILogListener { + private PrintWriter log = null; + private boolean usingLogFile = false; + private int tab; + + private static final String XML_VERSION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; + + protected static final String ATTRIBUTE_DATE = "date"; + protected static final String ATTRIBUTE_SEVERITY = "severity"; + protected static final String ATTRIBUTE_PLUGIN_ID = "plugin-id"; + protected static final String ATTRIBUTE_CODE = "code"; + protected static final String ATTRIBUTE_MESSAGE = "message"; + protected static final String ATTRIBUTE_TRACE = "trace"; + + protected static final String ELEMENT_LOG = "log"; + protected static final String ELEMENT_LOG_ENTRY = "log-entry"; + protected static final String ELEMENT_STATUS = "status"; + protected static final String ELEMENT_EXCEPTION = "exception"; + + + +PlatformLogWriter() { + usingLogFile = true; + // remove old log file + InternalPlatform.getMetaArea().getLogLocation().toFile().delete(); +} +/** + * It should only be used to pass System.out . + */ +PlatformLogWriter(OutputStream out) { + log = new PrintWriter(out); +} +private static void appendEscapedChar(StringBuffer buffer, char c) { + String replacement = getReplacement(c); + if (replacement != null) { + buffer.append('&'); + buffer.append(replacement); + buffer.append(';'); + } else { + buffer.append(c); + } +} +public static String getEscaped(String s) { + StringBuffer result = new StringBuffer(s.length() + 10); + for (int i = 0; i < s.length(); ++i) + appendEscapedChar(result, s.charAt(i)); + return result.toString(); +} +private static String getReplacement(char c) { + // Encode special XML characters into the equivalent character references. + // These five are defined by default for all XML documents. + switch (c) { + case '<' : + return "lt"; + case '>' : + return "gt"; + case '"' : + return "quot"; + case '\'' : + return "apos"; + case '&' : + return "amp"; + } + return null; +} +private void closeLogFile() { + try { + log.flush(); + log.close(); + } finally { + log = null; + } +} +/** + * Returns a string representation of the given severity. + */ +protected String encodeSeverity(int severity) { + switch (severity) { + case IStatus.ERROR : + return "ERROR"; + case IStatus.INFO : + return "INFO"; + case IStatus.OK: + return "OK"; + case IStatus.WARNING : + return "WARNING"; + } + //unknown severity, just print the integer + return Integer.toString(severity); +} +protected String encodeStackTrace(Throwable t) { + StringWriter sWriter = new StringWriter(); + PrintWriter pWriter = new PrintWriter(sWriter); + pWriter.println(); + t.printStackTrace(pWriter); + pWriter.flush(); + return sWriter.toString(); +} +public void endTag(String name) { + tab--; + printTag('/' + name, null); +} +public synchronized void logging(IStatus status, String plugin) { + // thread safety: (Concurrency003) + if (usingLogFile) + openLogFile(); + if (log == null) + return; + try { + writeLogEntry(status); + } catch (Exception e) { + e.printStackTrace(); + }finally { + if (usingLogFile) + closeLogFile(); + } +} +private void openLogFile() { + try { + File file = InternalPlatform.getMetaArea().getLogLocation().toFile(); + boolean newLog = !file.exists(); + log = new PrintWriter(new BufferedWriter(new FileWriter(file.getAbsolutePath(), true))); + if (newLog) { + log.println(XML_VERSION); + startTag(ELEMENT_LOG, null); + } + } catch (IOException e) { + // there was a problem opening the log file so log to the console + log = new PrintWriter(System.out); + } +} +public void printTabulation() { + for (int i = 0; i < tab; i++) + log.print(" "); +} + +public void printTag(String name, HashMap parameters) { + printTabulation(); + log.print('<'); + log.print(name); + tab++; + if (parameters != null) + for (Enumeration enum = Collections.enumeration(parameters.keySet()); enum.hasMoreElements();) { + //new line for each attribute if there's more than one + if (parameters.size() > 1) { + log.println(); + printTabulation(); + } + log.print(" "); + String key = (String) enum.nextElement(); + log.print(key); + log.print("=\""); + log.print(getEscaped(String.valueOf(parameters.get(key)))); + log.print("\""); + } + tab--; + log.println(">"); +} + +/** + * @see ILogListener + */ +public synchronized void shutdown() { + if (usingLogFile) { + try { + openLogFile(); + endTag(ELEMENT_LOG); + } finally { + closeLogFile(); + } + } else { + if (log != null) { + PrintWriter old = log; + log = null; + old.flush(); + old.close(); + } + } +} +public void startTag(String name, HashMap parameters) { + printTag(name, parameters); + tab++; +} +protected void write(Throwable throwable) throws SAXException { + if (throwable == null) + return; + HashMap attributes = new HashMap(); + attributes.put(ATTRIBUTE_MESSAGE, throwable.getMessage()); + attributes.put(ATTRIBUTE_TRACE, encodeStackTrace(throwable)); + startTag(ELEMENT_EXCEPTION, attributes); + endTag(ELEMENT_EXCEPTION); +} +protected void write(IStatus status) throws SAXException { + HashMap attributes = new HashMap(); + attributes.put(ATTRIBUTE_SEVERITY, encodeSeverity(status.getSeverity())); + attributes.put(ATTRIBUTE_PLUGIN_ID, status.getPlugin()); + attributes.put(ATTRIBUTE_CODE, Integer.toString(status.getCode())); + attributes.put(ATTRIBUTE_MESSAGE, status.getMessage()); + startTag(ELEMENT_STATUS, attributes); { + write(status.getException()); + if (status.isMultiStatus()) { + IStatus[] children = status.getChildren(); + for (int i = 0; i < children.length; i++) { + write(children[i]); + } + } + } + endTag(ELEMENT_STATUS); +} +protected void writeLogEntry(IStatus status) throws SAXException { + tab = 0; + HashMap attributes = new HashMap(); + attributes.put(ATTRIBUTE_DATE, new Date()); + startTag(ELEMENT_LOG_ENTRY, attributes); + tab = 1; + write(status); + endTag(ELEMENT_LOG_ENTRY); + tab = 0; +} +} +