View Javadoc

1   /* ============================================================
2    * JRobin : Pure java implementation of RRDTool's functionality
3    * ============================================================
4    *
5    * Project Info:  http://www.jrobin.org
6    * Project Lead:  Sasa Markovic (saxon@jrobin.org);
7    *
8    * (C) Copyright 2003-2005, by Sasa Markovic.
9    *
10   * Developers:    Sasa Markovic (saxon@jrobin.org)
11   *
12   *
13   * This library is free software; you can redistribute it and/or modify it under the terms
14   * of the GNU Lesser General Public License as published by the Free Software Foundation;
15   * either version 2.1 of the License, or (at your option) any later version.
16   *
17   * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18   * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19   * See the GNU Lesser General Public License for more details.
20   *
21   * You should have received a copy of the GNU Lesser General Public License along with this
22   * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23   * Boston, MA 02111-1307, USA.
24   */
25  package org.jrobin.core.timespec;
26  
27  class TimeScanner {
28  	private String dateString;
29  
30  	private int pos, pos_save;
31  	private TimeToken token, token_save;
32  
33  	static final TimeToken[] WORDS = {
34  			new TimeToken("midnight", TimeToken.MIDNIGHT),	/* 00:00:00 of today or tomorrow */
35  			new TimeToken("noon", TimeToken.NOON),		/* 12:00:00 of today or tomorrow */
36  			new TimeToken("teatime", TimeToken.TEATIME),	/* 16:00:00 of today or tomorrow */
37  			new TimeToken("am", TimeToken.AM),		/* morning times for 0-12 clock */
38  			new TimeToken("pm", TimeToken.PM),		/* evening times for 0-12 clock */
39  			new TimeToken("tomorrow", TimeToken.TOMORROW),
40  			new TimeToken("yesterday", TimeToken.YESTERDAY),
41  			new TimeToken("today", TimeToken.TODAY),
42  			new TimeToken("now", TimeToken.NOW),
43  			new TimeToken("n", TimeToken.NOW),
44  			new TimeToken("start", TimeToken.START),
45  			new TimeToken("s", TimeToken.START),
46  			new TimeToken("end", TimeToken.END),
47  			new TimeToken("e", TimeToken.END),
48  			new TimeToken("jan", TimeToken.JAN),
49  			new TimeToken("feb", TimeToken.FEB),
50  			new TimeToken("mar", TimeToken.MAR),
51  			new TimeToken("apr", TimeToken.APR),
52  			new TimeToken("may", TimeToken.MAY),
53  			new TimeToken("jun", TimeToken.JUN),
54  			new TimeToken("jul", TimeToken.JUL),
55  			new TimeToken("aug", TimeToken.AUG),
56  			new TimeToken("sep", TimeToken.SEP),
57  			new TimeToken("oct", TimeToken.OCT),
58  			new TimeToken("nov", TimeToken.NOV),
59  			new TimeToken("dec", TimeToken.DEC),
60  			new TimeToken("january", TimeToken.JAN),
61  			new TimeToken("february", TimeToken.FEB),
62  			new TimeToken("march", TimeToken.MAR),
63  			new TimeToken("april", TimeToken.APR),
64  			new TimeToken("may", TimeToken.MAY),
65  			new TimeToken("june", TimeToken.JUN),
66  			new TimeToken("july", TimeToken.JUL),
67  			new TimeToken("august", TimeToken.AUG),
68  			new TimeToken("september", TimeToken.SEP),
69  			new TimeToken("october", TimeToken.OCT),
70  			new TimeToken("november", TimeToken.NOV),
71  			new TimeToken("december", TimeToken.DEC),
72  			new TimeToken("sunday", TimeToken.SUN),
73  			new TimeToken("sun", TimeToken.SUN),
74  			new TimeToken("monday", TimeToken.MON),
75  			new TimeToken("mon", TimeToken.MON),
76  			new TimeToken("tuesday", TimeToken.TUE),
77  			new TimeToken("tue", TimeToken.TUE),
78  			new TimeToken("wednesday", TimeToken.WED),
79  			new TimeToken("wed", TimeToken.WED),
80  			new TimeToken("thursday", TimeToken.THU),
81  			new TimeToken("thu", TimeToken.THU),
82  			new TimeToken("friday", TimeToken.FRI),
83  			new TimeToken("fri", TimeToken.FRI),
84  			new TimeToken("saturday", TimeToken.SAT),
85  			new TimeToken("sat", TimeToken.SAT),
86  			new TimeToken(null, 0)			/*** SENTINEL ***/
87  	};
88  
89  	static TimeToken[] MULTIPLIERS = {
90  			new TimeToken("second", TimeToken.SECONDS),	/* seconds multiplier */
91  			new TimeToken("seconds", TimeToken.SECONDS),	/* (pluralized) */
92  			new TimeToken("sec", TimeToken.SECONDS),		/* (generic) */
93  			new TimeToken("s", TimeToken.SECONDS),		/* (short generic) */
94  			new TimeToken("minute", TimeToken.MINUTES),	/* minutes multiplier */
95  			new TimeToken("minutes", TimeToken.MINUTES),	/* (pluralized) */
96  			new TimeToken("min", TimeToken.MINUTES),		/* (generic) */
97  			new TimeToken("m", TimeToken.MONTHS_MINUTES),	/* (short generic) */
98  			new TimeToken("hour", TimeToken.HOURS),		/* hours ... */
99  			new TimeToken("hours", TimeToken.HOURS),		/* (pluralized) */
100 			new TimeToken("hr", TimeToken.HOURS),		/* (generic) */
101 			new TimeToken("h", TimeToken.HOURS),		/* (short generic) */
102 			new TimeToken("day", TimeToken.DAYS),		/* days ... */
103 			new TimeToken("days", TimeToken.DAYS),		/* (pluralized) */
104 			new TimeToken("d", TimeToken.DAYS),		/* (short generic) */
105 			new TimeToken("week", TimeToken.WEEKS),		/* week ... */
106 			new TimeToken("weeks", TimeToken.WEEKS),		/* (pluralized) */
107 			new TimeToken("wk", TimeToken.WEEKS),		/* (generic) */
108 			new TimeToken("w", TimeToken.WEEKS),		/* (short generic) */
109 			new TimeToken("month", TimeToken.MONTHS),	/* week ... */
110 			new TimeToken("months", TimeToken.MONTHS),	/* (pluralized) */
111 			new TimeToken("mon", TimeToken.MONTHS),		/* (generic) */
112 			new TimeToken("year", TimeToken.YEARS),		/* year ... */
113 			new TimeToken("years", TimeToken.YEARS),		/* (pluralized) */
114 			new TimeToken("yr", TimeToken.YEARS),		/* (generic) */
115 			new TimeToken("y", TimeToken.YEARS),		/* (short generic) */
116 			new TimeToken(null, 0)			/*** SENTINEL ***/
117 	};
118 
119 	TimeToken[] specials = WORDS;
120 
121 	public TimeScanner(String dateString) {
122 		this.dateString = dateString;
123 	}
124 
125 	void setContext(boolean parsingWords) {
126 		specials = parsingWords ? WORDS : MULTIPLIERS;
127 	}
128 
129 	TimeToken nextToken() {
130 		StringBuffer buffer = new StringBuffer("");
131 		while (pos < dateString.length()) {
132 			char c = dateString.charAt(pos++);
133 			if (Character.isWhitespace(c) || c == '_' || c == ',') {
134 				continue;
135 			}
136 			buffer.append(c);
137 			if (Character.isDigit(c)) {
138 				// pick as many digits as possible
139 				while (pos < dateString.length()) {
140 					char next = dateString.charAt(pos);
141 					if (Character.isDigit(next)) {
142 						buffer.append(next);
143 						pos++;
144 					}
145 					else {
146 						break;
147 					}
148 				}
149 				String value = buffer.toString();
150 				return token = new TimeToken(value, TimeToken.NUMBER);
151 			}
152 			if (Character.isLetter(c)) {
153 				// pick as many letters as possible
154 				while (pos < dateString.length()) {
155 					char next = dateString.charAt(pos);
156 					if (Character.isLetter(next)) {
157 						buffer.append(next);
158 						pos++;
159 					}
160 					else {
161 						break;
162 					}
163 				}
164 				String value = buffer.toString();
165 				return token = new TimeToken(value, parseToken(value));
166 			}
167 			switch (c) {
168 				case ':':
169 					return token = new TimeToken(":", TimeToken.COLON);
170 				case '.':
171 					return token = new TimeToken(".", TimeToken.DOT);
172 				case '+':
173 					return token = new TimeToken("+", TimeToken.PLUS);
174 				case '-':
175 					return token = new TimeToken("-", TimeToken.MINUS);
176 				case '/':
177 					return token = new TimeToken("/", TimeToken.SLASH);
178 				default:
179 					pos--;
180 					return token = new TimeToken(null, TimeToken.EOF);
181 			}
182 		}
183 		return token = new TimeToken(null, TimeToken.EOF);
184 	}
185 
186 	TimeToken resolveMonthsMinutes(int newId) {
187 		assert token.id == TimeToken.MONTHS_MINUTES;
188 		assert newId == TimeToken.MONTHS || newId == TimeToken.MINUTES;
189 		return token = new TimeToken(token.value, newId);
190 	}
191 
192 	void saveState() {
193 		token_save = token;
194 		pos_save = pos;
195 	}
196 
197 	TimeToken restoreState() {
198 		pos = pos_save;
199 		return token = token_save;
200 	}
201 
202 	private int parseToken(String arg) {
203 		for (int i = 0; specials[i].value != null; i++) {
204 			if (specials[i].value.equalsIgnoreCase(arg)) {
205 				return specials[i].id;
206 			}
207 		}
208 		return TimeToken.ID;
209 	}
210 }