1 | /*
|
---|
2 | * Copyright 2000-2004 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 |
|
---|
18 | package org.apache.tools.ant.taskdefs;
|
---|
19 |
|
---|
20 | import java.text.SimpleDateFormat;
|
---|
21 | import java.util.Calendar;
|
---|
22 | import java.util.Date;
|
---|
23 | import java.util.Enumeration;
|
---|
24 | import java.util.Hashtable;
|
---|
25 | import java.util.Locale;
|
---|
26 | import java.util.NoSuchElementException;
|
---|
27 | import java.util.StringTokenizer;
|
---|
28 | import java.util.TimeZone;
|
---|
29 | import java.util.Vector;
|
---|
30 | import org.apache.tools.ant.BuildException;
|
---|
31 | import org.apache.tools.ant.Location;
|
---|
32 | import org.apache.tools.ant.Project;
|
---|
33 | import org.apache.tools.ant.Task;
|
---|
34 | import org.apache.tools.ant.types.EnumeratedAttribute;
|
---|
35 |
|
---|
36 | /**
|
---|
37 | * Sets properties to the current time, or offsets from the current time.
|
---|
38 | * The default properties are TSTAMP, DSTAMP and TODAY;
|
---|
39 | *
|
---|
40 | * @since Ant 1.1
|
---|
41 | * @ant.task category="utility"
|
---|
42 | */
|
---|
43 | public class Tstamp extends Task {
|
---|
44 |
|
---|
45 | private Vector customFormats = new Vector();
|
---|
46 | private String prefix = "";
|
---|
47 |
|
---|
48 | /**
|
---|
49 | * Set a prefix for the properties. If the prefix does not end with a "."
|
---|
50 | * one is automatically added
|
---|
51 | * @since Ant 1.5
|
---|
52 | */
|
---|
53 | public void setPrefix(String prefix) {
|
---|
54 | this.prefix = prefix;
|
---|
55 | if (!this.prefix.endsWith(".")) {
|
---|
56 | this.prefix += ".";
|
---|
57 | }
|
---|
58 | }
|
---|
59 |
|
---|
60 | /**
|
---|
61 | * create the timestamps. Custom ones are done before
|
---|
62 | * the standard ones, to get their retaliation in early.
|
---|
63 | * @throws BuildException
|
---|
64 | */
|
---|
65 | public void execute() throws BuildException {
|
---|
66 | try {
|
---|
67 | Date d = new Date();
|
---|
68 |
|
---|
69 | Enumeration i = customFormats.elements();
|
---|
70 | while (i.hasMoreElements()) {
|
---|
71 | CustomFormat cts = (CustomFormat) i.nextElement();
|
---|
72 | cts.execute(getProject(), d, getLocation());
|
---|
73 | }
|
---|
74 |
|
---|
75 | SimpleDateFormat dstamp = new SimpleDateFormat ("yyyyMMdd");
|
---|
76 | setProperty("DSTAMP", dstamp.format(d));
|
---|
77 |
|
---|
78 | SimpleDateFormat tstamp = new SimpleDateFormat ("HHmm");
|
---|
79 | setProperty("TSTAMP", tstamp.format(d));
|
---|
80 |
|
---|
81 | SimpleDateFormat today
|
---|
82 | = new SimpleDateFormat ("MMMM d yyyy", Locale.US);
|
---|
83 | setProperty("TODAY", today.format(d));
|
---|
84 |
|
---|
85 | } catch (Exception e) {
|
---|
86 | throw new BuildException(e);
|
---|
87 | }
|
---|
88 | }
|
---|
89 |
|
---|
90 | /**
|
---|
91 | * create a custom format with the current prefix.
|
---|
92 | * @return a ready to fill-in format
|
---|
93 | */
|
---|
94 | public CustomFormat createFormat() {
|
---|
95 | CustomFormat cts = new CustomFormat();
|
---|
96 | customFormats.addElement(cts);
|
---|
97 | return cts;
|
---|
98 | }
|
---|
99 |
|
---|
100 | /**
|
---|
101 | * helper that encapsulates prefix logic and property setting
|
---|
102 | * policy (i.e. we use setNewProperty instead of setProperty).
|
---|
103 | */
|
---|
104 | private void setProperty(String name, String value) {
|
---|
105 | getProject().setNewProperty(prefix + name, value);
|
---|
106 | }
|
---|
107 |
|
---|
108 | /**
|
---|
109 | * This nested element that allows a property to be set
|
---|
110 | * to the current date and time in a given format.
|
---|
111 | * The date/time patterns are as defined in the
|
---|
112 | * Java SimpleDateFormat class.
|
---|
113 | * The format element also allows offsets to be applied to
|
---|
114 | * the time to generate different time values.
|
---|
115 | * @todo consider refactoring out into a re-usable element.
|
---|
116 | */
|
---|
117 | public class CustomFormat {
|
---|
118 | private TimeZone timeZone;
|
---|
119 | private String propertyName;
|
---|
120 | private String pattern;
|
---|
121 | private String language;
|
---|
122 | private String country;
|
---|
123 | private String variant;
|
---|
124 | private int offset = 0;
|
---|
125 | private int field = Calendar.DATE;
|
---|
126 |
|
---|
127 | /**
|
---|
128 | * Create a format
|
---|
129 | */
|
---|
130 | public CustomFormat() {
|
---|
131 | }
|
---|
132 |
|
---|
133 | /**
|
---|
134 | * The property to receive the date/time string in the given pattern
|
---|
135 | * @param propertyName
|
---|
136 | */
|
---|
137 | public void setProperty(String propertyName) {
|
---|
138 | this.propertyName = propertyName;
|
---|
139 | }
|
---|
140 |
|
---|
141 | /**
|
---|
142 | * The date/time pattern to be used. The values are as
|
---|
143 | * defined by the Java SimpleDateFormat class.
|
---|
144 | * @param pattern
|
---|
145 | * @see java.text.SimpleDateFormat
|
---|
146 | */
|
---|
147 | public void setPattern(String pattern) {
|
---|
148 | this.pattern = pattern;
|
---|
149 | }
|
---|
150 |
|
---|
151 | /**
|
---|
152 | * The locale used to create date/time string.
|
---|
153 | * The general form is "language, country, variant" but
|
---|
154 | * either variant or variant and country may be omitted.
|
---|
155 | * For more information please refer to documentation
|
---|
156 | * for the java.util.Locale class.
|
---|
157 | * @param locale
|
---|
158 | * @see java.util.Locale
|
---|
159 | */
|
---|
160 | public void setLocale(String locale) {
|
---|
161 | StringTokenizer st = new StringTokenizer(locale, " \t\n\r\f,");
|
---|
162 | try {
|
---|
163 | language = st.nextToken();
|
---|
164 | if (st.hasMoreElements()) {
|
---|
165 | country = st.nextToken();
|
---|
166 | if (st.hasMoreElements()) {
|
---|
167 | variant = st.nextToken();
|
---|
168 | if (st.hasMoreElements()) {
|
---|
169 | throw new BuildException("bad locale format",
|
---|
170 | getLocation());
|
---|
171 | }
|
---|
172 | }
|
---|
173 | } else {
|
---|
174 | country = "";
|
---|
175 | }
|
---|
176 | } catch (NoSuchElementException e) {
|
---|
177 | throw new BuildException("bad locale format", e,
|
---|
178 | getLocation());
|
---|
179 | }
|
---|
180 | }
|
---|
181 |
|
---|
182 | /**
|
---|
183 | * The timezone to use for displaying time.
|
---|
184 | * The values are as defined by the Java TimeZone class.
|
---|
185 | * @param id
|
---|
186 | * @see java.util.TimeZone
|
---|
187 | */
|
---|
188 | public void setTimezone(String id) {
|
---|
189 | timeZone = TimeZone.getTimeZone(id);
|
---|
190 | }
|
---|
191 |
|
---|
192 | /**
|
---|
193 | * The numeric offset to the current time.
|
---|
194 | * @param offset
|
---|
195 | */
|
---|
196 | public void setOffset(int offset) {
|
---|
197 | this.offset = offset;
|
---|
198 | }
|
---|
199 |
|
---|
200 | /**
|
---|
201 | * @deprecated setUnit(String) is deprecated and is replaced with
|
---|
202 | * setUnit(Tstamp.Unit) to make Ant's
|
---|
203 | * Introspection mechanism do the work and also to
|
---|
204 | * encapsulate operations on the unit in its own
|
---|
205 | * class.
|
---|
206 | */
|
---|
207 | public void setUnit(String unit) {
|
---|
208 | log("DEPRECATED - The setUnit(String) method has been deprecated."
|
---|
209 | + " Use setUnit(Tstamp.Unit) instead.");
|
---|
210 | Unit u = new Unit();
|
---|
211 | u.setValue(unit);
|
---|
212 | field = u.getCalendarField();
|
---|
213 | }
|
---|
214 |
|
---|
215 | /**
|
---|
216 | * The unit of the offset to be applied to the current time.
|
---|
217 | * Valid Values are
|
---|
218 | * <ul>
|
---|
219 | * <li>millisecond</li>
|
---|
220 | * <li>second</li>
|
---|
221 | * <li>minute</li>
|
---|
222 | * <li>hour</li>
|
---|
223 | * <li>day</li>
|
---|
224 | * <li>week</li>
|
---|
225 | * <li>month</li>
|
---|
226 | * <li>year</li>
|
---|
227 | * </ul>
|
---|
228 | * The default unit is day.
|
---|
229 | * @param unit
|
---|
230 | */
|
---|
231 | public void setUnit(Unit unit) {
|
---|
232 | field = unit.getCalendarField();
|
---|
233 | }
|
---|
234 |
|
---|
235 | /**
|
---|
236 | * validate parameter and execute the format
|
---|
237 | * @param project project to set property in
|
---|
238 | * @param date date to use as a starting point
|
---|
239 | * @param location line in file (for errors)
|
---|
240 | */
|
---|
241 | public void execute(Project project, Date date, Location location) {
|
---|
242 | if (propertyName == null) {
|
---|
243 | throw new BuildException("property attribute must be provided",
|
---|
244 | location);
|
---|
245 | }
|
---|
246 |
|
---|
247 | if (pattern == null) {
|
---|
248 | throw new BuildException("pattern attribute must be provided",
|
---|
249 | location);
|
---|
250 | }
|
---|
251 |
|
---|
252 | SimpleDateFormat sdf;
|
---|
253 | if (language == null) {
|
---|
254 | sdf = new SimpleDateFormat(pattern);
|
---|
255 | } else if (variant == null) {
|
---|
256 | sdf = new SimpleDateFormat(pattern,
|
---|
257 | new Locale(language, country));
|
---|
258 | } else {
|
---|
259 | sdf = new SimpleDateFormat(pattern,
|
---|
260 | new Locale(language, country,
|
---|
261 | variant));
|
---|
262 | }
|
---|
263 | if (offset != 0) {
|
---|
264 | Calendar calendar = Calendar.getInstance();
|
---|
265 | calendar.setTime(date);
|
---|
266 | calendar.add(field, offset);
|
---|
267 | date = calendar.getTime();
|
---|
268 | }
|
---|
269 | if (timeZone != null) {
|
---|
270 | sdf.setTimeZone(timeZone);
|
---|
271 | }
|
---|
272 | Tstamp.this.setProperty(propertyName, sdf.format(date));
|
---|
273 | }
|
---|
274 | }
|
---|
275 |
|
---|
276 | /**
|
---|
277 | * set of valid units to use for time offsets.
|
---|
278 | */
|
---|
279 | public static class Unit extends EnumeratedAttribute {
|
---|
280 |
|
---|
281 | private static final String MILLISECOND = "millisecond";
|
---|
282 | private static final String SECOND = "second";
|
---|
283 | private static final String MINUTE = "minute";
|
---|
284 | private static final String HOUR = "hour";
|
---|
285 | private static final String DAY = "day";
|
---|
286 | private static final String WEEK = "week";
|
---|
287 | private static final String MONTH = "month";
|
---|
288 | private static final String YEAR = "year";
|
---|
289 |
|
---|
290 | private static final String[] units = {
|
---|
291 | MILLISECOND,
|
---|
292 | SECOND,
|
---|
293 | MINUTE,
|
---|
294 | HOUR,
|
---|
295 | DAY,
|
---|
296 | WEEK,
|
---|
297 | MONTH,
|
---|
298 | YEAR
|
---|
299 | };
|
---|
300 |
|
---|
301 | private Hashtable calendarFields = new Hashtable();
|
---|
302 |
|
---|
303 | public Unit() {
|
---|
304 | calendarFields.put(MILLISECOND,
|
---|
305 | new Integer(Calendar.MILLISECOND));
|
---|
306 | calendarFields.put(SECOND, new Integer(Calendar.SECOND));
|
---|
307 | calendarFields.put(MINUTE, new Integer(Calendar.MINUTE));
|
---|
308 | calendarFields.put(HOUR, new Integer(Calendar.HOUR_OF_DAY));
|
---|
309 | calendarFields.put(DAY, new Integer(Calendar.DATE));
|
---|
310 | calendarFields.put(WEEK, new Integer(Calendar.WEEK_OF_YEAR));
|
---|
311 | calendarFields.put(MONTH, new Integer(Calendar.MONTH));
|
---|
312 | calendarFields.put(YEAR, new Integer(Calendar.YEAR));
|
---|
313 | }
|
---|
314 |
|
---|
315 | public int getCalendarField() {
|
---|
316 | String key = getValue().toLowerCase();
|
---|
317 | Integer i = (Integer) calendarFields.get(key);
|
---|
318 | return i.intValue();
|
---|
319 | }
|
---|
320 |
|
---|
321 | public String[] getValues() {
|
---|
322 | return units;
|
---|
323 | }
|
---|
324 | }
|
---|
325 | }
|
---|