Refactor for ConsoleAppender (and others next) to use inherited
Builders.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/2207cae2
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/2207cae2
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/2207cae2

Branch: 
refs/heads/LOG4J2-1010&LOG4J2-1447-injectable-contextdata&better-datastructure
Commit: 2207cae2a1213fda34cf94e5f08c49c2c9433e50
Parents: e3e37cc
Author: Gary Gregory <ggreg...@apache.org>
Authored: Wed Aug 10 20:09:29 2016 -0700
Committer: Gary Gregory <ggreg...@apache.org>
Committed: Wed Aug 10 20:09:29 2016 -0700

----------------------------------------------------------------------
 .../log4j/core/appender/AbstractAppender.java   | 58 +++++++++++++++
 .../appender/AbstractOutputStreamAppender.java  | 21 ++++++
 .../log4j/core/appender/ConsoleAppender.java    | 78 +++++++-------------
 .../log4j/core/filter/AbstractFilterable.java   | 27 +++++++
 .../core/appender/ConsoleAppenderTest.java      |  6 +-
 5 files changed, 134 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2207cae2/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
index 9f253a0..8df298f 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
@@ -23,7 +23,11 @@ import org.apache.logging.log4j.core.ErrorHandler;
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import 
org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
 import org.apache.logging.log4j.core.filter.AbstractFilterable;
+import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.util.Integers;
 
 /**
@@ -32,6 +36,60 @@ import org.apache.logging.log4j.core.util.Integers;
  */
 public abstract class AbstractAppender extends AbstractFilterable implements 
Appender {
 
+    /**
+     * Subclasses can extend this abstract Builder. 
+     * 
+     * @param <B> This builder class.
+     */
+    public abstract static class Builder<B extends Builder<B>> extends 
AbstractFilterable.Builder<B> {
+
+        @PluginBuilderAttribute
+        private boolean ignoreExceptions = true;
+        
+        @PluginElement("Layout")
+        @Required
+        private Layout<? extends Serializable> layout;
+
+        @PluginBuilderAttribute
+        @Required
+        private String name;
+
+        public String getName() {
+            return name;
+        }
+
+        public boolean isIgnoreExceptions() {
+            return ignoreExceptions;
+        }
+
+        public Layout<? extends Serializable> getLayout() {
+            return layout;
+        }
+
+        public B withName(String name) {
+            this.name = name;
+            return asBuilder();
+        }
+
+        public B withIgnoreExceptions(boolean ignoreExceptions) {
+            this.ignoreExceptions = ignoreExceptions;
+            return asBuilder();
+        }
+
+        public B withLayout(Layout<? extends Serializable> layout) {
+            this.layout = layout;
+            return asBuilder();
+        }
+
+        public Layout<? extends Serializable> getOrCreateLayout() {
+            if (layout == null) {
+                return PatternLayout.createDefaultLayout();
+            }
+            return layout;
+        }
+        
+    }
+    
     private final String name;
     private final boolean ignoreExceptions;
     private final Layout<? extends Serializable> layout;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2207cae2/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
index 4a95098..67e835a 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
@@ -21,6 +21,7 @@ import java.io.Serializable;
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.util.Constants;
 
 /**
@@ -31,6 +32,26 @@ import org.apache.logging.log4j.core.util.Constants;
 public abstract class AbstractOutputStreamAppender<M extends 
OutputStreamManager> extends AbstractAppender {
 
     /**
+     * Subclasses can extend this abstract Builder. 
+     * 
+     * @param <B> This builder class.
+     */
+    public abstract static class Builder<B extends Builder<B>> extends 
AbstractAppender.Builder<B> {
+    
+        @PluginBuilderAttribute
+        private boolean immediateFlush;
+
+        public boolean isImmediateFlush() {
+            return immediateFlush;
+        }
+
+        public B withImmediateFlush(boolean immediateFlush) {
+            this.immediateFlush = immediateFlush;
+            return asBuilder();
+        }
+    }
+    
+    /**
      * Immediate flush means that the underlying writer or output stream will 
be flushed at the end of each append
      * operation. Immediate flush is slower but ensures that each append 
request is actually written. If
      * <code>immediateFlush</code> is set to {@code false}, then there is a 
good chance that the last few logs events

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2207cae2/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
index 9747088..eed9319 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
@@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.appender.FileAppender.Builder;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
@@ -87,7 +88,7 @@ public final class ConsoleAppender extends 
AbstractOutputStreamAppender<OutputSt
      * @param ignore If {@code "true"} (default) exceptions encountered when 
appending events are logged; otherwise they
      *            are propagated to the caller.
      * @return The ConsoleAppender.
-     * @deprecated Use {@link #createAppender(Layout, Filter, Target, String, 
boolean, boolean, boolean)}.
+     * @deprecated Use {@link #newBuilder()}.
      */
     @Deprecated
     public static ConsoleAppender createAppender(Layout<? extends 
Serializable> layout,
@@ -122,17 +123,18 @@ public final class ConsoleAppender extends 
AbstractOutputStreamAppender<OutputSt
      * @param ignoreExceptions If {@code "true"} (default) exceptions 
encountered when appending events are logged; otherwise they
      *            are propagated to the caller.
      * @return The ConsoleAppender.
+     * @deprecated Use {@link #newBuilder()}.
      */
-    @PluginFactory
+    @Deprecated
     public static ConsoleAppender createAppender(
             // @formatter:off
-            @PluginElement("Layout") Layout<? extends Serializable> layout,
-            @PluginElement("Filter") final Filter filter,
-            @PluginAttribute(value = "target") Target target,
-            @PluginAttribute("name") final String name,
-            @PluginAttribute(value = "follow", defaultBoolean = false) final 
boolean follow,
-            @PluginAttribute(value = "direct", defaultBoolean = false) final 
boolean direct,
-            @PluginAttribute(value = "ignoreExceptions", defaultBoolean = 
true) final boolean ignoreExceptions) {
+            Layout<? extends Serializable> layout,
+            final Filter filter,
+            Target target,
+            final String name,
+            final boolean follow,
+            final boolean direct,
+            final boolean ignoreExceptions) {
             // @formatter:on
         if (name == null) {
             LOGGER.error("No name provided for ConsoleAppender");
@@ -156,72 +158,40 @@ public final class ConsoleAppender extends 
AbstractOutputStreamAppender<OutputSt
     }
 
     @PluginBuilderFactory
-    public static Builder newBuilder() {
-        return new Builder();
+    public static <B extends Builder<B>> B newBuilder() {
+        return new Builder<B>().asBuilder();
     }
 
     /**
      * Builds ConsoleAppender instances.
+     * @param <B> This builder class
      */
-    public static class Builder implements 
org.apache.logging.log4j.core.util.Builder<ConsoleAppender> {
-
-        @PluginElement("Layout")
-        @Required
-        private Layout<? extends Serializable> layout = 
PatternLayout.createDefaultLayout();
-
-        @PluginElement("Filter")
-        private Filter filter;
+    public static class Builder<B extends Builder<B>> extends 
AbstractOutputStreamAppender.Builder<B>
+            implements 
org.apache.logging.log4j.core.util.Builder<ConsoleAppender> {
 
         @PluginBuilderAttribute
         @Required
         private Target target = DEFAULT_TARGET;
 
         @PluginBuilderAttribute
-        @Required
-        private String name;
-
-        @PluginBuilderAttribute
         private boolean follow;
 
         @PluginBuilderAttribute
         private boolean direct;
 
-        @PluginBuilderAttribute
-        private boolean ignoreExceptions = true;
-
-        public Builder setLayout(final Layout<? extends Serializable> aLayout) 
{
-            this.layout = aLayout;
-            return this;
-        }
-
-        public Builder setFilter(final Filter aFilter) {
-            this.filter = aFilter;
-            return this;
-        }
-
-        public Builder setTarget(final Target aTarget) {
+        public B setTarget(final Target aTarget) {
             this.target = aTarget;
-            return this;
+            return asBuilder();
         }
 
-        public Builder setName(final String aName) {
-            this.name = aName;
-            return this;
-        }
-
-        public Builder setFollow(final boolean shouldFollow) {
+        public B setFollow(final boolean shouldFollow) {
             this.follow = shouldFollow;
-            return this;
+            return asBuilder();
         }
 
-        public Builder setDirect(final boolean shouldDirect) {
+        public B setDirect(final boolean shouldDirect) {
             this.direct = shouldDirect;
-            return this;
-        }
-
-        public Builder setIgnoreExceptions(final boolean 
shouldIgnoreExceptions) {
-            this.ignoreExceptions = shouldIgnoreExceptions;
-            return this;
+            return asBuilder();
         }
 
         @Override
@@ -229,7 +199,9 @@ public final class ConsoleAppender extends 
AbstractOutputStreamAppender<OutputSt
             if (follow && direct) {
                 throw new IllegalArgumentException("Cannot use both follow and 
direct on ConsoleAppender");
             }
-            return new ConsoleAppender(name, layout, filter, 
getManager(target, follow, direct, layout), ignoreExceptions, target);
+            Layout<? extends Serializable> layout = getOrCreateLayout();
+            return new ConsoleAppender(getName(), layout, getFilter(), 
getManager(target, follow, direct, layout),
+                    isIgnoreExceptions(), target);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2207cae2/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java
index 140a735..e57b58d 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java
@@ -21,6 +21,7 @@ import java.util.Iterator;
 import org.apache.logging.log4j.core.AbstractLifeCycle;
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
 
 /**
  * Enhances a Class by allowing it to contain Filters.
@@ -28,6 +29,32 @@ import org.apache.logging.log4j.core.LogEvent;
 public abstract class AbstractFilterable extends AbstractLifeCycle implements 
Filterable {
 
     /**
+     * Subclasses can extend this abstract Builder. 
+     * 
+     * @param <B> This builder class.
+     */
+    public abstract static class Builder<B extends Builder<B>> {
+
+        @PluginElement("Filter")
+        private Filter filter;
+
+        public Filter getFilter() {
+            return filter;
+        }
+
+        @SuppressWarnings("unchecked")
+        public B asBuilder() {
+            return (B) this;
+        }
+
+        public B withFilter(Filter filter) {
+            this.filter = filter;
+            return asBuilder();
+        }
+
+    }
+    
+    /**
      * May be null.
      */
     private volatile Filter filter;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2207cae2/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
index 9190359..80d024d 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
@@ -98,8 +98,8 @@ public class ConsoleAppenderTest {
             mocks.replayAll();
             systemSetter.systemSet(psMock);
             final Layout<String> layout = 
PatternLayout.newBuilder().withAlwaysWriteExceptions(true).build();
-            final ConsoleAppender app = ConsoleAppender.createAppender(layout, 
null, targetName, "Console", false, false,
-                    false);
+            final ConsoleAppender app = 
ConsoleAppender.newBuilder().withLayout(layout).setTarget(targetName)
+                    .withName("Console").withIgnoreExceptions(false).build();
             app.start();
             assertTrue("Appender did not start", app.isStarted());
 
@@ -131,7 +131,7 @@ public class ConsoleAppenderTest {
 
     private void testFollowSystemPrintStream(final PrintStream ps, final 
Target target, final SystemSetter systemSetter) {
         final ConsoleAppender app = 
ConsoleAppender.newBuilder().setTarget(target).setFollow(true)
-                .setIgnoreExceptions(false).build();
+                .withIgnoreExceptions(false).build();
         Assert.assertEquals(target, app.getTarget());
         app.start();
         try {

Reply via email to