View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2.provider.ftp;
18  
19  import java.net.Proxy;
20  import java.time.Duration;
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.List;
24  
25  import org.apache.commons.net.ftp.FTPReply;
26  import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
27  import org.apache.commons.vfs2.FileContent;
28  import org.apache.commons.vfs2.FileSystem;
29  import org.apache.commons.vfs2.FileSystemConfigBuilder;
30  import org.apache.commons.vfs2.FileSystemOptions;
31  
32  /**
33   * The config builder for various FTP configuration options.
34   */
35  public class FtpFileSystemConfigBuilder extends FileSystemConfigBuilder {
36  
37      private static final String _PREFIX = FtpFileSystemConfigBuilder.class.getName();
38  
39      private static final FtpFileSystemConfigBuildereSystemConfigBuilder.html#FtpFileSystemConfigBuilder">FtpFileSystemConfigBuilder BUILDER = new FtpFileSystemConfigBuilder();
40  
41      private static final String AUTODETECT_UTF8 = _PREFIX + ".AUTODETECT_UTF8";
42      private static final String CONNECT_TIMEOUT = _PREFIX + ".CONNECT_TIMEOUT";
43      private static final String DATA_TIMEOUT = _PREFIX + ".DATA_TIMEOUT";
44      private static final String DEFAULT_DATE_FORMAT = _PREFIX + ".DEFAULT_DATE_FORMAT";
45      private static final String ENCODING = _PREFIX + ".ENCODING";
46      private static final String FACTORY_KEY = FTPFileEntryParserFactory.class.getName() + ".KEY";
47      private static final String FILE_TYPE = _PREFIX + ".FILE_TYPE";
48      private static final String PASSIVE_MODE = _PREFIX + ".PASSIVE";
49      private static final String PROXY = _PREFIX + ".PROXY";
50      private static final String RECENT_DATE_FORMAT = _PREFIX + ".RECENT_DATE_FORMAT";
51      private static final String REMOTE_VERIFICATION = _PREFIX + ".REMOTE_VERIFICATION";
52      private static final String SERVER_LANGUAGE_CODE = _PREFIX + ".SERVER_LANGUAGE_CODE";
53      private static final String SERVER_TIME_ZONE_ID = _PREFIX + ".SERVER_TIME_ZONE_ID";
54      private static final String SHORT_MONTH_NAMES = _PREFIX + ".SHORT_MONTH_NAMES";
55      private static final String SO_TIMEOUT = _PREFIX + ".SO_TIMEOUT";
56      private static final String CONTROL_KEEP_ALIVE_TIMEOUT = _PREFIX + ".CONTROL_KEEP_ALIVE_TIMEOUT";
57      private static final String CONTROL_KEEP_ALIVE_REPLY_TIMEOUT = _PREFIX + ".CONTROL_KEEP_ALIVE_REPLY_TIMEOUT";
58      private static final String USER_DIR_IS_ROOT = _PREFIX + ".USER_DIR_IS_ROOT";
59      private static final String TRANSFER_ABORTED_OK_REPLY_CODES = _PREFIX + ".TRANSFER_ABORTED_OK_REPLY_CODES";
60      private static final String MDTM_LAST_MODIFED_TIME = _PREFIX + ".MDTM_LAST_MODIFED_TIME";
61  
62      /**
63       * Gets the singleton instance.
64       *
65       * @return the singleton instance.
66       */
67      public static FtpFileSystemConfigBuilder getInstance() {
68          return BUILDER;
69      }
70  
71      public static List<Integer> getSaneTransferAbortedOkReplyCodes() {
72          // See VFS-674, its accompanying PR and https://github.com/apache/commons-vfs/pull/51 as to why 426 and 550 are here
73          return new ArrayList<>(Arrays.asList(FTPReply.TRANSFER_ABORTED, FTPReply.FILE_UNAVAILABLE));
74      }
75  
76      private FtpFileSystemConfigBuilder() {
77          super("ftp.");
78      }
79  
80      /**
81       * Create new config builder with specified prefix string.
82       *
83       * @param prefix prefix string to use for parameters of this config builder.
84       * @since 2.1
85       */
86      protected FtpFileSystemConfigBuilder(final String prefix) {
87          super(prefix);
88      }
89  
90      /**
91       * Gets whether to try to autodetect the server encoding (only UTF8 is supported).
92       *
93       * @param options The FileSystemOptions.
94       * @return True if autodetection should be done.
95       * @since 2.4
96       */
97      public Boolean getAutodetectUtf8(final FileSystemOptions options) {
98          return getBoolean(options, AUTODETECT_UTF8);
99      }
100 
101     @Override
102     protected Class<? extends FileSystem> getConfigClass() {
103         return FtpFileSystem.class;
104     }
105 
106     /**
107      * Gets the timeout in milliseconds to use for the socket connection.
108      *
109      * @param options The FileSystemOptions.
110      * @return The timeout in milliseconds to use for the socket connection.
111      * @since 2.1
112      * @deprecated Use {@link #getConnectTimeoutDuration(FileSystemOptions)}.
113      */
114     @Deprecated
115     public Integer getConnectTimeout(final FileSystemOptions options) {
116         return getDurationInteger(options, CONNECT_TIMEOUT);
117     }
118 
119     /**
120      * Gets the timeout in milliseconds to use for the socket connection.
121      *
122      * @param options The FileSystemOptions.
123      * @return The timeout in milliseconds to use for the socket connection.
124      * @since 2.8.0
125      */
126     public Duration getConnectTimeoutDuration(final FileSystemOptions options) {
127         return getDuration(options, CONNECT_TIMEOUT);
128     }
129 
130     /**
131      * @param options The FileSystemOptions.
132      * @return The encoding.
133      * @since 2.0
134      */
135     public String getControlEncoding(final FileSystemOptions options) {
136         return getString(options, ENCODING);
137     }
138 
139     /**
140      * @param options The FileSystem options
141      * @return The controlKeepAliveReplyTimeout value.
142      * @since 2.8.0
143      */
144     public Duration getControlKeepAliveReplyTimeout(final FileSystemOptions options) {
145         return getDuration(options, CONTROL_KEEP_ALIVE_REPLY_TIMEOUT);
146     }
147 
148     /**
149      * @param options The FileSystem options
150      * @return The controlKeepAliveTimeout value.
151      * @since 2.8.0
152      */
153     public Duration getControlKeepAliveTimeout(final FileSystemOptions options) {
154         return getDuration(options, CONTROL_KEEP_ALIVE_TIMEOUT);
155     }
156 
157     /**
158      * @param options The FileSystemOptions.
159      * @return The timeout for opening the data channel in milliseconds.
160      * @see #setDataTimeout
161      * @deprecated Use {@link #getDataTimeoutDuration(FileSystemOptions)}.
162      */
163     @Deprecated
164     public Integer getDataTimeout(final FileSystemOptions options) {
165         return getDurationInteger(options, DATA_TIMEOUT);
166     }
167 
168     /**
169      * Gets the timeout for opening the data channel.
170      *
171      * @param options The FileSystemOptions.
172      * @return The timeout for opening the data channel.
173      * @see #setDataTimeout
174      * @since 2.8.0
175      */
176     public Duration getDataTimeoutDuration(final FileSystemOptions options) {
177         return getDuration(options, DATA_TIMEOUT);
178     }
179 
180     /**
181      * Get the default date format used by the server. See {@link org.apache.commons.net.ftp.FTPClientConfig} for
182      * details and examples.
183      *
184      * @param options The FileSystemOptions
185      * @return The default date format.
186      */
187     public String getDefaultDateFormat(final FileSystemOptions options) {
188         return getString(options, DEFAULT_DATE_FORMAT);
189     }
190 
191     /**
192      * @param options The FileSystemOptions.
193      * @see #setEntryParser
194      * @return the key to the EntryParser.
195      */
196     public String getEntryParser(final FileSystemOptions options) {
197         return getString(options, FACTORY_KEY);
198     }
199 
200     /**
201      * @param options The FlleSystemOptions.
202      * @see #setEntryParserFactory
203      * @return An FTPFileEntryParserFactory.
204      */
205     public FTPFileEntryParserFactory getEntryParserFactory(final FileSystemOptions options) {
206         return getParam(options, FTPFileEntryParserFactory.class.getName());
207     }
208 
209     /**
210      * Gets the file type parameter.
211      *
212      * @param options The FileSystemOptions.
213      * @return A FtpFileType
214      * @since 2.1
215      */
216     public FtpFileType getFileType(final FileSystemOptions options) {
217         return getEnum(FtpFileType.class, options, FILE_TYPE);
218     }
219 
220     /**
221      * Gets the option to use FTP MDTM for {@link FileContent#getLastModifiedTime()}.
222      *
223      * @param options The FileSystemOptions.
224      * @return true if MDTM should be used.
225      * @since 2.8.0
226      */
227     public Boolean getMdtmLastModifiedTime(final FileSystemOptions options) {
228         return getBoolean(options, MDTM_LAST_MODIFED_TIME);
229     }
230 
231     /**
232      * @param options The FileSystemOptions.
233      * @return true if passive mode is set.
234      * @see #setPassiveMode
235      */
236     public Boolean getPassiveMode(final FileSystemOptions options) {
237         return getBoolean(options, PASSIVE_MODE);
238     }
239 
240     /**
241      * Gets the Proxy.
242      *
243      * @param options The FileSystemOptions.
244      * @return the Proxy
245      * @since 2.1
246      */
247     public Proxy getProxy(final FileSystemOptions options) {
248         return getParam(options, PROXY);
249     }
250 
251     /**
252      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
253      *
254      * @param options The FileSystemOptions.
255      * @return The recent date format.
256      */
257     public String getRecentDateFormat(final FileSystemOptions options) {
258         return getString(options, RECENT_DATE_FORMAT);
259     }
260 
261     /**
262      * Gets whether to use remote verification.
263      *
264      * @param options The FileSystemOptions.
265      * @return True if remote verification should be done.
266      */
267     public Boolean getRemoteVerification(final FileSystemOptions options) {
268         return getBoolean(options, REMOTE_VERIFICATION);
269     }
270 
271     /**
272      * Get the language code used by the server. See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and
273      * examples.
274      *
275      * @param options The FilesystemOptions.
276      * @return The language code of the server.
277      */
278     public String getServerLanguageCode(final FileSystemOptions options) {
279         return getString(options, SERVER_LANGUAGE_CODE);
280     }
281 
282     /**
283      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
284      *
285      * @param options The FileSystemOptions.
286      * @return The server timezone id.
287      */
288     public String getServerTimeZoneId(final FileSystemOptions options) {
289         return getString(options, SERVER_TIME_ZONE_ID);
290     }
291 
292     /**
293      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
294      *
295      * @param options The FileSystemOptions.
296      * @return An array of short month names.
297      */
298     public String[] getShortMonthNames(final FileSystemOptions options) {
299         return getParam(options, SHORT_MONTH_NAMES);
300     }
301 
302     /**
303      * Gets The so timeout duration in milliseconds.
304      *
305      * @param options The FileSystem options.
306      * @return The so timeout duration in milliseconds.
307      * @see #getDataTimeout
308      * @since 2.0
309      * @deprecated Use {@link #getSoTimeoutDuration(FileSystemOptions)}.
310      */
311     @Deprecated
312     public Integer getSoTimeout(final FileSystemOptions options) {
313         return getDurationInteger(options, SO_TIMEOUT);
314     }
315 
316     /**
317      * Gets The so timeout duration.
318      *
319      * @param options The FileSystem options.
320      * @return The timeout value in milliseconds.
321      * @see #getDataTimeout
322      * @since 2.8.0
323      */
324     public Duration getSoTimeoutDuration(final FileSystemOptions options) {
325         return getDuration(options, SO_TIMEOUT);
326     }
327 
328     /**
329      * @param options The FileSystem options.
330      * @return The list of reply codes (apart from 200) that are considered as OK when prematurely
331      * closing a stream.
332      * @since 2.4
333      */
334     public List<Integer> getTransferAbortedOkReplyCodes(final FileSystemOptions options) {
335         return getParam(options, TRANSFER_ABORTED_OK_REPLY_CODES);
336     }
337 
338     /**
339      * Returns {@link Boolean#TRUE} if VFS should treat the user directory as the root directory. Defaults to
340      * {@code Boolean.TRUE} if the method {@link #setUserDirIsRoot(FileSystemOptions, boolean)} has not been
341      * invoked.
342      *
343      * @param options The FileSystemOptions.
344      * @return {@code Boolean.TRUE} if VFS treats the user directory as the root directory.
345      * @see #setUserDirIsRoot
346      */
347     public Boolean getUserDirIsRoot(final FileSystemOptions options) {
348         return getBoolean(options, USER_DIR_IS_ROOT, Boolean.TRUE);
349     }
350 
351     /**
352      * Sets whether to try to autodetect the server encoding (only UTF8 is supported).
353      *
354      * @param options The FileSystemOptions.
355      * @param autodetectUTF8 true if autodetection should be done.
356      * @since 2.4
357      */
358     public void setAutodetectUtf8(final FileSystemOptions options, final Boolean autodetectUTF8) {
359         setParam(options, AUTODETECT_UTF8, autodetectUTF8);
360     }
361 
362     /**
363      * Sets the timeout for the initial control connection.
364      * <p>
365      * If you set the connectTimeout to {@code null} no connectTimeout will be set.
366      * </p>
367      *
368      * @param options The FileSystemOptions.
369      * @param duration the timeout duration in milliseconds
370      * @since 2.8.0
371      */
372     public void setConnectTimeout(final FileSystemOptions options, final Duration duration) {
373         setParam(options, CONNECT_TIMEOUT, duration);
374     }
375 
376     /**
377      * Sets the timeout for the initial control connection.
378      * <p>
379      * If you set the connectTimeout to {@code null} no connectTimeout will be set.
380      * </p>
381      *
382      * @param options The FileSystemOptions.
383      * @param duration the timeout duration.
384      * @since 2.1
385      * @deprecated Use {@link #setConnectTimeout(FileSystemOptions, Duration)}.
386      */
387     @Deprecated
388     public void setConnectTimeout(final FileSystemOptions options, final Integer duration) {
389         setConnectTimeout(options, Duration.ofMillis(duration));
390     }
391 
392     /**
393      * See {@link org.apache.commons.net.ftp.FTP#setControlEncoding} for details and examples.
394      *
395      * @param options The FileSystemOptions.
396      * @param encoding the encoding to use
397      * @since 2.0
398      */
399     public void setControlEncoding(final FileSystemOptions options, final String encoding) {
400         setParam(options, ENCODING, encoding);
401     }
402 
403     /**
404      * Sets the control keep alive reply timeout for the FTP client.
405      *
406      * @param options The FileSystem options.
407      * @param duration timeout duration.
408      * @since 2.8.0
409      */
410     public void setControlKeepAliveReplyTimeout(final FileSystemOptions options, final Duration duration) {
411         setParam(options, CONTROL_KEEP_ALIVE_REPLY_TIMEOUT, duration);
412     }
413 
414     /**
415      * Sets the control keep alive timeout for the FTP client.
416      * <p>
417      * Set the {@code controlKeepAliveTimeout} to ensure the socket be alive after download huge file.
418      * </p>
419      *
420      * @param options The FileSystem options.
421      * @param duration The timeout duration.
422      * @since 2.8.0
423      */
424     public void setControlKeepAliveTimeout(final FileSystemOptions options, final Duration duration) {
425         setParam(options, CONTROL_KEEP_ALIVE_TIMEOUT, duration);
426     }
427 
428     /**
429      * Set the data timeout for the FTP client.
430      * <p>
431      * If you set the {@code dataTimeout} to {@code null}, no dataTimeout will be set on the FTP client.
432      * </p>
433      *
434      * @param options The FileSystemOptions.
435      * @param duration The timeout duration.
436      * @since 2.8.0
437      */
438     public void setDataTimeout(final FileSystemOptions options, final Duration duration) {
439         setParam(options, DATA_TIMEOUT, duration);
440     }
441 
442     /**
443      * Set the data timeout for the FTP client.
444      * <p>
445      * If you set the {@code dataTimeout} to {@code null}, no dataTimeout will be set on the FTP client.
446      * </p>
447      *
448      * @param options The FileSystemOptions.
449      * @param duration The timeout value.
450      * @deprecated Use {@link #setDataTimeout(FileSystemOptions, Duration)}.
451      */
452     @Deprecated
453     public void setDataTimeout(final FileSystemOptions options, final Integer duration) {
454         setDataTimeout(options, Duration.ofMillis(duration));
455     }
456 
457     /**
458      * Set the default date format used by the server. See {@link org.apache.commons.net.ftp.FTPClientConfig} for
459      * details and examples.
460      *
461      * @param options The FileSystemOptions.
462      * @param defaultDateFormat The default date format.
463      */
464     public void setDefaultDateFormat(final FileSystemOptions options, final String defaultDateFormat) {
465         setParam(options, DEFAULT_DATE_FORMAT, defaultDateFormat);
466     }
467 
468     /**
469      * Set the FQCN of your FileEntryParser used to parse the directory listing from your server.
470      * <p>
471      * If you do not use the default commons-net FTPFileEntryParserFactory e.g. by using {@link #setEntryParserFactory}
472      * this is the "key" parameter passed as argument into your custom factory.
473      * </p>
474      *
475      * @param options The FileSystemOptions.
476      * @param key The key.
477      */
478     public void setEntryParser(final FileSystemOptions options, final String key) {
479         setParam(options, FACTORY_KEY, key);
480     }
481 
482     /**
483      * FTPFileEntryParserFactory which will be used for ftp-entry parsing.
484      *
485      * @param options The FileSystemOptions.
486      * @param factory instance of your factory
487      */
488     public void setEntryParserFactory(final FileSystemOptions options, final FTPFileEntryParserFactory factory) {
489         setParam(options, FTPFileEntryParserFactory.class.getName(), factory);
490     }
491 
492     /**
493      * Sets the file type parameter.
494      *
495      * @param options The FileSystemOptions.
496      * @param ftpFileType A FtpFileType
497      * @since 2.1
498      */
499     public void setFileType(final FileSystemOptions options, final FtpFileType ftpFileType) {
500         setParam(options, FILE_TYPE, ftpFileType);
501     }
502 
503     /**
504      * Sets the option to use FTP MDTM for {@link FileContent#getLastModifiedTime()}.
505      *
506      * @param options The FileSystemOptions.
507      * @param mdtm true if MDTM should be used.
508      * @since 2.8.0
509      */
510     public void setMdtmLastModifiedTime(final FileSystemOptions options, final boolean mdtm) {
511         setParam(options, MDTM_LAST_MODIFED_TIME, toBooleanObject(mdtm));
512     }
513 
514     /**
515      * Enter into passive mode.
516      *
517      * @param options The FileSystemOptions.
518      * @param passiveMode true if passive mode should be used.
519      */
520     public void setPassiveMode(final FileSystemOptions options, final boolean passiveMode) {
521         setParam(options, PASSIVE_MODE, toBooleanObject(passiveMode));
522     }
523 
524     /**
525      * Sets the Proxy.
526      * <p>
527      * You might need to make sure that {@link #setPassiveMode(FileSystemOptions, boolean) passive mode} is activated.
528      * </p>
529      *
530      * @param options the FileSystem options.
531      * @param proxy the Proxy
532      * @since 2.1
533      */
534     public void setProxy(final FileSystemOptions options, final Proxy proxy) {
535         setParam(options, PROXY, proxy);
536     }
537 
538     /**
539      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
540      *
541      * @param options The FileSystemOptions.
542      * @param recentDateFormat The recent date format.
543      */
544     public void setRecentDateFormat(final FileSystemOptions options, final String recentDateFormat) {
545         setParam(options, RECENT_DATE_FORMAT, recentDateFormat);
546     }
547 
548     /**
549      * Sets whether to use remote verification.
550      *
551      * @param options The FileSystemOptions.
552      * @param remoteVerification True if verification should be done.
553      */
554     public void setRemoteVerification(final FileSystemOptions options, final boolean remoteVerification) {
555         setParam(options, REMOTE_VERIFICATION, remoteVerification);
556     }
557 
558     /**
559      * Set the language code used by the server. See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and
560      * examples.
561      *
562      * @param options The FileSystemOptions.
563      * @param serverLanguageCode The servers language code.
564      */
565     public void setServerLanguageCode(final FileSystemOptions options, final String serverLanguageCode) {
566         setParam(options, SERVER_LANGUAGE_CODE, serverLanguageCode);
567     }
568 
569     /**
570      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
571      *
572      * @param options The FileSystemOptions.
573      * @param serverTimeZoneId The server timezone id.
574      */
575     public void setServerTimeZoneId(final FileSystemOptions options, final String serverTimeZoneId) {
576         setParam(options, SERVER_TIME_ZONE_ID, serverTimeZoneId);
577     }
578 
579     /**
580      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
581      *
582      * @param options The FileSystemOptions.
583      * @param shortMonthNames an array of short month name Strings.
584      */
585     public void setShortMonthNames(final FileSystemOptions options, final String[] shortMonthNames) {
586         String[] clone = null;
587         if (shortMonthNames != null) {
588             clone = new String[shortMonthNames.length];
589             System.arraycopy(shortMonthNames, 0, clone, 0, shortMonthNames.length);
590         }
591 
592         setParam(options, SHORT_MONTH_NAMES, clone);
593     }
594 
595     /**
596      * Sets the socket timeout for the FTP client.
597      * <p>
598      * If you set the {@code soTimeout} to {@code null}, no socket timeout will be set on the FTP client.
599      * </p>
600      *
601      * @param options The FileSystem options.
602      * @param timeout The timeout value in milliseconds.
603      * @since 2.8.0
604      */
605     public void setSoTimeout(final FileSystemOptions options, final Duration timeout) {
606         setParam(options, SO_TIMEOUT, timeout);
607     }
608 
609     /**
610      * Sets the socket timeout for the FTP client.
611      * <p>
612      * If you set the {@code soTimeout} to {@code null}, no socket timeout will be set on the FTP client.
613      * </p>
614      *
615      * @param options The FileSystem options.
616      * @param timeout The timeout value in milliseconds.
617      * @since 2.0
618      * @deprecated Use {@link #setSoTimeout(FileSystemOptions, Duration)}.
619      */
620     @Deprecated
621     public void setSoTimeout(final FileSystemOptions options, final Integer timeout) {
622         setSoTimeout(options, Duration.ofMillis(timeout));
623     }
624 
625     /**
626      * Sets the list of reply codes that are considered as OK when prematurely closing a stream.
627      * <p>
628      * If you set the {@code replyCodes} to an empty list, all reply codes besides 200 will be
629      * considered as an error.
630      * </p>
631      *
632      * @param options The FileSystem options.
633      * @param replyCodes The reply codes.
634      * @since 2.4
635      */
636     public void setTransferAbortedOkReplyCodes(final FileSystemOptions options, final List<Integer> replyCodes) {
637         setParam(options, TRANSFER_ABORTED_OK_REPLY_CODES, replyCodes);
638     }
639 
640     /**
641      * Use user directory as root (do not change to fs root).
642      *
643      * @param options The FileSystemOptions.
644      * @param userDirIsRoot true if the user directory should be treated as the root.
645      */
646     public void setUserDirIsRoot(final FileSystemOptions options, final boolean userDirIsRoot) {
647         setParam(options, USER_DIR_IS_ROOT, toBooleanObject(userDirIsRoot));
648     }
649 }