KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > net > ftp > FTPClientConfig


1 /*
2  * Copyright 2005 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 package org.apache.commons.net.ftp;
17
18 import java.text.DateFormatSymbols JavaDoc;
19 import java.util.Collection JavaDoc;
20 import java.util.Locale JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.StringTokenizer JavaDoc;
23 import java.util.TreeMap JavaDoc;
24
25 /**
26  * <p>
27  * This class implements an alternate means of configuring the
28  * {@link org.apache.commons.net.ftp.FTPClient FTPClient} object and
29  * also subordinate objects which it uses. Any class implementing the
30  * {@link org.apache.commons.net.ftp.Configurable Configurable }
31  * interface can be configured by this object.
32  * </p><p>
33  * In particular this class was designed primarily to support configuration
34  * of FTP servers which express file timestamps in formats and languages
35  * other than those for the US locale, which although it is the most common
36  * is not universal. Unfortunately, nothing in the FTP spec allows this to
37  * be determined in an automated way, so manual configuration such as this
38  * is necessary.
39  * </p><p>
40  * This functionality was designed to allow existing clients to work exactly
41  * as before without requiring use of this component. This component should
42  * only need to be explicitly invoked by the user of this package for problem
43  * cases that previous implementations could not solve.
44  * </p>
45  * <h3>Examples of use of FTPClientConfig</h3>
46  * Use cases:
47  * You are trying to access a server that
48  * <ul>
49  * <li>lists files with timestamps that use month names in languages other
50  * than English</li>
51  * <li>lists files with timestamps that use date formats other
52  * than the American English "standard" <code>MM dd yyyy</code></li>
53  * <li>is in different timezone and you need accurate timestamps for
54  * dependency checking as in Ant</li>
55  * </ul>
56  * <p>
57  * Unpaged (whole list) access on a UNIX server that uses French month names
58  * but uses the "standard" <code>MMM d yyyy</code> date formatting
59  * <pre>
60  * FTPClient f=FTPClient();
61  * FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
62  * conf.setServerLanguageCode("fr");
63  * f.configure(conf);
64  * f.connect(server);
65  * f.login(username, password);
66  * FTPFile[] files = listFiles(directory);
67  * </pre>
68  * </p>
69  * <p>
70  * Paged access on a UNIX server that uses Danish month names
71  * and "European" date formatting in Denmark's time zone, when you
72  * are in some other time zone.
73  * <pre>
74  * FTPClient f=FTPClient();
75  * FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
76  * conf.setServerLanguageCode("da");
77  * conf.setDefaultDateFormat("d MMM yyyy");
78  * conf.setRecentDateFormat("d MMM HH:mm");
79  * conf.setTimeZoneId("Europe/Copenhagen");
80  * f.configure(conf);
81  * f.connect(server);
82  * f.login(username, password);
83  * FTPListParseEngine engine =
84  * f.initiateListParsing("com.whatever.YourOwnParser", directory);
85  *
86  * while (engine.hasNext()) {
87  * FTPFile[] files = engine.getNext(25); // "page size" you want
88  * //do whatever you want with these files, display them, etc.
89  * //expensive FTPFile objects not created until needed.
90  * }
91  * </pre>
92  * </p>
93  * <p>
94  * Unpaged (whole list) access on a VMS server that uses month names
95  * in a language not {@link #getSupportedLanguageCodes() supported} by the system.
96  * but uses the "standard" <code>MMM d yyyy</code> date formatting
97  * <pre>
98  * FTPClient f=FTPClient();
99  * FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_VMS);
100  * conf.setShortMonthNames(
101  * "jan|feb|mar|apr|ma|jn|jl|g|sep|okt|nv|des");
102  * f.configure(conf);
103  * f.connect(server);
104  * f.login(username, password);
105  * FTPFile[] files = listFiles(directory);
106  * </pre>
107  * </p>
108  * <p>
109  * Unpaged (whole list) access on a Windows-NT server in a different time zone.
110  * (Note, since the NT Format uses numeric date formatting, language issues
111  * are irrelevant here).
112  * <pre>
113  * FTPClient f=FTPClient();
114  * FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
115  * conf.setTimeZoneId("America/Denver");
116  * f.configure(conf);
117  * f.connect(server);
118  * f.login(username, password);
119  * FTPFile[] files = listFiles(directory);
120  * </pre>
121  * </p>
122  * Unpaged (whole list) access on a Windows-NT server in a different time zone
123  * but which has been configured to use a unix-style listing format.
124  * <pre>
125  * FTPClient f=FTPClient();
126  * FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
127  * conf.setTimeZoneId("America/Denver");
128  * f.configure(conf);
129  * f.connect(server);
130  * f.login(username, password);
131  * FTPFile[] files = listFiles(directory);
132  * </pre>
133  * </p>
134  * @since 1.4
135  * @see org.apache.commons.net.ftp.Configurable
136  * @see org.apache.commons.net.ftp.FTPClient
137  * @see org.apache.commons.net.ftp.parser.FTPTimestampParserImpl#configure(FTPClientConfig)
138  * @see org.apache.commons.net.ftp.parser.ConfigurableFTPFileEntryParserImpl
139  */

140 public class FTPClientConfig
141 {
142     
143     /**
144      * Identifier by which a unix-based ftp server is known throughout
145      * the commons-net ftp system.
146      */

147     public static final String JavaDoc SYST_UNIX = "UNIX";
148
149     /**
150      * Identifier by which a vms-based ftp server is known throughout
151      * the commons-net ftp system.
152      */

153     public static final String JavaDoc SYST_VMS = "VMS";
154     
155     /**
156      * Identifier by which a WindowsNT-based ftp server is known throughout
157      * the commons-net ftp system.
158      */

159     public static final String JavaDoc SYST_NT = "WINDOWS";
160
161     /**
162      * Identifier by which an OS/2-based ftp server is known throughout
163      * the commons-net ftp system.
164      */

165     public static final String JavaDoc SYST_OS2 = "OS/2";
166
167     /**
168      * Identifier by which an OS/400-based ftp server is known throughout
169      * the commons-net ftp system.
170      */

171     public static final String JavaDoc SYST_OS400 = "OS/400";
172     
173     /**
174      * Identifier by which an MVS-based ftp server is known throughout
175      * the commons-net ftp system.
176      */

177     public static final String JavaDoc SYST_MVS = "MVS";
178     
179     private final String JavaDoc serverSystemKey;
180     private String JavaDoc defaultDateFormatStr = null;
181     private String JavaDoc recentDateFormatStr = null;
182     private String JavaDoc serverLanguageCode = null;
183     private String JavaDoc shortMonthNames = null;
184     private String JavaDoc serverTimeZoneId = null;
185     
186     
187     /**
188      * The main constructor for an FTPClientConfig object
189      * @param systemKey key representing system type of the server being
190      * connected to. See {@link #getServerSystemKey() serverSystemKey}
191      */

192     public FTPClientConfig(String JavaDoc systemKey) {
193         this.serverSystemKey = systemKey;
194     }
195
196     /**
197      * Convenience constructor mainly for use in testing.
198      * Constructs a UNIX configuration.
199      */

200     public FTPClientConfig() {
201         this(SYST_UNIX);
202     }
203
204     /**
205      * Constructor which allows setting of all member fields
206      * @param systemKey key representing system type of the server being
207      * connected to. See
208      * {@link #getServerSystemKey() serverSystemKey}
209      * @param defaultDateFormatStr See
210      * {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
211      * @param recentDateFormatStr See
212      * {@link #setRecentDateFormatStr(String) recentDateFormatStr}
213      * @param serverLanguageCode See
214      * {@link #setServerLanguageCode(String) serverLanguageCode}
215      * @param shortMonthNames See
216      * {@link #setShortMonthNames(String) shortMonthNames}
217      * @param serverTimeZoneId See
218      * {@link #setServerTimeZoneId(String) serverTimeZoneId}
219      */

220     public FTPClientConfig(String JavaDoc systemKey,
221                            String JavaDoc defaultDateFormatStr,
222                            String JavaDoc recentDateFormatStr,
223                            String JavaDoc serverLanguageCode,
224                            String JavaDoc shortMonthNames,
225                            String JavaDoc serverTimeZoneId)
226     {
227         this(systemKey);
228         this.defaultDateFormatStr = defaultDateFormatStr;
229         this.recentDateFormatStr = recentDateFormatStr;
230         this.serverLanguageCode = serverLanguageCode;
231         this.shortMonthNames = shortMonthNames;
232         this.serverTimeZoneId = serverTimeZoneId;
233     }
234     
235     private static Map JavaDoc LANGUAGE_CODE_MAP = new TreeMap JavaDoc();
236     static {
237         
238         // if there are other commonly used month name encodings which
239
// correspond to particular locales, please add them here.
240

241         
242         
243         // many locales code short names for months as all three letters
244
// these we handle simply.
245
LANGUAGE_CODE_MAP.put("en", Locale.ENGLISH);
246         LANGUAGE_CODE_MAP.put("de",Locale.GERMAN);
247         LANGUAGE_CODE_MAP.put("it",Locale.ITALIAN);
248         LANGUAGE_CODE_MAP.put("es", new Locale JavaDoc("es", "", "")); // spanish
249
LANGUAGE_CODE_MAP.put("pt", new Locale JavaDoc("pt", "", "")); // portuguese
250
LANGUAGE_CODE_MAP.put("da", new Locale JavaDoc("da", "", "")); // danish
251
LANGUAGE_CODE_MAP.put("sv", new Locale JavaDoc("sv", "", "")); // swedish
252
LANGUAGE_CODE_MAP.put("no", new Locale JavaDoc("no", "", "")); // norwegian
253
LANGUAGE_CODE_MAP.put("nl", new Locale JavaDoc("nl", "", "")); // dutch
254
LANGUAGE_CODE_MAP.put("ro", new Locale JavaDoc("ro", "", "")); // romanian
255
LANGUAGE_CODE_MAP.put("sq", new Locale JavaDoc("sq", "", "")); // albanian
256
LANGUAGE_CODE_MAP.put("sh", new Locale JavaDoc("sh", "", "")); // serbo-croatian
257
LANGUAGE_CODE_MAP.put("sk", new Locale JavaDoc("sk", "", "")); // slovak
258
LANGUAGE_CODE_MAP.put("sl", new Locale JavaDoc("sl", "", "")); // slovenian
259

260
261         // some don't
262
LANGUAGE_CODE_MAP.put("fr",
263                 "jan|f\u00e9v|mar|avr|mai|jun|jui|ao\u00fb|sep|oct|nov|d\u00e9c"); //french
264

265     }
266     
267     /**
268      * Getter for the serverSystemKey property. This property
269      * specifies the general type of server to which the client connects.
270      * Should be either one of the <code>FTPClientConfig.SYST_*</code> codes
271      * or else the fully qualified class name of a parser implementing both
272      * the <code>FTPFileEntryParser</code> and <code>Configurable</code>
273      * interfaces.
274      * @return Returns the serverSystemKey property.
275      */

276     public String JavaDoc getServerSystemKey() {
277         return serverSystemKey;
278     }
279     
280     /**
281      * getter for the {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
282      * property.
283      * @return Returns the defaultDateFormatStr property.
284      */

285     public String JavaDoc getDefaultDateFormatStr() {
286         return defaultDateFormatStr;
287     }
288     
289     /**
290      * getter for the {@link #setRecentDateFormatStr(String) recentDateFormatStr} property.
291      * @return Returns the recentDateFormatStr property.
292      */

293
294     public String JavaDoc getRecentDateFormatStr() {
295         return recentDateFormatStr;
296     }
297     
298     /**
299      * getter for the {@link #setServerTimeZoneId(String) serverTimeZoneId} property.
300      * @return Returns the serverTimeZoneId property.
301      */

302     public String JavaDoc getServerTimeZoneId() {
303         return serverTimeZoneId;
304     }
305     
306     /**
307      * <p>
308      * getter for the {@link #setShortMonthNames(String) shortMonthNames}
309      * property.
310      * </p>
311      * @return Returns the shortMonthNames.
312      */

313     public String JavaDoc getShortMonthNames() {
314         return shortMonthNames;
315     }
316     
317     /**
318      * <p>
319      * getter for the {@link #setServerLanguageCode(String) serverLanguageCode} property.
320      * </p>
321 * * @return Returns the serverLanguageCode property.
322      */

323     public String JavaDoc getServerLanguageCode() {
324         return serverLanguageCode;
325     }
326     
327     /**
328      * <p>
329      * setter for the defaultDateFormatStr property. This property
330      * specifies the main date format that will be used by a parser configured
331      * by this configuration to parse file timestamps. If this is not
332      * specified, such a parser will use as a default value, the most commonly
333      * used format which will be in as used in <code>en_US</code> locales.
334      * </p><p>
335      * This should be in the format described for
336      * <code>java.text.SimpleDateFormat</code>.
337      * property.
338      * </p>
339      * @param defaultDateFormatStr The defaultDateFormatStr to set.
340      */

341     public void setDefaultDateFormatStr(String JavaDoc defaultDateFormatStr) {
342         this.defaultDateFormatStr = defaultDateFormatStr;
343     }
344     
345     /**
346      * <p>
347      * setter for the recentDateFormatStr property. This property
348      * specifies a secondary date format that will be used by a parser
349      * configured by this configuration to parse file timestamps, typically
350      * those less than a year old. If this is not specified, such a parser
351      * will not attempt to parse using an alternate format.
352      * </p>
353      * This is used primarily in unix-based systems.
354      * </p>
355      * This should be in the format described for
356      * <code>java.text.SimpleDateFormat</code>.
357      * </p>
358      * @param recentDateFormatStr The recentDateFormatStr to set.
359      */

360     public void setRecentDateFormatStr(String JavaDoc recentDateFormatStr) {
361         this.recentDateFormatStr = recentDateFormatStr;
362     }
363     
364     /**
365      * <p>
366      * setter for the serverTimeZoneId property. This property
367      * allows a time zone to be specified corresponding to that known to be
368      * used by an FTP server in file listings. This might be particularly
369      * useful to clients such as Ant that try to use these timestamps for
370      * dependency checking.
371      * </p><p>
372      * This should be one of the identifiers used by
373      * <code>java.util.TimeZone</code> to refer to time zones, for example,
374      * <code>America/Chicago</code> or <code>Asia/Rangoon</code>.
375      * </p>
376      * @param serverTimeZoneId The serverTimeZoneId to set.
377      */

378     public void setServerTimeZoneId(String JavaDoc serverTimeZoneId) {
379         this.serverTimeZoneId = serverTimeZoneId;
380     }
381     
382     /**
383      * <p>
384      * setter for the shortMonthNames property.
385      * This property allows the user to specify a set of month names
386      * used by the server that is different from those that may be
387      * specified using the {@link #setServerLanguageCode(String) serverLanguageCode}
388      * property.
389      * </p><p>
390      * This should be a string containing twelve strings each composed of
391      * three characters, delimited by pipe (|) characters. Currently,
392      * only 8-bit ASCII characters are known to be supported. For example,
393      * a set of month names used by a hypothetical Icelandic FTP server might
394      * conceivably be specified as
395      * <code>"jan|feb|mar|apr|ma&#xED;|j&#xFA;n|j&#xFA;l|&#xE1;g&#xFA;|sep|okt|n&#xF3;v|des"</code>.
396      * </p>
397      * @param shortMonthNames The value to set to the shortMonthNames property.
398      */

399     public void setShortMonthNames(String JavaDoc shortMonthNames) {
400         this.shortMonthNames = shortMonthNames;
401     }
402     
403     /**
404      * <p>
405      * setter for the serverLanguageCode property. This property allows
406      * user to specify a
407      * <a HREF="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">
408      * two-letter ISO-639 language code</a> that will be used to
409      * configure the set of month names used by the file timestamp parser.
410      * If neither this nor the {@link #setShortMonthNames(String) shortMonthNames}
411      * is specified, parsing will assume English month names, which may or
412      * may not be significant, depending on whether the date format(s)
413      * specified via {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
414      * and/or {@link #setRecentDateFormatStr(String) recentDateFormatStr} are using
415      * numeric or alphabetic month names.
416      * </p>
417      * <p>If the code supplied is not supported here, <code>en_US</code>
418      * month names will be used. We are supporting here those language
419      * codes which, when a <code> java.util.Locale</code> is constucted
420      * using it, and a <code>java.text.SimpleDateFormat</code> is
421      * constructed using that Locale, the array returned by the
422      * SimpleDateFormat's <code>getShortMonths()</code> method consists
423      * solely of three 8-bit ASCII character strings. Additionally,
424      * languages which do not meet this requirement are included if a
425      * common alternative set of short month names is known to be used.
426      * This means that users who can tell us of additional such encodings
427      * may get them added to the list of supported languages by contacting
428      * the jakarta-commons-net team.
429      * </p>
430      * <p><strong>
431      * Please note that this attribute will NOT be used to determine a
432      * locale-based date format for the language. </strong>
433      * Experience has shown that many if not most FTP servers outside the
434      * United States employ the standard <code>en_US</code> date format
435      * orderings of <code>MMM d yyyy</code> and <code>MMM d HH:mm</code>
436      * and attempting to deduce this automatically here would cause more
437      * problems than it would solve. The date format must be changed
438      * via the {@link #setDefaultDateFormatStr(String) defaultDateFormatStr} and/or
439      * {@link #setRecentDateFormatStr(String) recentDateFormatStr} parameters.
440      * </p>
441      * @param serverLanguageCode The value to set to the serverLanguageCode property.
442      */

443     public void setServerLanguageCode(String JavaDoc serverLanguageCode) {
444         this.serverLanguageCode = serverLanguageCode;
445     }
446     
447     /**
448      * Looks up the supplied language code in the internally maintained table of
449      * language codes. Returns a DateFormatSymbols object configured with
450      * short month names corresponding to the code. If there is no corresponding
451      * entry in the table, the object returned will be that for
452      * <code>Locale.US</code>
453      * @param languageCode See {@link #setServerLanguageCode(String) serverLanguageCode}
454      * @return a DateFormatSymbols object configured with short month names
455      * corresponding to the supplied code, or with month names for
456      * <code>Locale.US</code> if there is no corresponding entry in the internal
457      * table.
458      */

459     public static DateFormatSymbols JavaDoc lookupDateFormatSymbols(String JavaDoc languageCode)
460     {
461         Object JavaDoc lang = LANGUAGE_CODE_MAP.get(languageCode);
462         if (lang != null) {
463             if (lang instanceof Locale JavaDoc) {
464                 return new DateFormatSymbols JavaDoc((Locale JavaDoc) lang);
465             } else if (lang instanceof String JavaDoc){
466                 return getDateFormatSymbols((String JavaDoc) lang);
467             }
468         }
469         return new DateFormatSymbols JavaDoc(Locale.US);
470     }
471     
472     /**
473      * Returns a DateFormatSymbols object configured with short month names
474      * as in the supplied string
475      * @param shortmonths This should be as described in
476      * {@link #setShortMonthNames(String) shortMonthNames}
477      * @return a DateFormatSymbols object configured with short month names
478      * as in the supplied string
479      */

480     public static DateFormatSymbols JavaDoc getDateFormatSymbols(String JavaDoc shortmonths)
481     {
482         String JavaDoc[] months = splitShortMonthString(shortmonths);
483         DateFormatSymbols JavaDoc dfs = new DateFormatSymbols JavaDoc(Locale.US);
484         dfs.setShortMonths(months);
485         return dfs;
486     }
487     
488     private static String JavaDoc[] splitShortMonthString(String JavaDoc shortmonths) {
489         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(shortmonths, "|");
490         int monthcnt = st.countTokens();
491         if (12 != monthcnt) {
492             throw new IllegalArgumentException JavaDoc(
493                     "expecting a pipe-delimited string containing 12 tokens");
494         }
495         String JavaDoc[] months = new String JavaDoc[13];
496         int pos = 0;
497         while(st.hasMoreTokens()) {
498             months[pos++] = st.nextToken();
499         }
500         months[pos]="";
501         return months;
502     }
503
504     /**
505      * Returns a Collection of all the language codes currently supported
506      * by this class. See {@link #setServerLanguageCode(String) serverLanguageCode}
507      * for a functional descrption of language codes within this system.
508      *
509      * @return a Collection of all the language codes currently supported
510      * by this class
511      */

512     public static Collection JavaDoc getSupportedLanguageCodes() {
513         return LANGUAGE_CODE_MAP.keySet();
514     }
515     
516     
517 }
518
Popular Tags