summaryrefslogtreecommitdiff
path: root/libjava/classpath/java/util/logging/XMLFormatter.java
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/java/util/logging/XMLFormatter.java
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/classpath/java/util/logging/XMLFormatter.java')
-rw-r--r--libjava/classpath/java/util/logging/XMLFormatter.java389
1 files changed, 389 insertions, 0 deletions
diff --git a/libjava/classpath/java/util/logging/XMLFormatter.java b/libjava/classpath/java/util/logging/XMLFormatter.java
new file mode 100644
index 000000000..da7c6ef29
--- /dev/null
+++ b/libjava/classpath/java/util/logging/XMLFormatter.java
@@ -0,0 +1,389 @@
+/* XMLFormatter.java --
+ A class for formatting log messages into a standard XML format
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util.logging;
+
+import gnu.java.lang.CPStringBuilder;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.ResourceBundle;
+
+/**
+ * An <code>XMLFormatter</code> formats LogRecords into
+ * a standard XML format.
+ *
+ * @author Sascha Brawer (brawer@acm.org)
+ */
+public class XMLFormatter
+ extends Formatter
+{
+ /**
+ * Constructs a new XMLFormatter.
+ */
+ public XMLFormatter()
+ {
+ }
+
+
+ /**
+ * The character sequence that is used to separate lines in the
+ * generated XML stream. Somewhat surprisingly, the Sun J2SE 1.4
+ * reference implementation always uses UNIX line endings, even on
+ * platforms that have different line ending conventions (i.e.,
+ * DOS). The GNU Classpath implementation does not replicates this
+ * bug.
+ *
+ * See also the Sun bug parade, bug #4462871,
+ * "java.util.logging.SimpleFormatter uses hard-coded line separator".
+ */
+ private static final String lineSep = SimpleFormatter.lineSep;
+
+
+ /**
+ * A DateFormat for emitting time in the ISO 8601 format.
+ * Since the API specification of SimpleDateFormat does not talk
+ * about its thread-safety, we cannot share a singleton instance.
+ */
+ private final SimpleDateFormat iso8601
+ = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+
+
+ /**
+ * Appends a line consisting of indentation, opening element tag,
+ * element content, closing element tag and line separator to
+ * a CPStringBuilder, provided that the element content is
+ * actually existing.
+ *
+ * @param buf the CPStringBuilder to which the line will be appended.
+ *
+ * @param indent the indentation level.
+ *
+ * @param tag the element tag name, for instance <code>method</code>.
+ *
+ * @param content the element content, or <code>null</code> to
+ * have no output whatsoever appended to <code>buf</code>.
+ */
+ private static void appendTag(CPStringBuilder buf, int indent,
+ String tag, String content)
+ {
+ int i;
+
+ if (content == null)
+ return;
+
+ for (i = 0; i < indent * 2; i++)
+ buf.append(' ');
+
+ buf.append("<");
+ buf.append(tag);
+ buf.append('>');
+
+ /* Append the content, but escape for XML by replacing
+ * '&', '<', '>' and all non-ASCII characters with
+ * appropriate escape sequences.
+ * The Sun J2SE 1.4 reference implementation does not
+ * escape non-ASCII characters. This is a bug in their
+ * implementation which has been reported in the Java
+ * bug parade as bug number (FIXME: Insert number here).
+ */
+ for (i = 0; i < content.length(); i++)
+ {
+ char c = content.charAt(i);
+ switch (c)
+ {
+ case '&':
+ buf.append("&amp;");
+ break;
+
+ case '<':
+ buf.append("&lt;");
+ break;
+
+ case '>':
+ buf.append("&gt;");
+ break;
+
+ default:
+ if (((c >= 0x20) && (c <= 0x7e))
+ || (c == /* line feed */ 10)
+ || (c == /* carriage return */ 13))
+ buf.append(c);
+ else
+ {
+ buf.append("&#");
+ buf.append((int) c);
+ buf.append(';');
+ }
+ break;
+ } /* switch (c) */
+ } /* for i */
+
+ buf.append("</");
+ buf.append(tag);
+ buf.append(">");
+ buf.append(lineSep);
+ }
+
+
+ /**
+ * Appends a line consisting of indentation, opening element tag,
+ * numeric element content, closing element tag and line separator
+ * to a CPStringBuilder.
+ *
+ * @param buf the CPStringBuilder to which the line will be appended.
+ *
+ * @param indent the indentation level.
+ *
+ * @param tag the element tag name, for instance <code>method</code>.
+ *
+ * @param content the element content.
+ */
+ private static void appendTag(CPStringBuilder buf, int indent,
+ String tag, long content)
+ {
+ appendTag(buf, indent, tag, Long.toString(content));
+ }
+
+
+ public String format(LogRecord record)
+ {
+ CPStringBuilder buf = new CPStringBuilder(400);
+ Level level = record.getLevel();
+ long millis = record.getMillis();
+ Object[] params = record.getParameters();
+ ResourceBundle bundle = record.getResourceBundle();
+ String message;
+
+ buf.append("<record>");
+ buf.append(lineSep);
+
+
+ appendTag(buf, 1, "date", iso8601.format(new Date(millis)));
+ appendTag(buf, 1, "millis", millis);
+ appendTag(buf, 1, "sequence", record.getSequenceNumber());
+ appendTag(buf, 1, "logger", record.getLoggerName());
+
+ if (level.isStandardLevel())
+ appendTag(buf, 1, "level", level.toString());
+ else
+ appendTag(buf, 1, "level", level.intValue());
+
+ appendTag(buf, 1, "class", record.getSourceClassName());
+ appendTag(buf, 1, "method", record.getSourceMethodName());
+ appendTag(buf, 1, "thread", record.getThreadID());
+
+ /* The Sun J2SE 1.4 reference implementation does not emit the
+ * message in localized form. This is in violation of the API
+ * specification. The GNU Classpath implementation intentionally
+ * replicates the buggy behavior of the Sun implementation, as
+ * different log files might be a big nuisance to users.
+ */
+ try
+ {
+ record.setResourceBundle(null);
+ message = formatMessage(record);
+ }
+ finally
+ {
+ record.setResourceBundle(bundle);
+ }
+ appendTag(buf, 1, "message", message);
+
+ /* The Sun J2SE 1.4 reference implementation does not
+ * emit key, catalog and param tags. This is in violation
+ * of the API specification. The Classpath implementation
+ * intentionally replicates the buggy behavior of the
+ * Sun implementation, as different log files might be
+ * a big nuisance to users.
+ *
+ * FIXME: File a bug report with Sun. Insert bug number here.
+ *
+ *
+ * key = record.getMessage();
+ * if (key == null)
+ * key = "";
+ *
+ * if ((bundle != null) && !key.equals(message))
+ * {
+ * appendTag(buf, 1, "key", key);
+ * appendTag(buf, 1, "catalog", record.getResourceBundleName());
+ * }
+ *
+ * if (params != null)
+ * {
+ * for (int i = 0; i < params.length; i++)
+ * appendTag(buf, 1, "param", params[i].toString());
+ * }
+ */
+
+ /* FIXME: We have no way to obtain the stacktrace before free JVMs
+ * support the corresponding method in java.lang.Throwable. Well,
+ * it would be possible to parse the output of printStackTrace,
+ * but this would be pretty kludgy. Instead, we postpose the
+ * implementation until Throwable has made progress.
+ */
+ Throwable thrown = record.getThrown();
+ if (thrown != null)
+ {
+ buf.append(" <exception>");
+ buf.append(lineSep);
+
+ /* The API specification is not clear about what exactly
+ * goes into the XML record for a thrown exception: It
+ * could be the result of getMessage(), getLocalizedMessage(),
+ * or toString(). Therefore, it was necessary to write a
+ * Mauve testlet and run it with the Sun J2SE 1.4 reference
+ * implementation. It turned out that the we need to call
+ * toString().
+ *
+ * FIXME: File a bug report with Sun, asking for clearer
+ * specs.
+ */
+ appendTag(buf, 2, "message", thrown.toString());
+
+ /* FIXME: The Logging DTD specifies:
+ *
+ * <!ELEMENT exception (message?, frame+)>
+ *
+ * However, java.lang.Throwable.getStackTrace() is
+ * allowed to return an empty array. So, what frame should
+ * be emitted for an empty stack trace? We probably
+ * should file a bug report with Sun, asking for the DTD
+ * to be changed.
+ */
+
+ buf.append(" </exception>");
+ buf.append(lineSep);
+ }
+
+
+ buf.append("</record>");
+ buf.append(lineSep);
+
+ return buf.toString();
+ }
+
+
+ /**
+ * Returns a string that handlers are supposed to emit before
+ * the first log record. The base implementation returns an
+ * empty string, but subclasses such as {@link XMLFormatter}
+ * override this method in order to provide a suitable header.
+ *
+ * @return a string for the header.
+ *
+ * @param h the handler which will prepend the returned
+ * string in front of the first log record. This method
+ * will inspect certain properties of the handler, for
+ * example its encoding, in order to construct the header.
+ */
+ public String getHead(Handler h)
+ {
+ CPStringBuilder buf;
+ String encoding;
+
+ buf = new CPStringBuilder(80);
+ buf.append("<?xml version=\"1.0\" encoding=\"");
+
+ encoding = h.getEncoding();
+
+ /* file.encoding is a system property with the Sun JVM, indicating
+ * the platform-default file encoding. Unfortunately, the API
+ * specification for java.lang.System.getProperties() does not
+ * list this property.
+ */
+ if (encoding == null)
+ encoding = System.getProperty("file.encoding");
+
+ /* Since file.encoding is not listed with the API specification of
+ * java.lang.System.getProperties(), there might be some VMs that
+ * do not define this system property. Therefore, we use UTF-8 as
+ * a reasonable default. Please note that if the platform encoding
+ * uses the same codepoints as US-ASCII for the US-ASCII character
+ * set (e.g, 65 for A), it does not matter whether we emit the
+ * wrong encoding into the XML header -- the GNU Classpath will
+ * emit XML escape sequences like &#1234; for any non-ASCII
+ * character. Virtually all character encodings use the same code
+ * points as US-ASCII for ASCII characters. Probably, EBCDIC is
+ * the only exception.
+ */
+ if (encoding == null)
+ encoding = "UTF-8";
+
+ /* On Windows XP localized for Swiss German (this is one of
+ * my [Sascha Brawer's] test machines), the default encoding
+ * has the canonical name "windows-1252". The "historical" name
+ * of this encoding is "Cp1252" (see the Javadoc for the class
+ * java.nio.charset.Charset for the distinction). Now, that class
+ * does have a method for mapping historical to canonical encoding
+ * names. However, if we used it here, we would be come dependent
+ * on java.nio.*, which was only introduced with J2SE 1.4.
+ * Thus, we do this little hack here. As soon as Classpath supports
+ * java.nio.charset.CharSet, this hack should be replaced by
+ * code that correctly canonicalizes the encoding name.
+ */
+ if ((encoding.length() > 2) && encoding.startsWith("Cp"))
+ encoding = "windows-" + encoding.substring(2);
+
+ buf.append(encoding);
+
+ buf.append("\" standalone=\"no\"?>");
+ buf.append(lineSep);
+
+ /* SYSTEM is not a fully qualified URL so that validating
+ * XML parsers do not need to connect to the Internet in
+ * order to read in a log file. See also the Sun Bug Parade,
+ * bug #4372790, "Logging APIs: need to use relative URL for XML
+ * doctype".
+ */
+ buf.append("<!DOCTYPE log SYSTEM \"logger.dtd\">");
+ buf.append(lineSep);
+ buf.append("<log>");
+ buf.append(lineSep);
+
+ return buf.toString();
+ }
+
+
+ public String getTail(Handler h)
+ {
+ return "</log>" + lineSep;
+ }
+}