/**
* Copyright 1996-2014 FoxBPM ORG.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @author MAENLIANG
*/
package org.foxbpm.engine.impl.schedule;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.foxbpm.engine.exception.FoxBPMException;
import org.foxbpm.engine.impl.expression.ExpressionMgmt;
import org.foxbpm.engine.impl.util.ClockUtil;
import org.foxbpm.engine.impl.util.ExceptionUtil;
import org.foxbpm.engine.impl.util.QuartzUtil;
import org.foxbpm.engine.impl.util.StringUtil;
import org.foxbpm.kernel.runtime.FlowNodeExecutionContext;
import org.foxbpm.kernel.runtime.ListenerExecutionContext;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.JobDetailImpl;
/**
* FOXBPM 工作详细
*
* @author MAENLIANG
* @date 2014-06-25
*
*/
public class FoxbpmJobDetail<T extends Job> extends JobDetailImpl {
/**
* serialVersionUID
*/
private static final long serialVersionUID = -1555130032039717646L;
protected JobDetail jobDetail;
protected T foxbpmJob;
protected List<Trigger> triggerList = new ArrayList<Trigger>();
public FoxbpmJobDetail(T foxbpmJob) {
this.foxbpmJob = foxbpmJob;
if (foxbpmJob instanceof FoxbpmScheduleJob) {
this.jobDetail = JobBuilder.newJob(foxbpmJob.getClass()).withIdentity(((FoxbpmScheduleJob) foxbpmJob).getName(), ((FoxbpmScheduleJob) foxbpmJob).getGroupName()).build();
} else {
throw new FoxBPMException("非 FoxbpmScheduleJob ,无法创建FoxbpmJobDetail!");
}
}
/**
* 创建两种类型TRIGGER
*
* @param startDate
* @param cronExpression
* @param triggerName
* @param groupName
* @return trigger
*/
public void createTrigger(Object startDate, String cronExpression, String durationExpression,
String triggerName, String groupName) {
Trigger trigger = null;
TriggerBuilder<Trigger> withIdentity = newTrigger().withIdentity(triggerName, groupName);
if (startDate == null && isBlank(cronExpression) && isBlank(durationExpression)) {
throw new FoxBPMException("自动启动流程实例,启动时间表达式为空!");
} else if (startDate != null) {
// Date 启动
if (startDate instanceof Date) {
Date date = (Date) startDate;
trigger = withIdentity.startAt(date).build();
} else if (startDate instanceof String) {
Date date = ClockUtil.parseStringToDate((String) startDate);
trigger = withIdentity.startAt(date).build();
} else {
throw new FoxBPMException("自动启动流程实例,启动时间表达式有错误!");
}
} else if (isNotBlank(cronExpression)) {
// CRON表达式启动
trigger = withIdentity.withSchedule(cronSchedule(cronExpression)).build();
} else if (isNotBlank(durationExpression)) {
// TODO DURATION Expression暂时未实现
}
triggerList.add(trigger);
}
/**
* 只支持创建TRIGGER 和 日期
* @param timeExpression
* @param executionContext
* @param groupName
*/
@SuppressWarnings("unchecked")
public void createDateTimeTriggerList(String timeExpression,
ListenerExecutionContext executionContext, String groupName) {
if (timeExpression == null || StringUtil.isBlank(timeExpression)) {
return;
}
List<Trigger> triggersList = new ArrayList<Trigger>();
Object triggerObj = null;
try {
triggerObj = ExpressionMgmt.execute(timeExpression,(FlowNodeExecutionContext)executionContext);
} catch (Exception e1) {
throw ExceptionUtil.getException("10304005", e1, timeExpression);
}
if (triggerObj == null) {
throw new FoxBPMException("FoxbpmJobDetail创建TRIGGER LIST时候,TIMER 表达式执行结果为NULL");
}
if (triggerObj instanceof List) {
try {
triggersList = (List<Trigger>) triggerObj;
} catch (Exception e) {
throw new FoxBPMException("FoxbpmJobDetail创建的触发器集合必须为List<Trigger>");
}
} else if (triggerObj instanceof Trigger) {
triggersList.add((Trigger) triggerObj);
} else if (triggerObj instanceof Date) {
triggersList.add(QuartzUtil.createTriggerByDateTime(triggerObj, groupName));
} else {
throw new FoxBPMException("创建TRIGGER LIST时候,TIMER 表达式执行错误");
}
this.triggerList = triggersList;
}
/**
* 只支持创建表达式和TRIGGER
* @param timeExpression
* @param executionContext
* @param groupName
*/
@SuppressWarnings("unchecked")
public void createTriggerListByCycle(String timeExpression,
ListenerExecutionContext executionContext, String groupName) {
if (timeExpression == null || StringUtil.isBlank(timeExpression)) {
return;
}
List<Trigger> triggersList = new ArrayList<Trigger>();
Object triggerObj = ExpressionMgmt.execute(timeExpression, executionContext);
if (triggerObj == null) {
throw new FoxBPMException("FoxbpmJobDetail创建TRIGGER LIST时候,TIMER 表达式执行结果为NULL");
}
if (triggerObj instanceof List) {
try {
triggersList = (List<Trigger>) triggerObj;
} catch (Exception e) {
throw new FoxBPMException("FoxbpmJobDetail创建的触发器集合必须为List<Trigger>");
}
} else if (triggerObj instanceof Trigger) {
triggersList.add((Trigger) triggerObj);
} else if (triggerObj instanceof String) {
triggersList.add(QuartzUtil.createCronTrigger(groupName, triggerObj.toString()));
} else {
throw new FoxBPMException("创建TRIGGER LIST时候,TIMER 表达式执行错误");
}
this.triggerList = triggersList;
}
public void putContextAttribute(String attributeName, Object attribute) {
this.jobDetail.getJobDataMap().put(attributeName, attribute);
}
public JobDetail getJobDetail() {
return jobDetail;
}
public void setJobDetail(JobDetail jobDetail) {
this.jobDetail = jobDetail;
}
public T getFoxbpmJob() {
return foxbpmJob;
}
public void setFoxbpmJob(T foxbpmJob) {
this.foxbpmJob = foxbpmJob;
}
public List<Trigger> getTriggerList() {
return triggerList;
}
public void setTriggerList(List<Trigger> triggerList) {
this.triggerList = triggerList;
}
}