/* * Copyright 2009 NCHOVY * * 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. */ package org.krakenapps.cron; import java.text.ParseException; import java.util.HashMap; import java.util.Map; import org.krakenapps.cron.impl.CronField; import org.krakenapps.cron.impl.CronField.Type; /** * Schedule used for registering cron jobs. * * @author periphery * @since 1.0.0 */ public final class Schedule { /** * fieldName to CronField mapping */ private final Map<String, CronField> map; private final String taskName; private Schedule() { this.map = null; this.taskName = null; } private Schedule(Builder builder) { this.map = new HashMap<String, CronField>(); this.map.put(Type.MINUTE.toString(), builder.map.get(Type.MINUTE.toString())); this.map.put(Type.HOUR.toString(), builder.map.get(Type.HOUR.toString())); this.map.put(Type.MONTH.toString(), builder.map.get(Type.MONTH.toString())); CronField dom = builder.map.get(Type.DAY_OF_MONTH.toString()); CronField dow = builder.map.get(Type.DAY_OF_WEEK.toString()); try { CronField.solveCollision(dom, dow); } catch (Exception e) { // must succeed. ignore. } this.map.put(Type.DAY_OF_MONTH.toString(), dom); this.map.put(Type.DAY_OF_WEEK.toString(), dow); this.taskName = builder.taskName; } /** * returns task Name */ public String getTaskName() { return this.taskName; } @Override public String toString() { return String.format("%8s %8s %8s %8s %8s / %8s", map.get("Minute"), map.get("Hour"), map.get("DayOfMonth"), map.get("Month"), map.get("DayOfWeek"), taskName); } /** * returns bitmap string of the given cron field used for debugging. */ public String fieldMembers(CronField.Type type) { return map.get(type.toString()).debugString(); } /** * returns members of the given cron field */ public CronField get(Type type) { return map.get(type.toString()); } @Override public boolean equals(Object sche) { return (sche instanceof Schedule) && this.toString().equals(((Schedule) sche).toString()); } @Override public int hashCode() { return this.toString().hashCode(); } /** * builder class for schedule class */ public static class Builder { private final Map<String, CronField> map; private final String taskName; /** * create new builder object. default scheduling rule is * "* * * * *"(minutely). */ public Builder(String taskName) { this.map = new HashMap<String, CronField>(); this.taskName = taskName; try { this.map.put("Minute", new CronField(CronField.Type.MINUTE, null)); this.map.put("Hour", new CronField(CronField.Type.HOUR, null)); this.map.put("DayOfMonth", new CronField(CronField.Type.DAY_OF_MONTH, null)); this.map.put("Month", new CronField(CronField.Type.MONTH, null)); this.map.put("DayOfWeek", new CronField(CronField.Type.DAY_OF_WEEK, null)); } catch (ParseException e) { // must succeed. ignored. } } /** * Set cron field with given expression. Following expressions are * supported. 1. comma(',') as list. e.g:"1,3,4,8" (space inside the * list must not be used) 2. dash('-') as range. e.g:"1-6", which means * 1 to 6 3. asterisk('*') as wild. e.g:"*", which means every~ 4. * slash('/') as interval. e.g:"* /5" which means every five~ (without * whitespace) */ public Builder set(CronField.Type type, String exp) throws ParseException { this.map.put(type.toString(), new CronField(type, exp)); return this; } /** * returns schedule object representing scheduling rule of current build * object. e.g. new * Schedule.Builder("test").set(CronField.Type.Minute,"5").build(); * represents schedule of "5 * * * * / test" */ public Schedule build() { return new Schedule(this); } /** * returns schedule object representing scheduling rule of given * expression. cron fields previously set by set() method are ignored. */ public Schedule build(String exp) throws Exception { String[] splited = exp.split(" "); if (splited.length != 5) throw new ParseException("wrong format", 0); set(CronField.Type.MINUTE, splited[0]); set(CronField.Type.HOUR, splited[1]); set(CronField.Type.DAY_OF_MONTH, splited[2]); set(CronField.Type.MONTH, splited[3]); set(CronField.Type.DAY_OF_WEEK, splited[4]); return build(); } /** * same as build("0 0 1 1 *") */ public Schedule buildYearly() { return mustSuccessBuild("0 0 1 1 *"); } /** * same as build("0 0 1 * *") */ public Schedule buildMonthly() { return mustSuccessBuild("0 0 1 * *"); } /** * same as build("0 0 * * 0") */ public Schedule buildWeekly() { return mustSuccessBuild("0 0 * * 0"); } /** * same as build("0 0 * * *") */ public Schedule buildDaily() { return mustSuccessBuild("0 0 * * *"); } /** * same as build("0 * * * *") */ public Schedule buildHourly() { return mustSuccessBuild("0 * * * *"); } private Schedule mustSuccessBuild(String expression) { try { return build(expression); } catch (Exception e) { // ignore all, not reachable return null; } } } }