Do we really want two LifeCycle abstract classes?

Will this not be a case -- like plug in builders vs. factory methods --
where we have two ways of doing the same thing?

When do I use one vs. the other? You'd need to Javadoc that at least.

Shouldn't we just have one way of doing this?

Gary
---------- Forwarded message ----------
From: <mattsic...@apache.org>
Date: Wed, Sep 24, 2014 at 1:39 AM
Subject: [2/4] git commit: Add LifeCycle abstract class that uses
AtomicReference.
To: comm...@logging.apache.org


Add LifeCycle abstract class that uses AtomicReference.


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

Branch: refs/heads/master
Commit: 1a332afa33c55a72ae8ab5ec83cd5964de3fdc67
Parents: b701951
Author: Matt Sicker <mattsic...@apache.org>
Authored: Sun Sep 21 20:30:50 2014 -0500
Committer: Matt Sicker <mattsic...@apache.org>
Committed: Tue Sep 23 23:32:49 2014 -0500

----------------------------------------------------------------------
 .../log4j/core/AbstractAtomicLifeCycle.java     | 102 +++++++++++++++++++
 .../apache/logging/log4j/core/LifeCycle.java    |   9 +-
 2 files changed, 108 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1a332afa/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractAtomicLifeCycle.java
----------------------------------------------------------------------
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractAtomicLifeCycle.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractAtomicLifeCycle.java
new file mode 100644
index 0000000..05a343a
--- /dev/null
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/AbstractAtomicLifeCycle.java
@@ -0,0 +1,102 @@
+package org.apache.logging.log4j.core;
+
+import java.io.Serializable;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.logging.log4j.core.util.Throwables;
+import org.apache.logging.log4j.status.StatusLogger;
+
+/**
+ * An extensible {@link LifeCycle} using an {@link AtomicReference} to
wrap its {@link LifeCycle.State}. Thus, classes
+ * which extend this class will follow the finite state machine as follows:
+ * <ol>
+ * <li>When {@link #start()} is called, {@link #doStart()} is called if
and only if this is in the INITIALIZED state or
+ * the STOPPED state.</li>
+ * <li>Before {@link #doStart()} is called, this will be in the STARTING
state.</li>
+ * <li>After {@link #doStart()} is called, this will be in the STARTED
state if no exception was thrown; otherwise,
+ * this will be in the INITIALIZED state again, and the exception thrown
will be re-thrown (if unchecked) or wrapped
+ * in an {@link java.lang.reflect.UndeclaredThrowableException} and then
rethrown (if checked).</li>
+ * <li>When {@link #stop()} is called, {@link #doStop()} is called if and
only if this is in the STARTED state.</li>
+ * <li>Before {@link #doStop()} is called, this will be in the STOPPING
state.</li>
+ * <li>After {@link #doStop()} is called, this will be in the STOPPED
state. Any exceptions thrown will be re-thrown
+ * as described above.</li>
+ * </ol>
+ *
+ * @since 2.1
+ */
+public abstract class AbstractAtomicLifeCycle implements LifeCycle,
Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    protected static final StatusLogger LOGGER = StatusLogger.getLogger();
+
+    private final AtomicReference<State> state = new
AtomicReference<State>(State.INITIALIZED);
+
+    @Override
+    public void start() {
+        if (state.compareAndSet(State.INITIALIZED, State.STARTING) ||
+            state.compareAndSet(State.STOPPED, State.STARTING)) {
+            try {
+                doStart();
+                state.set(State.STARTED);
+            } catch (final Exception e) {
+                state.set(State.INITIALIZED);
+                Throwables.rethrow(e);
+            }
+        }
+    }
+
+    /**
+     * Performs the start-up logic. This method is called only if this is
in the INITIALIZED or STOPPED state.
+     *
+     * @throws Exception
+     */
+    protected abstract void doStart() throws Exception;
+
+    @Override
+    public void stop() {
+        if (state.compareAndSet(State.STARTED, State.STOPPING)) {
+            try {
+                doStop();
+            } catch (Exception e) {
+                Throwables.rethrow(e);
+            } finally {
+                state.set(State.STOPPED);
+            }
+        }
+    }
+
+    /**
+     * Performs the tear-down logic. This method is called only if this is
in the STARTED state.
+     *
+     * @throws Exception
+     */
+    protected abstract void doStop() throws Exception;
+
+    @Override
+    public boolean isStarted() {
+        return state.get() == State.STARTED;
+    }
+
+    @Override
+    public boolean isStopped() {
+        return state.get() == State.STOPPED;
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        final AbstractAtomicLifeCycle that = (AbstractAtomicLifeCycle) o;
+        return state.equals(that.state);
+    }
+
+    @Override
+    public int hashCode() {
+        return state.hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1a332afa/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java
----------------------------------------------------------------------
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java
index e75ebd5..191edcd 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LifeCycle.java
@@ -18,7 +18,7 @@
 package org.apache.logging.log4j.core;

 /**
- * All proper Java frameworks implement some sort of object life cycle. In
Log4j, the main interface for handling
+ * Generic object life cycle support interface. In Log4j, the main
interface for handling
  * the life cycle context of an object is this one. An object first starts
in the {@link State#INITIALIZED} state
  * by default to indicate the class has been loaded. From here, calling
the {@link #start()} method will change this
  * state to {@link State#STARTING}. After successfully being started, this
state is changed to {@link State#STARTED}.
@@ -26,9 +26,12 @@ package org.apache.logging.log4j.core;
  * stopped, this goes into the {@link State#STOPPED} state. In most
circumstances, implementation classes should
  * store their {@link State} in a {@code volatile} field or inside an
  * {@link java.util.concurrent.atomic.AtomicReference} dependant on
synchronization and concurrency requirements.
+ *
+ * @see AbstractLifeCycle
+ * @see AbstractAtomicLifeCycle
  */
 public interface LifeCycle {
-
+
     /**
      * Status of a life cycle like a {@link LoggerContext}.
      */
@@ -44,7 +47,7 @@ public interface LifeCycle {
         /** Has stopped. */
         STOPPED
     }
-
+
     void start();

     void stop();




-- 
E-Mail: garydgreg...@gmail.com | ggreg...@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Reply via email to