1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.net.ftp.parser;
19
20 import java.text.DateFormatSymbols;
21 import java.text.ParseException;
22 import java.text.ParsePosition;
23 import java.text.SimpleDateFormat;
24 import java.util.Calendar;
25 import java.util.Date;
26 import java.util.TimeZone;
27
28 import org.apache.commons.net.ftp.Configurable;
29 import org.apache.commons.net.ftp.FTPClientConfig;
30
31
32
33
34
35
36
37
38
39 public class FTPTimestampParserImpl implements
40 FTPTimestampParser, Configurable
41 {
42
43
44 private SimpleDateFormat defaultDateFormat;
45 private SimpleDateFormat recentDateFormat;
46 private boolean lenientFutureDates = false;
47
48
49
50
51
52 public FTPTimestampParserImpl() {
53 setDefaultDateFormat(DEFAULT_SDF);
54 setRecentDateFormat(DEFAULT_RECENT_SDF);
55 }
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public Calendar parseTimestamp(String timestampStr) throws ParseException {
75 Calendar now = Calendar.getInstance();
76 return parseTimestamp(timestampStr, now);
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 public Calendar parseTimestamp(String timestampStr, Calendar serverTime) throws ParseException {
95 Calendar now = (Calendar) serverTime.clone();
96 now.setTimeZone(this.getServerTimeZone());
97 Calendar working = (Calendar) now.clone();
98 working.setTimeZone(getServerTimeZone());
99 ParsePosition pp = new ParsePosition(0);
100
101 Date parsed = null;
102 if (recentDateFormat != null) {
103 if (lenientFutureDates) {
104
105
106 now.add(Calendar.DATE, 1);
107 }
108 parsed = recentDateFormat.parse(timestampStr, pp);
109 }
110 if (parsed != null && pp.getIndex() == timestampStr.length())
111 {
112 working.setTime(parsed);
113 working.set(Calendar.YEAR, now.get(Calendar.YEAR));
114
115 if (working.after(now)) {
116 working.add(Calendar.YEAR, -1);
117 }
118 } else {
119
120
121
122
123
124 if (recentDateFormat != null) {
125 pp = new ParsePosition(0);
126 int year = now.get(Calendar.YEAR);
127 String timeStampStrPlusYear = timestampStr + " " + year;
128 SimpleDateFormat hackFormatter = new SimpleDateFormat(recentDateFormat.toPattern() + " yyyy",
129 recentDateFormat.getDateFormatSymbols());
130 hackFormatter.setLenient(false);
131 hackFormatter.setTimeZone(recentDateFormat.getTimeZone());
132 parsed = hackFormatter.parse(timeStampStrPlusYear, pp);
133 }
134 if (parsed != null && pp.getIndex() == timestampStr.length() + 5) {
135 working.setTime(parsed);
136 }
137 else {
138 pp = new ParsePosition(0);
139 parsed = defaultDateFormat.parse(timestampStr, pp);
140
141
142
143
144
145
146
147 if (parsed != null && pp.getIndex() == timestampStr.length()) {
148 working.setTime(parsed);
149 } else {
150 throw new ParseException(
151 "Timestamp could not be parsed with older or recent DateFormat",
152 pp.getIndex());
153 }
154 }
155 }
156 return working;
157 }
158
159
160
161
162 public SimpleDateFormat getDefaultDateFormat() {
163 return defaultDateFormat;
164 }
165
166
167
168 public String getDefaultDateFormatString() {
169 return defaultDateFormat.toPattern();
170 }
171
172
173
174 private void setDefaultDateFormat(String format) {
175 if (format != null) {
176 this.defaultDateFormat = new SimpleDateFormat(format);
177 this.defaultDateFormat.setLenient(false);
178 }
179 }
180
181
182
183 public SimpleDateFormat getRecentDateFormat() {
184 return recentDateFormat;
185 }
186
187
188
189 public String getRecentDateFormatString() {
190 return recentDateFormat.toPattern();
191 }
192
193
194
195 private void setRecentDateFormat(String format) {
196 if (format != null) {
197 this.recentDateFormat = new SimpleDateFormat(format);
198 this.recentDateFormat.setLenient(false);
199 }
200 }
201
202
203
204
205
206 public String[] getShortMonths() {
207 return defaultDateFormat.getDateFormatSymbols().getShortMonths();
208 }
209
210
211
212
213
214 public TimeZone getServerTimeZone() {
215 return this.defaultDateFormat.getTimeZone();
216 }
217
218
219
220
221
222
223 private void setServerTimeZone(String serverTimeZoneId) {
224 TimeZone serverTimeZone = TimeZone.getDefault();
225 if (serverTimeZoneId != null) {
226 serverTimeZone = TimeZone.getTimeZone(serverTimeZoneId);
227 }
228 this.defaultDateFormat.setTimeZone(serverTimeZone);
229 if (this.recentDateFormat != null) {
230 this.recentDateFormat.setTimeZone(serverTimeZone);
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 public void configure(FTPClientConfig config) {
257 DateFormatSymbols dfs = null;
258
259 String languageCode = config.getServerLanguageCode();
260 String shortmonths = config.getShortMonthNames();
261 if (shortmonths != null) {
262 dfs = FTPClientConfig.getDateFormatSymbols(shortmonths);
263 } else if (languageCode != null) {
264 dfs = FTPClientConfig.lookupDateFormatSymbols(languageCode);
265 } else {
266 dfs = FTPClientConfig.lookupDateFormatSymbols("en");
267 }
268
269
270 String recentFormatString = config.getRecentDateFormatStr();
271 if (recentFormatString == null) {
272 this.recentDateFormat = null;
273 } else {
274 this.recentDateFormat = new SimpleDateFormat(recentFormatString, dfs);
275 this.recentDateFormat.setLenient(false);
276 }
277
278 String defaultFormatString = config.getDefaultDateFormatStr();
279 if (defaultFormatString == null) {
280 throw new IllegalArgumentException("defaultFormatString cannot be null");
281 }
282 this.defaultDateFormat = new SimpleDateFormat(defaultFormatString, dfs);
283 this.defaultDateFormat.setLenient(false);
284
285 setServerTimeZone(config.getServerTimeZoneId());
286
287 this.lenientFutureDates = config.isLenientFutureDates();
288 }
289
290
291
292 boolean isLenientFutureDates() {
293 return lenientFutureDates;
294 }
295
296
297
298 void setLenientFutureDates(boolean lenientFutureDates) {
299 this.lenientFutureDates = lenientFutureDates;
300 }
301 }