001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.server.dispatch;
030:
031: import com.caucho.config.ConfigException;
032: import com.caucho.config.types.Period;
033: import com.caucho.log.Log;
034: import com.caucho.util.IntArray;
035: import com.caucho.util.L10N;
036: import com.caucho.util.QDate;
037:
038: import java.util.logging.Logger;
039:
040: /**
041: * Configuration for a run-at
042: */
043: public class RunAt {
044: static L10N L = new L10N(RunAt.class);
045: private static final Logger log = Log.open(RunAt.class);
046:
047: private QDate _cal = QDate.createLocal();
048:
049: private long _period = -1;
050:
051: private IntArray _hourTimes;
052: private IntArray _minuteTimes;
053:
054: /**
055: * Creates a new servlet configuration object.
056: */
057: public RunAt() {
058: }
059:
060: /**
061: * Adds the text.
062: */
063: public void addText(String runAt) throws ConfigException {
064: configureRunAt(runAt);
065: }
066:
067: /**
068: * Sets the period
069: */
070: public void setPeriod(Period period) throws ConfigException {
071: _period = period.getPeriod();
072: }
073:
074: /**
075: * Returns the next time.
076: */
077: public long getNextTimeout(long now) {
078: _cal.setGMTTime(now);
079: long zone = _cal.getZoneOffset();
080:
081: if (_period > 0)
082: return Period.periodEnd(now + zone, _period) - zone;
083:
084: now = now - now % 60000;
085:
086: long local = now + zone;
087:
088: long dayMinutes = (local / 60000) % (24 * 60);
089: long hourMinutes = dayMinutes % 60;
090:
091: long nextDelta = Long.MAX_VALUE;
092:
093: for (int i = 0; _hourTimes != null && i < _hourTimes.size(); i++) {
094: long time = _hourTimes.get(i);
095: long delta = (time - dayMinutes + 24 * 60) % (24 * 60);
096:
097: if (delta == 0)
098: delta = 24 * 60;
099:
100: if (delta < nextDelta && delta > 0)
101: nextDelta = delta;
102: }
103:
104: for (int i = 0; _minuteTimes != null && i < _minuteTimes.size(); i++) {
105: long time = _minuteTimes.get(i);
106: long delta = (time - hourMinutes + 60) % 60;
107:
108: if (delta == 0)
109: delta = 60;
110:
111: if (delta < nextDelta && delta > 0)
112: nextDelta = delta;
113: }
114:
115: if (nextDelta < Integer.MAX_VALUE)
116: return now + nextDelta * 60000L;
117: else
118: return Long.MAX_VALUE / 2;
119: }
120:
121: /**
122: * Configures the run-at time.
123: */
124: private void configureRunAt(String string) throws ConfigException {
125: int len = string.length();
126: char ch = 0;
127: int i = 0;
128: while (true) {
129: for (; i < len
130: && (Character.isWhitespace(ch = string.charAt(i)) || ch == ','); i++) {
131: }
132:
133: if (i >= len)
134: return;
135:
136: if (!(ch >= '0' && ch <= '9' || ch == ':'))
137: throw new ConfigException(
138: L
139: .l(
140: "illegal run-at time `{0}'. Run-at values are either hour (0:00, 6:30, 12:15) or minute (:15, :30, :45).",
141: string));
142:
143: int hour = 0;
144: int minute = 0;
145: boolean hasHour = false;
146: for (; i < len && (ch = string.charAt(i)) >= '0'
147: && ch <= '9'; i++) {
148: hasHour = true;
149: hour = 10 * hour + ch - '0';
150: }
151:
152: if (ch == ':') {
153: i++;
154: for (; i < len && (ch = string.charAt(i)) >= '0'
155: && ch <= '9'; i++)
156: minute = 10 * minute + ch - '0';
157:
158: }
159:
160: if (hasHour) {
161: if (_hourTimes == null)
162: _hourTimes = new IntArray();
163: _hourTimes.add(60 * hour + minute);
164: } else {
165: if (_minuteTimes == null)
166: _minuteTimes = new IntArray();
167: _minuteTimes.add(minute);
168: }
169: }
170: }
171: }
|