下面列出了org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer#org.quartz.Calendar 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* <p>
* Update a calendar.
* </p>
*
* @param conn
* the DB Connection
* @param calendarName
* the name for the new calendar
* @param calendar
* the calendar
* @return the number of rows updated
* @throws IOException
* if there were problems serializing the calendar
*/
@Override
public int updateCalendar(Connection conn, String calendarName,
Calendar calendar) throws IOException, SQLException {
//log.debug( "Updating calendar " + calendarName + " : " + calendar );
ByteArrayOutputStream baos = serializeObject(calendar);
byte buf[] = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(buf);
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(rtp(UPDATE_CALENDAR));
ps.setBinaryStream(1, bais, buf.length);
ps.setString(2, calendarName);
return ps.executeUpdate();
} finally {
closeStatement(ps);
}
}
@Test
public void storeCalendar() throws Exception {
final String calendarName = "weekdayCalendar";
Calendar calendar = getCalendar();
jobStore.storeCalendar(calendarName, calendar, false, false);
final String calendarHashKey = schema.calendarHashKey(calendarName);
Map<String, String> calendarMap = jedis.hgetAll(calendarHashKey);
assertThat(calendarMap, hasKey("calendar_class"));
assertEquals(calendar.getClass().getName(), calendarMap.get("calendar_class"));
assertThat(calendarMap, hasKey("calendar_json"));
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> calendarJson = mapper.readValue(calendarMap.get("calendar_json"), new TypeReference<HashMap<String, Object>>() {
});
assertThat(calendarJson, hasKey("description"));
assertEquals("Only run on weekdays.", calendarJson.get("description"));
}
/**
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(Object arg0, Object arg1) {
java.util.Calendar c1 = (java.util.Calendar) arg0;
java.util.Calendar c2 = (java.util.Calendar) arg1;
int month1 = c1.get(java.util.Calendar.MONTH);
int month2 = c2.get(java.util.Calendar.MONTH);
int day1 = c1.get(java.util.Calendar.DAY_OF_MONTH);
int day2 = c2.get(java.util.Calendar.DAY_OF_MONTH);
if (month1 < month2) {
return -1;
}
if (month1 > month2) {
return 1;
}
if (day1 < day2) {
return -1;
}
if (day1 > day2) {
return 1;
}
return 0;
}
/**
* <p>
* Redefine a certain day to be excluded (true) or included (false).
* </p>
*/
public void setDayExcluded(java.util.Calendar day, boolean exclude) {
if (exclude) {
if (isDayExcluded(day)) {
return;
}
excludeDays.add(day);
dataSorted = false;
} else {
if (!isDayExcluded(day)) {
return;
}
removeExcludedDay(day, true);
}
}
public Calendar buildCalendar(List<CalendarInfo> infos) {
MultipleCalendar mulCalendar=null;
Collection<CalendarProvider> providers=applicationContext.getBeansOfType(CalendarProvider.class).values();
for(CalendarInfo info:infos){
for(CalendarProvider provider:providers){
Calendar calendar=provider.getCalendar(info.getId());
if(calendar!=null){
if(mulCalendar==null){
mulCalendar=new MultipleCalendar();;
}
mulCalendar.addCalendar((BaseCalendar)calendar);
}
}
}
return mulCalendar;
}
public int compare(java.util.Calendar c1, java.util.Calendar c2) {
int month1 = c1.get(java.util.Calendar.MONTH);
int month2 = c2.get(java.util.Calendar.MONTH);
int day1 = c1.get(java.util.Calendar.DAY_OF_MONTH);
int day2 = c2.get(java.util.Calendar.DAY_OF_MONTH);
if (month1 < month2) {
return -1;
}
if (month1 > month2) {
return 1;
}
if (day1 < day2) {
return -1;
}
if (day1 > day2) {
return 1;
}
return 0;
}
/**
* <p>
* Determine whether the given time (in milliseconds) is 'included' by the
* Calendar.
* </p>
*
* <p>
* Note that this Calendar is only has full-day precision.
* </p>
*/
@Override
public boolean isTimeIncluded(long timeStamp) {
if (excludeAll == true) {
return false;
}
// Test the base calendar first. Only if the base calendar not already
// excludes the time/date, continue evaluating this calendar instance.
if (super.isTimeIncluded(timeStamp) == false) { return false; }
java.util.Calendar cl = createJavaCalendar(timeStamp);
int day = cl.get(java.util.Calendar.DAY_OF_MONTH);
return !(isDayExcluded(day));
}
/**
* <p>
* Called when the <code>{@link Scheduler}</code> has decided to 'fire'
* the trigger (execute the associated <code>Job</code>), in order to
* give the <code>Trigger</code> a chance to update itself for its next
* triggering (if any).
* </p>
*
* @see #executionComplete(JobExecutionContext, JobExecutionException)
*/
@Override
public void triggered(Calendar calendar) {
timesTriggered++;
previousFireTime = nextFireTime;
nextFireTime = getFireTimeAfter(nextFireTime);
while (nextFireTime != null && calendar != null
&& !calendar.isTimeIncluded(nextFireTime.getTime())) {
nextFireTime = getFireTimeAfter(nextFireTime);
if(nextFireTime == null)
break;
//avoid infinite loop
java.util.Calendar c = java.util.Calendar.getInstance();
c.setTime(nextFireTime);
if (c.get(java.util.Calendar.YEAR) > YEAR_TO_GIVEUP_SCHEDULING_AT) {
nextFireTime = null;
}
}
}
/**
* <p>
* Determine whether the given time (in milliseconds) is 'included' by the
* Calendar.
* </p>
*
* <p>
* Note that this Calendar is only has full-day precision.
* </p>
*/
@Override
public boolean isTimeIncluded(long timeStamp) {
if (excludeAll == true) {
return false;
}
// Test the base calendar first. Only if the base calendar not already
// excludes the time/date, continue evaluating this calendar instance.
if (super.isTimeIncluded(timeStamp) == false) { return false; }
java.util.Calendar cl = createJavaCalendar(timeStamp);
int wday = cl.get(java.util.Calendar.DAY_OF_WEEK);
return !(isDayExcluded(wday));
}
/**
* <p>
* Determine the next time (in milliseconds) that is 'included' by the
* Calendar after the given time. Return the original value if timeStamp is
* included. Return 0 if all days are excluded.
* </p>
*
* <p>
* Note that this Calendar is only has full-day precision.
* </p>
*/
public long getNextIncludedTime(long timeStamp) {
// Call base calendar implementation first
long baseTime = super.getNextIncludedTime(timeStamp);
if ((baseTime > 0) && (baseTime > timeStamp)) {
timeStamp = baseTime;
}
// Get timestamp for 00:00:00
java.util.Calendar day = getStartOfDayJavaCalendar(timeStamp);
if (isDayExcluded(day) == false) {
return timeStamp; // return the original value
}
while (isDayExcluded(day) == true) {
day.add(java.util.Calendar.DATE, 1);
}
return day.getTime().getTime();
}
/**
* <p>
* Determine the next time (in milliseconds) that is 'included' by the
* Calendar after the given time.
* </p>
*
* <p>
* Note that this Calendar is only has full-day precision.
* </p>
*/
@Override
public long getNextIncludedTime(long timeStamp) {
// Call base calendar implementation first
long baseTime = super.getNextIncludedTime(timeStamp);
if ((baseTime > 0) && (baseTime > timeStamp)) {
timeStamp = baseTime;
}
// Get timestamp for 00:00:00
java.util.Calendar day = getStartOfDayJavaCalendar(timeStamp);
while (isTimeIncluded(day.getTime().getTime()) == false) {
day.add(java.util.Calendar.DATE, 1);
}
return day.getTime().getTime();
}
private void doUpdateOfMisfiredTrigger(Connection conn, OperableTrigger trig, boolean forceState, String newStateIfNotComplete, boolean recovering) throws JobPersistenceException {
Calendar cal = null;
if (trig.getCalendarName() != null) {
cal = retrieveCalendar(conn, trig.getCalendarName());
}
schedSignaler.notifyTriggerListenersMisfired(trig);
trig.updateAfterMisfire(cal);
if (trig.getNextFireTime() == null) {
storeTrigger(conn, trig,
null, true, STATE_COMPLETE, forceState, recovering);
schedSignaler.notifySchedulerListenersFinalized(trig);
} else {
storeTrigger(conn, trig, null, true, newStateIfNotComplete,
forceState, false);
}
}
public ApiBootQuartzAutoConfiguration(ApiBootQuartzProperties properties, ObjectProvider<SchedulerFactoryBeanCustomizer> customizers, JobDetail[] jobDetails, Map<String, Calendar> calendars, Trigger[] triggers, ApplicationContext applicationContext) {
this.properties = properties;
this.customizers = customizers;
this.jobDetails = jobDetails;
this.calendars = calendars;
this.triggers = triggers;
this.applicationContext = applicationContext;
}
/**
* @see org.quartz.impl.triggers.AbstractTrigger#updateWithNewCalendar(org.quartz.Calendar, long)
*/
@Override
public void updateWithNewCalendar(Calendar calendar, long misfireThreshold)
{
nextFireTime = getFireTimeAfter(previousFireTime);
if (nextFireTime == null || calendar == null) {
return;
}
Date now = new Date();
while (nextFireTime != null && !calendar.isTimeIncluded(nextFireTime.getTime())) {
nextFireTime = getFireTimeAfter(nextFireTime);
if(nextFireTime == null)
break;
//avoid infinite loop
java.util.Calendar c = java.util.Calendar.getInstance();
c.setTime(nextFireTime);
if (c.get(java.util.Calendar.YEAR) > YEAR_TO_GIVEUP_SCHEDULING_AT) {
nextFireTime = null;
}
if(nextFireTime != null && nextFireTime.before(now)) {
long diff = now.getTime() - nextFireTime.getTime();
if(diff >= misfireThreshold) {
nextFireTime = getFireTimeAfter(nextFireTime);
}
}
}
}
public JobQuartzAutoConfiguration(QuartzProperties properties, JobServerProperties jobServerProperties, ObjectProvider<SchedulerFactoryBeanCustomizer> customizers, ObjectProvider<JobDetail[]> jobDetails, ObjectProvider<Map<String, Calendar>> calendars, ObjectProvider<Trigger[]> triggers, ApplicationContext applicationContext) {
this.properties = properties;
this.jobServerProperties = jobServerProperties;
this.customizers = customizers;
this.jobDetails = (JobDetail[]) jobDetails.getIfAvailable();
this.calendars = (Map) calendars.getIfAvailable();
this.triggers = (Trigger[]) triggers.getIfAvailable();
this.applicationContext = applicationContext;
// 初始化job属性配置信息
initJobProperties(this.properties);
}
public ApiBootQuartzAutoConfiguration(ApiBootQuartzProperties properties, ObjectProvider<SchedulerFactoryBeanCustomizer> customizers, JobDetail[] jobDetails, Map<String, Calendar> calendars, Trigger[] triggers, ApplicationContext applicationContext) {
this.properties = properties;
this.customizers = customizers;
this.jobDetails = jobDetails;
this.calendars = calendars;
this.triggers = triggers;
this.applicationContext = applicationContext;
}
/**
* <p>
* Calls the equivalent method on the 'proxied' <code>QuartzScheduler</code>.
* </p>
*/
public void addCalendar(String calName, Calendar calendar, boolean replace, boolean updateTriggers)
throws SchedulerException {
try {
getRemoteScheduler().addCalendar(calName, calendar,
replace, updateTriggers);
} catch (RemoteException re) {
throw invalidateHandleCreateException(
"Error communicating with remote scheduler.", re);
}
}
/**
* Helper to find a calendar by name.
*/
@Nullable
private Calendar findCalendar(final ODatabaseDocumentTx db, final String name) {
CalendarEntity calendarEntity = calendarEntityAdapter.readByName(db, name);
if (calendarEntity != null) {
return calendarEntity.getValue();
}
return null;
}
public Calendar getCalendar(final String calName) {
try {
return scheduler.getCalendar(calName);
} catch (final SchedulerException e) {
throw new QuartzSchedulerException(e);
}
}
public TriggerFiredBundle(JobDetail job, Trigger trigger, Calendar cal,
boolean jobIsRecovering, Date fireTime, Date scheduledFireTime,
Date prevFireTime, Date nextFireTime) {
this.job = job;
this.trigger = trigger;
this.cal = cal;
this.jobIsRecovering = jobIsRecovering;
this.fireTime = fireTime;
this.scheduledFireTime = scheduledFireTime;
this.prevFireTime = prevFireTime;
this.nextFireTime = nextFireTime;
}
/**
* <p>
* Get the <code>{@link Calendar}</code> instance with the given name.
* </p>
*/
public Calendar getCalendar(String calName)
throws SchedulerException {
validateState();
return resources.getJobStore().retrieveCalendar(calName);
}
@Override
public void storeCalendar(String name, Calendar calendar, boolean replaceExisting, boolean updateTriggers)
throws ObjectAlreadyExistsException, JobPersistenceException {
try {
realJobStore.storeCalendar(name, calendar, replaceExisting, updateTriggers);
} catch (RejoinException e) {
throw new JobPersistenceException("Storing calendar failed due to client rejoin", e);
}
}
/**
* <p>
* Store the given <code>{@link org.quartz.Calendar}</code>.
* </p>
*
* @param calendar The <code>Calendar</code> to be stored.
* @param replaceExisting If <code>true</code>, any <code>Calendar</code> existing in the <code>JobStore</code> with
* the same name & group should be over-written.
* @param updateTriggers If <code>true</code>, any <code>Trigger</code>s existing in the <code>JobStore</code> that
* reference an existing Calendar with the same name with have their next fire time re-computed with the new
* <code>Calendar</code>.
* @throws ObjectAlreadyExistsException if a <code>Calendar</code> with the same name already exists, and
* replaceExisting is set to false.
*/
@Override
public void storeCalendar(String name, Calendar calendar, boolean replaceExisting, boolean updateTriggers)
throws ObjectAlreadyExistsException, JobPersistenceException {
Calendar clone = (Calendar) calendar.clone();
lock();
try {
Calendar cal = calendarsByName.get(name);
if (cal != null && replaceExisting == false) {
throw new ObjectAlreadyExistsException("Calendar with name '" + name + "' already exists.");
} else if (cal != null) {
calendarsByName.remove(name);
}
Calendar cw = clone;
calendarsByName.putNoReturn(name, cw);
if (cal != null && updateTriggers) {
for (TriggerWrapper tw : triggerFacade.getTriggerWrappersForCalendar(name)) {
boolean removed = timeTriggers.remove(tw);
tw.updateWithNewCalendar(clone, getMisfireThreshold(), triggerFacade);
if (removed) {
timeTriggers.add(tw);
}
}
}
} finally {
unlock();
}
}
boolean applyMisfire(TriggerWrapper tw) throws JobPersistenceException {
long misfireTime = System.currentTimeMillis();
if (getMisfireThreshold() > 0) {
misfireTime -= getMisfireThreshold();
}
Date tnft = tw.getNextFireTime();
if (tnft == null || tnft.getTime() > misfireTime
|| tw.getMisfireInstruction() == Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY) { return false; }
Calendar cal = null;
if (tw.getCalendarName() != null) {
cal = retrieveCalendar(tw.getCalendarName());
}
signaler.notifyTriggerListenersMisfired(tw.getTriggerClone());
tw.updateAfterMisfire(cal, triggerFacade);
if (tw.getNextFireTime() == null) {
tw.setState(TriggerState.COMPLETE, terracottaClientId, triggerFacade);
signaler.notifySchedulerListenersFinalized(tw.getTriggerClone());
timeTriggers.remove(tw);
} else if (tnft.equals(tw.getNextFireTime())) { return false; }
return true;
}
/**
* Store calendar in redis.
*
* @param name the name
* @param calendar the calendar
* @param replaceExisting the replace existing
* @param updateTriggers the update triggers
* @param jedis thread-safe redis connection
* @throws ObjectAlreadyExistsException the object already exists exception
* @throws JobPersistenceException
*/
private void storeCalendar(String name, Calendar calendar,
boolean replaceExisting, boolean updateTriggers, Jedis jedis)
throws ObjectAlreadyExistsException, JobPersistenceException {
String calendarHashKey = createCalendarHashKey(name);
if (jedis.exists(calendarHashKey) && !replaceExisting)
throw new ObjectAlreadyExistsException(calendarHashKey + " already exists");
Gson gson = new Gson();
Map<String, String> calendarHash = new HashMap<>();
calendarHash.put(CALENDAR_CLASS, calendar.getClass().getName());
calendarHash.put(CALENDAR_SERIALIZED, gson.toJson(calendar));
jedis.hmset(calendarHashKey, calendarHash);
jedis.sadd(CALENDARS_SET, calendarHashKey);
if (updateTriggers) {
String calendarTriggersSetkey = createCalendarTriggersSetKey(name);
Set<String> triggerHasjKeys = jedis.smembers(calendarTriggersSetkey);
for (String triggerHashKey : triggerHasjKeys) {
OperableTrigger trigger = retrieveTrigger(new TriggerKey(triggerHashKey.split(":")[2], triggerHashKey.split(":")[1]), jedis);
long removed = jedis.zrem(RedisTriggerState.WAITING.getKey(), triggerHashKey);
trigger.updateWithNewCalendar(calendar, getMisfireThreshold());
if (removed == 1)
setTriggerState(RedisTriggerState.WAITING, (double)trigger.getNextFireTime().getTime(), triggerHashKey);
}
}
}
/**
* Determine whether or not the given trigger has misfired.
* If so, notify the {@link org.quartz.spi.SchedulerSignaler} and update the trigger.
* @param trigger the trigger to check for misfire
* @param jedis a thread-safe Redis connection
* @return false if the trigger has misfired; true otherwise
* @throws JobPersistenceException
*/
protected boolean applyMisfire(OperableTrigger trigger, T jedis) throws JobPersistenceException {
long misfireTime = System.currentTimeMillis();
if(misfireThreshold > 0){
misfireTime -= misfireThreshold;
}
final Date nextFireTime = trigger.getNextFireTime();
if(nextFireTime == null || nextFireTime.getTime() > misfireTime
|| trigger.getMisfireInstruction() == Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY){
return false;
}
Calendar calendar = null;
if(trigger.getCalendarName() != null){
calendar = retrieveCalendar(trigger.getCalendarName(), jedis);
}
signaler.notifyTriggerListenersMisfired((OperableTrigger) trigger.clone());
trigger.updateAfterMisfire(calendar);
storeTrigger(trigger, true, jedis);
if(trigger.getNextFireTime() == null){
setTriggerState(RedisTriggerState.COMPLETED, (double) System.currentTimeMillis(), redisSchema.triggerHashKey(trigger.getKey()), jedis);
signaler.notifySchedulerListenersFinalized(trigger);
}
else if(nextFireTime.equals(trigger.getNextFireTime())){
return false;
}
return true;
}
/**
* Store a {@link Calendar}
*
* @param name the name of the calendar
* @param calendar the calendar object to be stored
* @param replaceExisting if true, any existing calendar with the same name will be overwritten
* @param updateTriggers if true, any existing triggers associated with the calendar will be updated
* @param jedis a thread-safe Redis connection
* @throws JobPersistenceException
*/
@Override
public void storeCalendar(String name, Calendar calendar, boolean replaceExisting, boolean updateTriggers, JedisClusterCommandsWrapper jedis) throws JobPersistenceException {
final String calendarHashKey = redisSchema.calendarHashKey(name);
if (!replaceExisting && jedis.exists(calendarHashKey)) {
throw new ObjectAlreadyExistsException(String.format("Calendar with key %s already exists.", calendarHashKey));
}
Map<String, String> calendarMap = new HashMap<>();
calendarMap.put(CALENDAR_CLASS, calendar.getClass().getName());
try {
calendarMap.put(CALENDAR_JSON, mapper.writeValueAsString(calendar));
} catch (JsonProcessingException e) {
throw new JobPersistenceException("Unable to serialize calendar.", e);
}
jedis.hmset(calendarHashKey, calendarMap);
jedis.sadd(redisSchema.calendarsSet(), calendarHashKey);
if (updateTriggers) {
final String calendarTriggersSetKey = redisSchema.calendarTriggersSetKey(name);
Set<String> triggerHashKeys = jedis.smembers(calendarTriggersSetKey);
for (String triggerHashKey : triggerHashKeys) {
OperableTrigger trigger = retrieveTrigger(redisSchema.triggerKey(triggerHashKey), jedis);
long removed = jedis.zrem(redisSchema.triggerStateKey(RedisTriggerState.WAITING), triggerHashKey);
trigger.updateWithNewCalendar(calendar, misfireThreshold);
if (removed == 1) {
setTriggerState(RedisTriggerState.WAITING, (double) trigger.getNextFireTime().getTime(), triggerHashKey, jedis);
}
}
}
}
protected boolean applyMisfire(TriggerWrapper tw) {
long misfireTime = System.currentTimeMillis();
if (getMisfireThreshold() > 0) {
misfireTime -= getMisfireThreshold();
}
Date tnft = tw.trigger.getNextFireTime();
if (tnft == null || tnft.getTime() > misfireTime) {
return false;
}
Calendar cal = null;
if (tw.trigger.getCalendarName() != null) {
cal = retrieveCalendar(null, tw.trigger.getCalendarName());
}
signaler.notifyTriggerListenersMisfired((Trigger)tw.trigger.clone());
tw.trigger.updateAfterMisfire(cal);
if (tw.trigger.getNextFireTime() == null) {
tw.state = TriggerWrapper.STATE_COMPLETE;
signaler.notifySchedulerListenersFinalized(tw.trigger);
synchronized (lock) {
timeTriggers.remove(tw);
}
} else if (tnft.equals(tw.trigger.getNextFireTime())) {
return false;
}
return true;
}
/**
* <p>
* Get the <code>{@link Calendar}</code> instance with the given name.
* </p>
*/
public Calendar getCalendar(SchedulingContext ctxt, String calName)
throws SchedulerException {
validateState();
return resources.getJobStore().retrieveCalendar(ctxt, calName);
}
@Test(expected = JobPersistenceException.class)
public void storeCalendarNoReplace() throws Exception {
final String calendarName = "weekdayCalendar";
Calendar calendar = getCalendar();
jobStore.storeCalendar(calendarName, calendar, false, false);
jobStore.storeCalendar(calendarName, calendar, false, false);
}