On Tue, Oct 9, 2012 at 10:19 AM, Ralph Goers <[email protected]>wrote:

> This requires a long answer.
>
> Ceki realized in Logback that OutputStreams really needed a byte array.
>  So he changed Appenders to require an Encoder instead of an Appender.
>  Layouts still return a String so he created a wrapper Encoder to convert
> the String to a byte array.
>
> The idea of using a byte array is correct - most of the time, as most of
> the Appenders use an OutputStream.  However, the JMS appenders don't. They
> require a Serializable object.
>
> When developing Log4j I did not like having both Encoders and Layouts, so
> I chose to have Layouts return a byte array. But then it made no sense to
> have something based on the AbstractStringLayout convert the String to a
> byte array only to have to convert it back to a String again for the JMS
> Appenders, which is why I added formatAs().  Now the JMS Appender can send
> both a Serialized LogEvent and a String.
>
> So in looking at how formatAs() is used I would think that we could just
> change Layout to
>
> public interface Layout {
>
>     Serializable formatAs();
>
>     ...
> }
>
> I tried that refactoring and ran into one ugly:
>

For
org.apache.logging.log4j.core.layout.AbstractStringLayout.format(LogEvent)

I had to change:

    public byte[] format(LogEvent event) {
        return encoder.getBytes(*formatAs(event)*);
    }

to:

    public byte[] format(LogEvent event) {
        return encoder.getBytes(*formatAs(event).toString()*);
    }

The change set is below.

Thoughts?

Gary

Index:
src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
===================================================================
---
src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
(revision 1396432)
+++
src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
(working copy)
@@ -20,13 +20,10 @@
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.status.StatusLogger;

-import java.io.Serializable;
-
 /**
  * Base class for Layouts.
- * @param <T> The Class that the Layout will format the LogEvent into.
  */
-public abstract class AbstractLayout<T extends Serializable> implements
Layout<T> {
+public abstract class AbstractLayout implements Layout {
     /**
      * Allow subclasses access to the status logger without creating
another instance.
      */
Index:
src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
===================================================================
---
src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
(revision 1396432)
+++
src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
(working copy)
@@ -24,7 +24,7 @@
 /**
  * Base class for Layouts that result in a String.
  */
-public abstract class AbstractStringLayout extends AbstractLayout<String> {
+public abstract class AbstractStringLayout extends AbstractLayout {

     /**
      * The charset of the formatted message.
@@ -54,7 +54,7 @@
      * @return The formatted event as a byte array.
      */
     public byte[] format(LogEvent event) {
-        return encoder.getBytes(formatAs(event));
+        return encoder.getBytes(formatAs(event).toString());
     }

     protected Charset getCharset() {
Index: src/main/java/org/apache/logging/log4j/core/layout/HTMLLayout.java
===================================================================
--- src/main/java/org/apache/logging/log4j/core/layout/HTMLLayout.java
(revision 1396432)
+++ src/main/java/org/apache/logging/log4j/core/layout/HTMLLayout.java
(working copy)
@@ -27,6 +27,7 @@
 import java.io.InterruptedIOException;
 import java.io.LineNumberReader;
 import java.io.PrintWriter;
+import java.io.Serializable;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.lang.management.ManagementFactory;
@@ -73,7 +74,7 @@
      * @param event The Logging Event.
      * @return A String containging the LogEvent as HTML.
      */
-    public String formatAs(LogEvent event) {
+    public Serializable formatAs(LogEvent event) {
         StringBuilder sbuf = new StringBuilder(BUF_SIZE);

         sbuf.append(LINE_SEP).append("<tr>").append(LINE_SEP);
Index: src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
===================================================================
---
src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
(revision 1396432)
+++
src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
(working copy)
@@ -29,6 +29,7 @@
 import org.apache.logging.log4j.core.pattern.PatternParser;
 import org.apache.logging.log4j.core.pattern.RegexReplacement;

+import java.io.Serializable;
 import java.nio.charset.Charset;
 import java.util.List;

@@ -134,7 +135,7 @@
      * @param event logging event to be formatted.
      * @return The event formatted as a String.
      */
-    public String formatAs(final LogEvent event) {
+    public Serializable formatAs(final LogEvent event) {
         StringBuilder buf = new StringBuilder();
         for (PatternFormatter formatter : formatters) {
             formatter.format(event, buf);
Index: src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java
===================================================================
---
src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java
(revision 1396432)
+++
src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java
(working copy)
@@ -29,6 +29,7 @@
 import org.apache.logging.log4j.message.StructuredDataId;
 import org.apache.logging.log4j.message.StructuredDataMessage;

+import java.io.Serializable;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
@@ -151,7 +152,7 @@
      * @param event The LogEvent.
      * @return The RFC 5424 String representation of the LogEvent.
      */
-    public String formatAs(final LogEvent event) {
+    public Serializable formatAs(final LogEvent event) {
         Message msg = event.getMessage();
         boolean isStructured = msg instanceof StructuredDataMessage;
         StringBuilder buf = new StringBuilder();
Index:
src/main/java/org/apache/logging/log4j/core/layout/SerializedLayout.java
===================================================================
---
src/main/java/org/apache/logging/log4j/core/layout/SerializedLayout.java
(revision 1396432)
+++
src/main/java/org/apache/logging/log4j/core/layout/SerializedLayout.java
(working copy)
@@ -24,12 +24,13 @@
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
+import java.io.Serializable;

 /**
  * Format a LogEvent in its serialized form.
  */
 @Plugin(name = "SerializedLayout", type = "Core", elementType = "layout",
printObject = true)
-public final class SerializedLayout extends AbstractLayout<LogEvent> {
+public final class SerializedLayout extends AbstractLayout {

     private static byte[] header;

@@ -68,7 +69,7 @@
      * @param event The Logging Event.
      * @return The LogEvent.
      */
-    public LogEvent formatAs(final LogEvent event) {
+    public Serializable formatAs(final LogEvent event) {
         return event;
     }

Index: src/main/java/org/apache/logging/log4j/core/layout/SyslogLayout.java
===================================================================
--- src/main/java/org/apache/logging/log4j/core/layout/SyslogLayout.java
(revision 1396432)
+++ src/main/java/org/apache/logging/log4j/core/layout/SyslogLayout.java
(working copy)
@@ -23,6 +23,7 @@
 import org.apache.logging.log4j.core.net.Facility;
 import org.apache.logging.log4j.core.net.Priority;

+import java.io.Serializable;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.nio.charset.Charset;
@@ -61,7 +62,7 @@
      * @param event The LogEvent
      * @return the event formatted as a String.
      */
-    public String formatAs(final LogEvent event) {
+    public Serializable formatAs(final LogEvent event) {
         StringBuilder buf = new StringBuilder();

         buf.append("<");
Index: src/main/java/org/apache/logging/log4j/core/layout/XMLLayout.java
===================================================================
--- src/main/java/org/apache/logging/log4j/core/layout/XMLLayout.java
(revision 1396432)
+++ src/main/java/org/apache/logging/log4j/core/layout/XMLLayout.java
(working copy)
@@ -20,6 +20,7 @@
 import java.io.InterruptedIOException;
 import java.io.LineNumberReader;
 import java.io.PrintWriter;
+import java.io.Serializable;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.nio.charset.Charset;
@@ -93,7 +94,7 @@
      * @param event The LogEvent.
      * @return The XML representation of the LogEvent.
      */
-    public String formatAs(final LogEvent event) {
+    public Serializable formatAs(final LogEvent event) {
         StringBuilder buf = new StringBuilder(DEFAULT_SIZE);

         // We yield to the \r\n heresy.
Index: src/main/java/org/apache/logging/log4j/core/Layout.java
===================================================================
--- src/main/java/org/apache/logging/log4j/core/Layout.java    (revision
1396432)
+++ src/main/java/org/apache/logging/log4j/core/Layout.java    (working
copy)
@@ -23,9 +23,8 @@
  *  Would introduce an EventEncoder, EventRenderer or something similar
for the logging event to byte encoding.
  * (RG) A layout can be configured with a Charset and then Strings can be
converted to byte arrays. OTOH, it isn't
  * possible to write byte arrays as character streams.
- * @param <T> The Object type that will be returned on the formatAs call.
  */
-public interface Layout<T extends Serializable> {
+public interface Layout {
     /**
      * Formats the event suitable for display.
      * @param event The Logging Event.
@@ -41,7 +40,7 @@
      * @param event The Logging Event.
      * @return The formatted event.
      */
-    T formatAs(LogEvent event);
+    Serializable formatAs(LogEvent event);

     /**
      * Returns the header for the layout format.

Gary


> On Oct 9, 2012, at 6:23 AM, Gary Gregory wrote:
>
> Hi All:
>
> We currently have a generics warning for:
>
> org.apache.logging.log4j.core.Appender.getLayout()
>
> because the method is defined as:
>
> Layout getLayout();
>
> and Layout<T extends Serializable>
>
> Which hints at defining getLayout() as:
>
> Layout<T> getLayout();
>
> Which means either:
>
> <T extends Serializable> Layout<T> getLayout();
>
> or:
>
> public interface Appender<T extends Serializable> extends Lifecycle {
> ...
> Layout<T> getLayout();
>
> Now I also see:
>
> @issue LOG4J2-36 Refactor into Channel
>
> But the issue has been closed with no changes planned.
>
> So... thoughts?
>
> Gary
>
>
>
>
> --
> E-Mail: [email protected] | [email protected]
> JUnit in Action, 2nd Ed: <http://goog_1249600977/>http://bit.ly/ECvg0
> Spring Batch in Action: <http://s.apache.org/HOq>http://bit.ly/bqpbCK
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>
>
>


-- 
E-Mail: [email protected] | [email protected]
JUnit in Action, 2nd Ed: <http://goog_1249600977>http://bit.ly/ECvg0
Spring Batch in Action: <http://s.apache.org/HOq>http://bit.ly/bqpbCK
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Reply via email to