001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.tools.ant.types.selectors;
020:
021: import java.io.File;
022: import java.text.DateFormat;
023: import java.text.SimpleDateFormat;
024: import java.text.ParseException;
025: import java.util.Locale;
026:
027: import org.apache.tools.ant.Project;
028: import org.apache.tools.ant.types.Parameter;
029: import org.apache.tools.ant.types.TimeComparison;
030: import org.apache.tools.ant.util.FileUtils;
031:
032: /**
033: * Selector that chooses files based on their last modified date.
034: *
035: * @since 1.5
036: */
037: public class DateSelector extends BaseExtendSelector {
038:
039: /** Utilities used for file operations */
040: private static final FileUtils FILE_UTILS = FileUtils
041: .getFileUtils();
042:
043: private long millis = -1;
044: private String dateTime = null;
045: private boolean includeDirs = false;
046: private long granularity = 0;
047: private String pattern;
048: private TimeComparison when = TimeComparison.EQUAL;
049:
050: /** Key to used for parameterized custom selector */
051: public static final String MILLIS_KEY = "millis";
052: /** Key to used for parameterized custom selector */
053: public static final String DATETIME_KEY = "datetime";
054: /** Key to used for parameterized custom selector */
055: public static final String CHECKDIRS_KEY = "checkdirs";
056: /** Key to used for parameterized custom selector */
057: public static final String GRANULARITY_KEY = "granularity";
058: /** Key to used for parameterized custom selector */
059: public static final String WHEN_KEY = "when";
060: /** Key to used for parameterized custom selector */
061: public static final String PATTERN_KEY = "pattern";
062:
063: /**
064: * Creates a new <code>DateSelector</code> instance.
065: *
066: */
067: public DateSelector() {
068: granularity = FILE_UTILS.getFileTimestampGranularity();
069: }
070:
071: /**
072: * @return a string describing this object
073: */
074: public String toString() {
075: StringBuffer buf = new StringBuffer("{dateselector date: ");
076: buf.append(dateTime);
077: buf.append(" compare: ").append(when.getValue());
078: buf.append(" granularity: ");
079: buf.append(granularity);
080: if (pattern != null) {
081: buf.append(" pattern: ").append(pattern);
082: }
083: buf.append("}");
084: return buf.toString();
085: }
086:
087: /**
088: * Set the time; for users who prefer to express time in ms since 1970.
089: *
090: * @param millis the time to compare file's last modified date to,
091: * expressed in milliseconds.
092: */
093: public void setMillis(long millis) {
094: this .millis = millis;
095: }
096:
097: /**
098: * Returns the millisecond value the selector is set for.
099: * @return the millisecond value.
100: */
101: public long getMillis() {
102: if (dateTime != null) {
103: validate();
104: }
105: return millis;
106: }
107:
108: /**
109: * Sets the date. The user must supply it in MM/DD/YYYY HH:MM AM_PM format,
110: * unless an alternate pattern is specified via the pattern attribute.
111: *
112: * @param dateTime a formatted date <code>String</code>.
113: */
114: public void setDatetime(String dateTime) {
115: this .dateTime = dateTime;
116: millis = -1;
117: }
118:
119: /**
120: * Set whether to check dates on directories.
121: *
122: * @param includeDirs whether to check the timestamp on directories.
123: */
124: public void setCheckdirs(boolean includeDirs) {
125: this .includeDirs = includeDirs;
126: }
127:
128: /**
129: * Sets the number of milliseconds leeway we will give before we consider
130: * a file not to have matched a date.
131: * @param granularity the number of milliseconds leeway.
132: */
133: public void setGranularity(int granularity) {
134: this .granularity = granularity;
135: }
136:
137: /**
138: * Sets the type of comparison to be done on the file's last modified
139: * date.
140: *
141: * @param tcmp The comparison to perform, an EnumeratedAttribute.
142: */
143: public void setWhen(TimeComparisons tcmp) {
144: setWhen((TimeComparison) tcmp);
145: }
146:
147: /**
148: * Set the comparison type.
149: * @param t TimeComparison object.
150: */
151: public void setWhen(TimeComparison t) {
152: when = t;
153: }
154:
155: /**
156: * Sets the pattern to be used for the SimpleDateFormat.
157: *
158: * @param pattern the pattern that defines the date format.
159: */
160: public void setPattern(String pattern) {
161: this .pattern = pattern;
162: }
163:
164: /**
165: * When using this as a custom selector, this method will be called.
166: * It translates each parameter into the appropriate setXXX() call.
167: *
168: * @param parameters the complete set of parameters for this selector.
169: */
170: public void setParameters(Parameter[] parameters) {
171: super .setParameters(parameters);
172: if (parameters != null) {
173: for (int i = 0; i < parameters.length; i++) {
174: String paramname = parameters[i].getName();
175: if (MILLIS_KEY.equalsIgnoreCase(paramname)) {
176: try {
177: setMillis(new Long(parameters[i].getValue())
178: .longValue());
179: } catch (NumberFormatException nfe) {
180: setError("Invalid millisecond setting "
181: + parameters[i].getValue());
182: }
183: } else if (DATETIME_KEY.equalsIgnoreCase(paramname)) {
184: setDatetime(parameters[i].getValue());
185: } else if (CHECKDIRS_KEY.equalsIgnoreCase(paramname)) {
186: setCheckdirs(Project.toBoolean(parameters[i]
187: .getValue()));
188: } else if (GRANULARITY_KEY.equalsIgnoreCase(paramname)) {
189: try {
190: setGranularity(new Integer(parameters[i]
191: .getValue()).intValue());
192: } catch (NumberFormatException nfe) {
193: setError("Invalid granularity setting "
194: + parameters[i].getValue());
195: }
196: } else if (WHEN_KEY.equalsIgnoreCase(paramname)) {
197: setWhen(new TimeComparison(parameters[i].getValue()));
198: } else if (PATTERN_KEY.equalsIgnoreCase(paramname)) {
199: setPattern(parameters[i].getValue());
200: } else {
201: setError("Invalid parameter " + paramname);
202: }
203: }
204: }
205: }
206:
207: /**
208: * This is a consistency check to ensure the selector's required
209: * values have been set.
210: */
211: public void verifySettings() {
212: if (dateTime == null && millis < 0) {
213: setError("You must provide a datetime or the number of "
214: + "milliseconds.");
215: } else if (millis < 0 && dateTime != null) {
216: // check millis and only set it once.
217: DateFormat df = ((pattern == null) ? DateFormat
218: .getDateTimeInstance(DateFormat.SHORT,
219: DateFormat.SHORT, Locale.US)
220: : new SimpleDateFormat(pattern));
221:
222: try {
223: setMillis(df.parse(dateTime).getTime());
224: if (millis < 0) {
225: setError("Date of "
226: + dateTime
227: + " results in negative milliseconds value"
228: + " relative to epoch (January 1, 1970, 00:00:00 GMT).");
229: }
230: } catch (ParseException pe) {
231: setError("Date of "
232: + dateTime
233: + " Cannot be parsed correctly. It should be in"
234: + ((pattern == null) ? " MM/DD/YYYY HH:MM AM_PM"
235: : pattern) + " format.");
236: }
237: }
238: }
239:
240: /**
241: * The heart of the matter. This is where the selector gets to decide
242: * on the inclusion of a file in a particular fileset.
243: *
244: * @param basedir the base directory from which the scan is being performed.
245: * @param filename is the name of the file to check.
246: * @param file is a java.io.File object the selector can use.
247: * @return whether the file is selected.
248: */
249: public boolean isSelected(File basedir, String filename, File file) {
250:
251: validate();
252:
253: return (file.isDirectory() && !includeDirs)
254: || when.evaluate(file.lastModified(), millis,
255: granularity);
256: }
257:
258: /**
259: * Enumerated attribute with the values for time comparison.
260: * <p>
261: */
262: public static class TimeComparisons extends TimeComparison {
263: }
264:
265: }
|