Package org.drools.process.instance.timer

Source Code of org.drools.process.instance.timer.TimerManager$ProcessJobContext

package org.drools.process.instance.timer;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.drools.WorkingMemory;
import org.drools.process.instance.ProcessInstance;
import org.drools.time.Job;
import org.drools.time.JobContext;
import org.drools.time.JobHandle;
import org.drools.time.TimerService;
import org.drools.time.Trigger;

/**
*
* @author <a href="mailto:kris_verlaenen@hotmail.com">Kris Verlaenen</a>
*/
public class TimerManager {
    private long          timerId = 0;

    private WorkingMemory workingMemory;
    private TimerService  timerService;
    private Map<Long, TimerInstance> timers = new HashMap<Long, TimerInstance>();
    private Job processJob = new ProcessJob();

    public TimerManager(WorkingMemory workingMemory, TimerService timerService) {
        this.workingMemory = workingMemory;
        this.timerService = timerService;
    }

    public void registerTimer(final TimerInstance timer,
                              ProcessInstance processInstance) {
        timer.setId( ++timerId );
        timer.setProcessInstanceId(processInstance.getId());
        timer.setActivated(new Date());
       
        ProcessJobContext ctx = new ProcessJobContext( timer,
                                                       processInstance.getId(),
                                                       this.workingMemory );

        JobHandle jobHandle = this.timerService.scheduleJob( processJob,
                                                             ctx,
                                                             new TimerTrigger( timerService.getCurrentTime(),
                                                                               timer.getDelay(),
                                                                               timer.getPeriod() ) );
        timer.setJobHandle( jobHandle );
        timers.put(timer.getId(), timer);
    }

    public void internalAddTimer(final TimerInstance timer) {
    ProcessJobContext ctx = new ProcessJobContext(
      timer, timer.getProcessInstanceId(), this.workingMemory);

    long delay;
    Date lastTriggered = timer.getLastTriggered();
    if (lastTriggered == null) {
      Date activated = timer.getActivated();
      Date now = new Date();
      long timespan = now.getTime() - activated.getTime();
      delay = timer.getDelay() - timespan;
      if (delay < 0) {
        delay = 0;
      }
    } else {
      Date now = new Date();
      long timespan = now.getTime() - lastTriggered.getTime();
      delay = timespan - timer.getPeriod();
      if (delay < 0) {
        delay = 0;
      }
    }
    JobHandle jobHandle = this.timerService.scheduleJob(
      processJob, ctx, new TimerTrigger(timerService.getCurrentTime(),
                                              delay,
                                              timer.getPeriod()));
    timer.setJobHandle(jobHandle);
    timers.put(timer.getId(), timer);
  }

    public void cancelTimer(long timerId) {
      TimerInstance timer = timers.remove(timerId);
      if (timer != null) {
        timerService.removeJob( timer.getJobHandle() );
      }
    }
   
    public void dispose() {
      for (TimerInstance timer: timers.values()) {
        timerService.removeJob( timer.getJobHandle() );
      }
    }
   
    public TimerService getTimerService() {
        return this.timerService;
    }
   
    public Collection<TimerInstance> getTimers() {
      return timers.values();
    }
   
    public long internalGetTimerId() {
      return timerId;
    }
   
    public void internalSetTimerId(long timerId) {
      this.timerId = timerId;
    }
   
    public void setTimerService(TimerService timerService) {
        this.timerService = timerService;
    }

    public class ProcessJob implements Job {
     
        public void execute(JobContext c) {
            ProcessJobContext ctx = (ProcessJobContext) c;

            Long processInstanceId = ctx.getProcessInstanceId();
            WorkingMemory workingMemory = ctx.getWorkingMemory();

            if ( processInstanceId == null ) {
                throw new IllegalArgumentException( "Could not find process instance for timer " );
            }
           
            ctx.getTimer().setLastTriggered(new Date());
           
            ProcessInstance processInstance = ( ProcessInstance ) workingMemory.getProcessInstance( processInstanceId );
            // process instance may have finished already
            if ( processInstance != null ) {
                workingMemory.getSignalManager().signalEvent(processInstance, "timerTriggered", ctx.getTimer());
            }

            if (ctx.getTimer().getPeriod() == 0) {
              TimerManager.this.timers.remove(ctx.getTimer().getId());
            }
        }

    }

    public static class TimerTrigger
        implements
        Trigger {
        private Date next;
        private long period;

        public TimerTrigger() {
           
        }
       
        public TimerTrigger(long currentTS,
                            long delay,
                            long period) {
            this.next = new Date( currentTS + delay  );
            this.period = period;
        }

        public Date hasNextFireTime() {
            return next;
        }
       
        public Date nextFireTime() {
            Date date = next;
            if ( this.period != 0 ) {
                // repeated fires for the given period
                // FIXME: this is not safe for serialization
                next = new Date( next.getTime() + this.period );               
            } else {
                next = null;
            }
            return date;
        }

        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.next = (Date) in.readObject();
            this.period = in.readLong();
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeObject( this.next );
            out.writeLong( this.period );
        }

    }

    public static class ProcessJobContext
        implements
        JobContext {
        private Long          processInstanceId;
        private WorkingMemory workingMemory;
        private TimerInstance timer;

        private JobHandle     jobHandle;

        public ProcessJobContext(final TimerInstance timer,
                                 final Long processInstanceId,
                                 final WorkingMemory workingMemory) {
            this.timer = timer;
            this.processInstanceId = processInstanceId;
            this.workingMemory = workingMemory;
        }

        public Long getProcessInstanceId() {
            return processInstanceId;
        }

        public WorkingMemory getWorkingMemory() {
            return workingMemory;
        }

        public JobHandle getJobHandle() {
            return this.jobHandle;
        }

        public void setJobHandle(JobHandle jobHandle) {
            this.jobHandle = jobHandle;
        }

        public TimerInstance getTimer() {
            return timer;
        }

    }

}
TOP

Related Classes of org.drools.process.instance.timer.TimerManager$ProcessJobContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.