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