View Javadoc

1   /*
2    Copyright 2008 Ramon Servadei
3   
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7   
8    http://www.apache.org/licenses/LICENSE-2.0
9   
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15   */
16  package fulmine;
17  
18  import static fulmine.util.Utils.safeToString;
19  import fulmine.util.log.AsyncLog;
20  
21  /**
22   * Base-class for all {@link ILifeCycle} instances.
23   * 
24   * @author Ramon Servadei
25   * 
26   */
27  public abstract class AbstractLifeCycle implements ILifeCycle
28  {
29      private final static AsyncLog LOG = new AsyncLog(AbstractLifeCycle.class);
30  
31      /**
32       * The active flag. Uses the <a
33       * href="http://www.ibm.com/developerworks/java/library/j-jtp06197.html"
34       * >'cheap read-write lock'</a>
35       */
36      private volatile boolean active;
37  
38      public AbstractLifeCycle()
39      {
40          super();
41      }
42  
43      public final boolean isActive()
44      {
45          return this.active;
46      }
47  
48      /**
49       * Overridden in subclasses to perform custom logic on activation. Any
50       * exceptions should be thrown as a {@link RuntimeException} or subclass
51       * thereof. When this method is called, the {@link #isActive()} method will
52       * return <code>true</code>.
53       */
54      protected abstract void doStart();
55  
56      /**
57       * Overridden in subclasses to perform custom logic on destruction. Any
58       * exceptions should be thrown as a {@link RuntimeException} or subclass
59       * thereof.
60       */
61      protected abstract void doDestroy();
62  
63      public final void start()
64      {
65          boolean start = false;
66          synchronized (this)
67          {
68              if (!isActive())
69              {
70                  this.active = true;
71                  start = true;
72              }
73          }
74          if (start)
75          {
76              if (getLog().isTraceEnabled())
77              {
78                  getLog().trace("Starting " + safeToString(this));
79              }
80              try
81              {
82                  doStart();
83              }
84              catch (RuntimeException e)
85              {
86                  getLog().warn("Exception starting " + safeToString(this), e);
87                  throw e;
88              }
89          }
90      }
91  
92      public final void destroy()
93      {
94          boolean destroy = false;
95          synchronized (this)
96          {
97              if (isActive())
98              {
99                  this.active = false;
100                 destroy = true;
101             }
102         }
103         if (destroy)
104         {
105             if (getLog().isTraceEnabled())
106             {
107                 getLog().trace("Destroying " + safeToString(this));
108             }
109             try
110             {
111                 doDestroy();
112             }
113             catch (RuntimeException e)
114             {
115                 getLog().warn("Exception destroying " + safeToString(this), e);
116             }
117         }
118     }
119 
120     @Override
121     protected final void finalize() throws Throwable
122     {
123         super.finalize();
124         destroy();
125     }
126 
127     /**
128      * Get the log to use for the object hierarchy
129      * 
130      * @return the log to use for the object hierarchy
131      */
132     protected AsyncLog getLog()
133     {
134         return LOG;
135     }
136 
137     /**
138      * Check if this instance is active.
139      * 
140      * @throws IllegalStateException
141      *             if this is not active
142      */
143     protected void checkActive()
144     {
145         if (!isActive())
146         {
147             throw new IllegalStateException(this + " is not active.");
148         }
149     }
150 
151     @Override
152     public String toString()
153     {
154         return getClass().getSimpleName();
155     }
156 }