KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > oddjob > framework > StructuralJob


1 package org.oddjob.framework;
2
3
4 import java.util.Date JavaDoc;
5
6 import org.apache.log4j.MDC;
7 import org.oddjob.Resetable;
8 import org.oddjob.Stateful;
9 import org.oddjob.Structural;
10 import org.oddjob.images.IconHelper;
11 import org.oddjob.logging.Log4jArchiver;
12 import org.oddjob.state.AbstractJobStateListener;
13 import org.oddjob.structural.StatefulChildHelper;
14 import org.oddjob.structural.StructuralListener;
15 import org.oddjob.util.OddjobLockedException;
16
17 /**
18  * An abstract implementation of a job which provides commen functionality to
19  * concrete sub classes.
20  *
21  * @author Rob Gordon
22  */

23
24 public abstract class StructuralJob extends BasePrimary
25         implements
26             Runnable JavaDoc, Resetable, Stateful, Structural {
27
28     /**
29      * Intended to be used by decendent classes to
30      * help implement Structural.
31      */

32     protected StatefulChildHelper childHelper;
33             
34     /** Use to suppress child state changes when executing. */
35     private volatile boolean executing;
36     
37     public StructuralJob() {
38         completeConstruction();
39     }
40     
41     /**
42      * Complete construction after constructor or
43      * maybe one day deserialisation.
44      *
45      */

46     private void completeConstruction() {
47         childHelper = new StatefulChildHelper(this);
48         childHelper.addJobStateListener(new AbstractJobStateListener() {
49             protected void jobStateReady(Stateful source, Date JavaDoc time) {
50                 if (!executing) {
51                     StructuralJob.super.setJobStateReady();
52                     logger().info("Job [" + StructuralJob.this
53                             + "] Ready.");
54                 }
55             }
56             protected void jobStateComplete(Stateful source, Date JavaDoc time) {
57                 if (!executing) {
58                     StructuralJob.super.setJobStateComplete();
59                     logger().info("Job [" + StructuralJob.this
60                             + "] Complete.");
61                 }
62             }
63             protected void jobStateNotComplete(Stateful source, Date JavaDoc time) {
64                 if (!executing) {
65                     StructuralJob.super.setJobStateNotComplete();
66                     logger().info("Job [" + StructuralJob.this
67                             + "] Not Complete.");
68                 }
69             }
70             /* (non-Javadoc)
71              * @see org.oddjob.state.AbstractJobStateListener#jobStateException(org.oddjob.Stateful, java.util.Date, java.lang.Throwable)
72              */

73             protected void jobStateException(Stateful source, Date JavaDoc time,
74                     Throwable JavaDoc throwable) {
75                 if (!executing) {
76                     StructuralJob.super.setJobStateException(throwable);
77                     logger().warn("Job [" + StructuralJob.this
78                             + "] Exception.", throwable);
79                 }
80             }
81         });
82     }
83     
84     
85     /*
86      * (non-Javadoc)
87      * @see org.oddjob.framework.BaseComponent#independant()
88      */

89     protected boolean independant() {
90         return true;
91     }
92         
93     /**
94      * Execute this job.
95      *
96      * @throws Exception If the unexpected occurs.
97      */

98     abstract protected void execute() throws Throwable JavaDoc;
99
100     /**
101      * Implement the main execute method for a job. This surrounds the
102      * doExecute method of the sub class and sets state for the job.
103      */

104     public final void run() throws OddjobLockedException {
105         lock.accquire("Job executing.");
106         String JavaDoc oldMDC = (String JavaDoc)MDC.get(Log4jArchiver.MDC);
107         try {
108             MDC.put(Log4jArchiver.MDC, getLogger());
109             if (!stateHandler.requestJobStateExecuting()) {
110                 logger().debug("Can't execute job [" + this + "] because state is ["
111                         + stateHandler.getJobState() + "]");
112                 return;
113             }
114             iconHelper.changeIcon(IconHelper.EXECUTING);
115             executing = true;
116             
117             // runtime configuration.
118
if (!configure()) {
119                 executing = false;
120                 return;
121             }
122             
123             logger().info("Executing job [" + this + "]");
124             try {
125                 execute();
126                 // we ignore state while executing but now we need to update.
127
// dependent on our child states.
128
// synchronize so this updates before any child states trigger.
129
synchronized (stateHandler) {
130                     executing = false;
131                     childHelper.refreshState();
132                 }
133             }
134             catch (Throwable JavaDoc e) {
135                 executing = false;
136                 logger().warn("Job Exception in [" + this + "]", e);
137                 setJobStateException(e);
138             }
139         }
140         finally {
141             if (oldMDC != null) {
142                 MDC.put(Log4jArchiver.MDC, oldMDC);
143             }
144             else {
145                 MDC.remove(Log4jArchiver.MDC);
146             }
147             lock.release();
148         }
149     }
150     
151     /**
152      * Implementation for a typical stop. Subclasses must implement
153      * Stoppable to take advantage of it.
154      * <p>
155      * This stop implementation doesn't check that the job is
156      * executing as stop messages must cascade down the hierarchy
157      * to manually started jobs.
158      */

159     public void stop() {
160         if (destroyed) {
161             throw new IllegalStateException JavaDoc("[" + this + "] destroyed");
162         }
163         logger().debug("Thread [" + Thread.currentThread().getName()
164                 + "] requested [" + getName() + "] stop.");
165         
166         if (iconHelper.currentId()== IconHelper.EXECUTING) {
167             iconHelper.changeIcon(IconHelper.STOPPING);
168         }
169         
170         stop = true;
171         childHelper.stopChildren();
172         
173         synchronized (this) {
174             notifyAll();
175         }
176     }
177     
178     /**
179      * Perform a soft reset on the job.
180      */

181     public void softReset() {
182         lock.accquire("Soft Reset in progress.");
183         try {
184             childHelper.softResetChildren();
185             stop = false;
186         } finally {
187             lock.release();
188         }
189     }
190     
191     /**
192      * Perform a hard reset on the job.
193      */

194     public void hardReset() {
195         lock.accquire("Hard Reset in progress.");
196         try {
197             childHelper.hardResetChildren();
198             stop = false;
199         } finally {
200             lock.release();
201         }
202     }
203
204     /**
205      * Add a listener. The listener will immediately recieve add
206      * notifications for all existing children.
207      *
208      * @param listener The listener.
209      */

210     public void addStructuralListener(StructuralListener listener) {
211         if (destroyed) {
212             throw new IllegalStateException JavaDoc("[" + this + "] destroyed");
213         }
214         childHelper.addStructuralListener(listener);
215     }
216     
217     /**
218      * Remove a listener.
219      *
220      * @param listener The listner.
221      */

222     public void removeStructuralListener(StructuralListener listener) {
223         childHelper.removeStructuralListener(listener);
224     }
225     
226     /**
227      * Destroy this component.
228      */

229     public void onDestroy() {
230         childHelper.destroyAll();
231     }
232         
233 }
234
Popular Tags