001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.filter.text.cql2;
017:
018: import java.util.Calendar;
019: import java.util.Date;
020:
021: /**
022: * Utility class for filter builder
023: *
024: * @since 2.4
025: * @author Mauricio Pazos (Axios Engineering)
026: * @author Gabriel Roldan (Axios Engineering)
027: * @version $Id: Util.java 28415 2007-12-18 09:54:31Z vmpazos $
028: * @source $URL:
029: * http://svn.geotools.org/geotools/trunk/gt/modules/library/cql/src/main/java/org/geotools/text/filter/Util.java $
030: */
031: final class Util {
032: private static final Calendar CALENDAR = Calendar.getInstance();
033: private static final int YEARS = 0;
034: private static final int MONTHS = 1;
035: private static final int DAYS = 2;
036:
037: /** Y,M,D */
038: private static int[] DURATION_DATE = new int[3];
039: private static final int HOURS = 0;
040: private static final int MINUTES = 1;
041: private static final int SECONDS = 2;
042:
043: /** H,M,S */
044: private static int[] DURATION_TIME = new int[3];
045:
046: private Util() {
047: // utility class
048: }
049:
050: /**
051: * Extract from duration string the values of years, month and days
052: *
053: * @param duration
054: * @return int[3] with years,months,days, if some value are not present -1
055: * will be returned.
056: */
057: private static int[] extractDurationDate(final String duration) {
058: // initializa duration date container
059: for (int i = 0; i < DURATION_DATE.length; i++) {
060: DURATION_DATE[i] = -1;
061: }
062:
063: // if has not duration date return array with -1 values
064: int cursor = duration.indexOf("P");
065:
066: if (cursor == -1) {
067: return DURATION_DATE;
068: }
069:
070: // extracts duration date and set duration array
071: cursor++;
072:
073: // years
074: int endYears = duration.indexOf("Y", cursor);
075:
076: if (endYears >= 0) {
077: String strYears = duration.substring(cursor, endYears);
078: int years = Integer.parseInt(strYears);
079: DURATION_DATE[YEARS] = years;
080:
081: cursor = endYears + 1;
082: }
083:
084: // months
085: int endMonths = duration.indexOf("M", cursor);
086:
087: if (endMonths >= 0) {
088: String strMonths = duration.substring(cursor, endMonths);
089: int months = Integer.parseInt(strMonths);
090: DURATION_DATE[MONTHS] = months;
091:
092: cursor = endMonths + 1;
093: }
094:
095: // days
096: int endDays = duration.indexOf("D", cursor);
097:
098: if (endDays >= 0) {
099: String strDays = duration.substring(cursor, endDays);
100: int days = Integer.parseInt(strDays);
101: DURATION_DATE[DAYS] = days;
102: }
103:
104: return DURATION_DATE;
105: }
106:
107: /**
108: * Extract from duration string the values of hours, minutes and seconds
109: *
110: * @param duration
111: * @return int[3] with hours, minutes and seconds if some value are not
112: * present -1 will be returned.
113: */
114: private static int[] extractDurationTime(final String duration) {
115: for (int i = 0; i < DURATION_TIME.length; i++) {
116: DURATION_TIME[i] = -1;
117: }
118:
119: int cursor = duration.indexOf("T");
120:
121: if (cursor == -1) {
122: return DURATION_TIME;
123: }
124:
125: cursor++;
126:
127: // hours
128: int endHours = duration.indexOf("H", cursor);
129:
130: if (endHours >= 0) {
131: String strHours = duration.substring(cursor, endHours);
132: int hours = Integer.parseInt(strHours);
133: DURATION_TIME[HOURS] = hours;
134:
135: cursor = endHours + 1;
136: }
137:
138: // minute
139: int endMinutes = duration.indexOf("M", cursor);
140:
141: if (endMinutes >= 0) {
142: String strMinutes = duration.substring(cursor, endMinutes);
143: int minutes = Integer.parseInt(strMinutes);
144: DURATION_TIME[MINUTES] = minutes;
145:
146: cursor = endMinutes + 1;
147: }
148:
149: // seconds
150: int endSeconds = duration.indexOf("S", cursor);
151:
152: if (endSeconds >= 0) {
153: String strSeconds = duration.substring(cursor, endSeconds);
154: int seconds = Integer.parseInt(strSeconds);
155: DURATION_TIME[SECONDS] = seconds;
156: }
157:
158: return DURATION_TIME;
159: }
160:
161: /**
162: * Add duration to date
163: *
164: * @param date
165: * a Date
166: * @param duration
167: * a String formated like "P##Y##M##D"
168: *
169: * @return a Date
170: *
171: */
172: public static Date addDurationToDate(final Date date,
173: final String duration) throws NumberFormatException {
174: final int positive = 1;
175:
176: Date computedDate = null;
177:
178: computedDate = computeDateFromDurationDate(date, duration,
179: positive);
180:
181: computedDate = computeDateFromDurationTime(computedDate,
182: duration, positive);
183:
184: return computedDate;
185: }
186:
187: /**
188: * Adds years, month and days (duration) to initial date.
189: *
190: * @param date
191: * initial date
192: * @param duration
193: * a String with format: PddYddMddD
194: * @return Date a computed date. if duration have not got duration "P"
195: * return date value.
196: *
197: */
198: private static Date computeDateFromDurationDate(final Date date,
199: final String duration, int sign) {
200: DURATION_DATE = extractDurationDate(duration);
201:
202: if (isNull(DURATION_DATE)) {
203: return date;
204: }
205:
206: CALENDAR.setTime(date);
207:
208: // years
209: if (DURATION_DATE[YEARS] >= 0) {
210: CALENDAR.add(Calendar.YEAR, sign * DURATION_DATE[YEARS]);
211: }
212:
213: // months
214: if (DURATION_DATE[MONTHS] >= 0) {
215: CALENDAR.add(Calendar.MONTH, sign * DURATION_DATE[MONTHS]);
216: }
217:
218: // days
219: if (DURATION_DATE[DAYS] >= 0) {
220: CALENDAR.add(Calendar.DATE, sign * DURATION_DATE[DAYS]);
221: }
222:
223: Date lastDate = CALENDAR.getTime();
224:
225: return lastDate;
226: }
227:
228: /**
229: * durDate is null if all his values are -1
230: *
231: * @param durDate
232: * @return true if has some greater than or equal 0
233: */
234: private static boolean isNull(int[] durDate) {
235: for (int i = 0; i < durDate.length; i++) {
236: if (durDate[i] >= 0) {
237: return false;
238: }
239: }
240:
241: return true;
242: }
243:
244: /**
245: * Add or subtract time duration to initial date.
246: *
247: * @param date
248: * initial date
249: * @param duration
250: * a String with format: TddHddMddS
251: * @param sign
252: * 1 or -1 (add or subract)
253: * @return Date a computed date. if duration have not got duration "T"
254: * return date value.
255: */
256: private static Date computeDateFromDurationTime(final Date date,
257: final String duration, final int sign) {
258: DURATION_TIME = extractDurationTime(duration);
259:
260: if (isNull(DURATION_TIME)) {
261: return date;
262: }
263:
264: CALENDAR.setTime(date);
265:
266: // hours
267: if (DURATION_TIME[HOURS] >= 0) {
268: CALENDAR.add(Calendar.HOUR, sign * DURATION_TIME[HOURS]);
269: }
270:
271: // minute
272: if (DURATION_TIME[MINUTES] >= 0) {
273: CALENDAR
274: .add(Calendar.MINUTE, sign * DURATION_TIME[MINUTES]);
275: }
276:
277: // seconds
278: if (DURATION_TIME[SECONDS] >= 0) {
279: CALENDAR
280: .add(Calendar.SECOND, sign * DURATION_TIME[SECONDS]);
281: }
282:
283: Date lastDate = CALENDAR.getTime();
284:
285: return lastDate;
286: }
287:
288: /**
289: * Subtracts duration to date
290: *
291: * @param date
292: * a Date
293: * @param duration
294: * a String formated like "P##Y##M##D"
295: *
296: * @return a Date
297: */
298: public static Date subtractDurationToDate(Date date, String duration) {
299: final int negative = -1;
300:
301: Date computedDate = null;
302:
303: computedDate = computeDateFromDurationDate(date, duration,
304: negative);
305:
306: computedDate = computeDateFromDurationTime(computedDate,
307: duration, negative);
308:
309: return computedDate;
310: }
311: }
|