1 package org.oddjob.jobs; 2 3 import java.util.Date ; 4 5 import org.apache.log4j.MDC; 6 import org.oddjob.Resetable; 7 import org.oddjob.Stateful; 8 import org.oddjob.Stoppable; 9 import org.oddjob.Structural; 10 import org.oddjob.framework.BasePrimary; 11 import org.oddjob.images.IconHelper; 12 import org.oddjob.logging.Log4jArchiver; 13 import org.oddjob.state.AbstractJobStateListener; 14 import org.oddjob.state.JobState; 15 import org.oddjob.state.JobStateEvent; 16 import org.oddjob.structural.ChildHelper; 17 import org.oddjob.structural.StructuralListener; 18 import org.oddjob.util.OddjobLockedException; 19 20 47 48 49 public class IfJob extends BasePrimary 50 implements Runnable , Stateful, Resetable, Structural, Stoppable { 51 private static final long serialVersionUID = 20050806; 52 53 private boolean initialised; 54 55 61 private transient Runnable childJob; 62 63 69 private transient Runnable thenJob; 70 71 77 private transient Runnable elseJob; 78 79 80 86 private transient Runnable exceptionJob; 87 88 private transient ChildHelper childHelper = new ChildHelper(this); 89 90 private transient volatile boolean executingChild; 92 93 private transient JobStateEvent lastChildEvent; 94 private transient JobStateEvent lastDependantEvent; 95 96 class ChildListener extends AbstractJobStateListener { 97 protected void jobStateReady(Stateful source, Date time) { 98 lastChildEvent = new JobStateEvent( 99 IfJob.this, JobState.READY, time, null); 100 if (executingChild) { 101 return; 102 } 103 fireJobStateEvent(lastChildEvent); 104 } 105 106 protected void jobStateComplete(Stateful source, Date time) { 107 lastChildEvent = new JobStateEvent( 108 IfJob.this, JobState.COMPLETE, time, null); 109 if (executingChild) { 110 return; 111 } 112 if (lastDependantEvent == null) { 113 fireJobStateEvent(lastChildEvent); 115 } 116 else { 117 fireJobStateEvent(lastDependantEvent); 118 } 119 } 120 121 protected void jobStateNotComplete(Stateful source, Date time) { 122 lastChildEvent = new JobStateEvent( 123 IfJob.this, JobState.NOT_COMPLETE, time, null); 124 if (executingChild) { 125 return; 126 } 127 if (lastDependantEvent.getJobState() == JobState.EXCEPTION) { 128 if (lastDependantEvent == null) { 129 fireJobStateEvent(lastChildEvent); 131 } 132 else { 133 fireJobStateEvent(lastDependantEvent); 134 } 135 } else { 136 fireJobStateEvent(lastChildEvent); 137 } 138 } 139 protected void jobStateException(Stateful source, Date time, Throwable throwable) { 140 lastChildEvent = new JobStateEvent( 141 IfJob.this, JobState.EXCEPTION, time, throwable); 142 if (executingChild) { 143 return; 144 } 145 fireJobStateEvent(lastChildEvent); 146 } 147 } 148 149 private transient ChildListener childListener; 150 151 class DependentListener extends AbstractJobStateListener { 152 protected void jobStateReady(Stateful source, Date time) { 153 lastDependantEvent = new JobStateEvent( 154 IfJob.this, JobState.READY, time, null); 155 fireJobStateEvent(lastDependantEvent); 156 } 157 158 protected void jobStateComplete(Stateful source, Date time) { 159 lastDependantEvent = new JobStateEvent( 160 IfJob.this, JobState.COMPLETE, time, null); 161 fireJobStateEvent(lastChildEvent); 162 } 163 164 protected void jobStateNotComplete(Stateful source, Date time) { 165 lastDependantEvent = new JobStateEvent( 166 IfJob.this, JobState.NOT_COMPLETE, time, null); 167 if (lastChildEvent.getJobState() == JobState.EXCEPTION) { 168 fireJobStateEvent(lastChildEvent); 169 } else { 170 fireJobStateEvent(lastDependantEvent); 171 } 172 } 173 protected void jobStateException(Stateful source, Date time, Throwable throwable) { 174 lastDependantEvent = new JobStateEvent( 175 IfJob.this, JobState.EXCEPTION, time, throwable); 176 fireJobStateEvent(lastDependantEvent); 177 } 178 } 179 180 private transient DependentListener thenListener; 181 private transient DependentListener elseListener; 182 private transient DependentListener exceptionListener; 183 184 189 public void addComponentChild(Runnable child) 190 throws ClassCastException { 191 childJob = child; 192 childListener = new ChildListener(); 193 ((Stateful) childJob).addJobStateListener(childListener); 194 } 195 196 201 public void addComponentThen(Runnable then) { 202 thenJob = then; 203 thenListener = new DependentListener(); 204 ((Stateful) thenJob).addJobStateListener(thenListener); 205 } 206 207 212 public void addComponentElse(Runnable elze) { 213 elseJob = elze; 214 elseListener = new DependentListener(); 215 ((Stateful) elseJob).addJobStateListener(elseListener); 216 } 217 218 223 public void addComponentException(Runnable exception) { 224 exceptionJob = exception; 225 exceptionListener = new DependentListener(); 226 ((Stateful) exceptionJob).addJobStateListener(exceptionListener); 227 } 228 229 232 public void init() { 233 if (childJob == null) { 234 throw new IllegalStateException ("A child job is required."); 235 } 236 childHelper.addChild(childJob); 237 if (thenJob != null) { 238 childHelper.addChild(thenJob); 239 } 240 if (elseJob != null) { 241 childHelper.addChild(elseJob); 242 } 243 if (exceptionJob != null) { 244 childHelper.addChild(exceptionJob); 245 } 246 initialised = true; 247 } 248 249 public final void run() throws OddjobLockedException { 250 if (!initialised) { 251 throw new IllegalStateException ("Not initialised - remeber to call init()"); 252 } 253 lock.accquire("Job executing."); 254 String oldMDC = (String )MDC.get(Log4jArchiver.MDC); 255 try { 256 MDC.put(Log4jArchiver.MDC, getLogger()); 257 if (!stateHandler.requestJobStateExecuting()) { 258 logger().debug("Can't execute job [" + this + "] because state is [" 259 + stateHandler.getJobState() + "]"); 260 return; 261 } 262 iconHelper.changeIcon(IconHelper.EXECUTING); 263 264 if (!configure()) { 266 return; 267 } 268 logger().info("Executing job [" + this + "]"); 269 try { 270 execute(); 271 } 272 catch (Throwable e) { 273 logger().warn("Job Exception in [" + this + "]", e); 274 setJobStateException(e); 275 return; 276 } 277 278 logger().debug("Finished job [" + this + "]"); 279 } 280 finally { 281 if (oldMDC != null) { 282 MDC.put(Log4jArchiver.MDC, oldMDC); 283 } 284 else { 285 MDC.remove(Log4jArchiver.MDC); 286 } 287 lock.release(); 288 } 289 } 290 291 protected void execute() { 292 293 executingChild = true; 294 try { 295 childJob.run(); 296 } finally { 297 executingChild = false; 298 } 299 300 JobState jobState = lastChildEvent.getJobState(); 301 if (jobState == JobState.COMPLETE) { 302 if (thenJob != null) { 303 thenJob.run(); 304 } 305 else { 306 fireJobStateEvent(lastChildEvent); 307 } 308 } 309 else if (jobState == JobState.NOT_COMPLETE) { 310 if (elseJob != null) { 311 elseJob.run(); 312 } 313 else { 314 fireJobStateEvent(lastChildEvent); 315 } 316 } 317 else if (jobState == JobState.EXCEPTION) { 318 if (exceptionJob != null) { 319 exceptionJob.run(); 320 } 321 else { 322 fireJobStateEvent(lastChildEvent); 323 } 324 } 325 } 326 327 332 protected void fireJobStateEvent(JobStateEvent event) { 333 stateHandler.fireEvent(event); 334 JobState jobState = event.getJobState(); 335 if (jobState == JobState.READY) { 336 iconHelper.changeIcon(IconHelper.READY); 337 logger().info("Job [" + this + "] Ready."); 338 } 339 else if (jobState == JobState.COMPLETE) { 340 iconHelper.changeIcon(IconHelper.COMPLETE); 341 logger().info("Job [" + this + "] Complete."); 342 } 343 else if (jobState == JobState.NOT_COMPLETE) { 344 iconHelper.changeIcon(IconHelper.NOT_COMPLETE); 345 logger().info("Job [" + this + "] Not Complete."); 346 } 347 else if (jobState == JobState.EXCEPTION) { 348 iconHelper.changeIcon(IconHelper.EXCEPTION); 349 logger().warn("Job [" + this + "] Exception.", 350 event.getException()); 351 } 352 } 353 354 357 public void softReset() { 358 if (childJob instanceof Resetable) { 359 ((Resetable) childJob).softReset(); 360 } 361 if (thenJob != null && thenJob instanceof Resetable) { 362 ((Resetable) thenJob).hardReset(); 363 } 364 if (elseJob != null && elseJob instanceof Resetable) { 365 ((Resetable) elseJob).hardReset(); 366 } 367 if (exceptionJob != null && exceptionJob instanceof Resetable) { 368 ((Resetable) exceptionJob).hardReset(); 369 } 370 } 371 372 public void stop() { 373 if (destroyed) { 374 throw new IllegalStateException ("[" + this + "] destroyed"); 375 } 376 logger().debug("Thread [" + Thread.currentThread().getName() 377 + "] requested [" + getName() + "] stop."); 378 379 if (iconHelper.currentId()== IconHelper.EXECUTING) { 380 iconHelper.changeIcon(IconHelper.STOPPING); 381 } 382 383 stop = true; 384 childHelper.stopChildren(); 385 386 synchronized (this) { 387 notifyAll(); 388 } 389 } 390 391 394 public void hardReset() { 395 childHelper.hardResetChildren(); 396 } 397 398 404 public void addStructuralListener(StructuralListener listener) { 405 if (destroyed) { 406 throw new IllegalStateException ("[" + this + "] destroyed"); 407 } 408 childHelper.addStructuralListener(listener); 409 } 410 411 416 public void removeStructuralListener(StructuralListener listener) { 417 childHelper.removeStructuralListener(listener); 418 } 419 420 public void onDestroy() { 421 if (thenJob != null) { 422 ((Stateful) thenJob).removeJobStateListener(thenListener); 423 } 424 if (elseJob != null) { 425 ((Stateful) elseJob).removeJobStateListener(elseListener); 426 } 427 if (exceptionJob != null) { 428 ((Stateful) exceptionJob).removeJobStateListener(exceptionListener); 429 } 430 ((Stateful)childJob).removeJobStateListener(childListener); 431 childHelper.destroyAll(); 432 } 433 } 434 435 | Popular Tags |