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.util.ArrayList;
21  import java.util.Arrays;
22  import java.util.List;
23  
24  import org.apache.commons.net.ftp.FTPReply;
25  import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
26  import org.apache.commons.vfs2.FileSystem;
27  import org.apache.commons.vfs2.FileSystemConfigBuilder;
28  import org.apache.commons.vfs2.FileSystemOptions;
29  
30  /**
31   * The config builder for various ftp configuration options.
32   */
33  public class FtpFileSystemConfigBuilder extends FileSystemConfigBuilder {
34  
35      private static final String _PREFIX = FtpFileSystemConfigBuilder.class.getName();
36  
37      private static final FtpFileSystemConfigBuildereSystemConfigBuilder.html#FtpFileSystemConfigBuilder">FtpFileSystemConfigBuilder BUILDER = new FtpFileSystemConfigBuilder();
38  
39      private static final String AUTODETECT_UTF8 = _PREFIX + ".AUTODETECT_UTF8";
40      private static final String CONNECT_TIMEOUT = _PREFIX + ".CONNECT_TIMEOUT";
41      private static final String DATA_TIMEOUT = _PREFIX + ".DATA_TIMEOUT";
42      private static final String DEFAULT_DATE_FORMAT = _PREFIX + ".DEFAULT_DATE_FORMAT";
43      private static final String ENCODING = _PREFIX + ".ENCODING";
44      private static final String FACTORY_KEY = FTPFileEntryParserFactory.class.getName() + ".KEY";
45      private static final String FILE_TYPE = _PREFIX + ".FILE_TYPE";
46      private static final String PASSIVE_MODE = _PREFIX + ".PASSIVE";
47      private static final String PROXY = _PREFIX + ".PROXY";
48      private static final String RECENT_DATE_FORMAT = _PREFIX + ".RECENT_DATE_FORMAT";
49      private static final String REMOTE_VERIFICATION = _PREFIX + ".REMOTE_VERIFICATION";
50      private static final String SERVER_LANGUAGE_CODE = _PREFIX + ".SERVER_LANGUAGE_CODE";
51      private static final String SERVER_TIME_ZONE_ID = _PREFIX + ".SERVER_TIME_ZONE_ID";
52      private static final String SHORT_MONTH_NAMES = _PREFIX + ".SHORT_MONTH_NAMES";
53      private static final String SO_TIMEOUT = _PREFIX + ".SO_TIMEOUT";
54      private static final String USER_DIR_IS_ROOT = _PREFIX + ".USER_DIR_IS_ROOT";
55      private static final String TRANSFER_ABORTED_OK_REPLY_CODES = _PREFIX + ".TRANSFER_ABORTED_OK_REPLY_CODES";
56  
57      private FtpFileSystemConfigBuilder() {
58          super("ftp.");
59      }
60  
61      /**
62       * Create new config builder with specified prefix string.
63       *
64       * @param prefix prefix string to use for parameters of this config builder.
65       * @since 2.1
66       */
67      protected FtpFileSystemConfigBuilder(final String prefix) {
68          super(prefix);
69      }
70  
71      /**
72       * Gets the singleton instance.
73       *
74       * @return the singleton instance.
75       */
76      public static FtpFileSystemConfigBuilder getInstance() {
77          return BUILDER;
78      }
79  
80      @Override
81      protected Class<? extends FileSystem> getConfigClass() {
82          return FtpFileSystem.class;
83      }
84  
85      public static List<Integer> getSaneTransferAbortedOkReplyCodes() {
86          // See VFS-674, its accompanying PR and https://github.com/apache/commons-vfs/pull/51 as to why 426 and 550 are here
87          return new ArrayList<>(Arrays.asList(FTPReply.TRANSFER_ABORTED, FTPReply.FILE_UNAVAILABLE));
88      }
89  
90      /**
91       * Gets whether to try to autodetect the server encoding (only UTF8 is supported).
92       *
93       * @param opts The FileSystemOptions.
94       * @return True if autodetection should be done.
95       * @since 2.4
96       */
97      public Boolean getAutodetectUtf8(final FileSystemOptions opts) {
98          return getBoolean(opts, AUTODETECT_UTF8);
99      }
100 
101     /**
102      * Gets the timeout in milliseconds to use for the socket connection.
103      *
104      * @param opts The FileSystemOptions.
105      * @return The timeout in milliseconds to use for the socket connection.
106      * @since 2.1
107      */
108     public Integer getConnectTimeout(final FileSystemOptions opts) {
109         return getInteger(opts, CONNECT_TIMEOUT);
110     }
111 
112     /**
113      * @param opts The FileSystemOptions.
114      * @return The encoding.
115      * @since 2.0
116      */
117     public String getControlEncoding(final FileSystemOptions opts) {
118         return getString(opts, ENCODING);
119     }
120 
121     /**
122      * @param opts The FileSystemOptions.
123      * @return The timeout for opening the data channel in milliseconds.
124      * @see #setDataTimeout
125      */
126     public Integer getDataTimeout(final FileSystemOptions opts) {
127         return getInteger(opts, DATA_TIMEOUT);
128     }
129 
130     /**
131      * Get the default date format used by the server. See {@link org.apache.commons.net.ftp.FTPClientConfig} for
132      * details and examples.
133      *
134      * @param opts The FileSystemOptions
135      * @return The default date format.
136      */
137     public String getDefaultDateFormat(final FileSystemOptions opts) {
138         return getString(opts, DEFAULT_DATE_FORMAT);
139     }
140 
141     /**
142      * @param opts The FileSystemOptions.
143      * @see #setEntryParser
144      * @return the key to the EntryParser.
145      */
146     public String getEntryParser(final FileSystemOptions opts) {
147         return getString(opts, FACTORY_KEY);
148     }
149 
150     /**
151      * @param opts The FlleSystemOptions.
152      * @see #setEntryParserFactory
153      * @return An FTPFileEntryParserFactory.
154      */
155     public FTPFileEntryParserFactory getEntryParserFactory(final FileSystemOptions opts) {
156         return (FTPFileEntryParserFactory) getParam(opts, FTPFileEntryParserFactory.class.getName());
157     }
158 
159     /**
160      * Gets the file type parameter.
161      *
162      * @param opts The FileSystemOptions.
163      * @return A FtpFileType
164      * @since 2.1
165      */
166     public FtpFileType getFileType(final FileSystemOptions opts) {
167         return getEnum(FtpFileType.class, opts, FILE_TYPE);
168     }
169 
170     /**
171      * @param opts The FileSystemOptions.
172      * @return true if passive mode is set.
173      * @see #setPassiveMode
174      */
175     public Boolean getPassiveMode(final FileSystemOptions opts) {
176         return getBoolean(opts, PASSIVE_MODE);
177     }
178 
179     /**
180      * Gets the Proxy.
181      *
182      * @param opts The FileSystemOptions.
183      * @return the Proxy
184      * @since 2.1
185      */
186     public Proxy getProxy(final FileSystemOptions opts) {
187         return (Proxy) this.getParam(opts, PROXY);
188     }
189 
190     /**
191      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
192      *
193      * @param opts The FileSystemOptions.
194      * @return The recent date format.
195      */
196     public String getRecentDateFormat(final FileSystemOptions opts) {
197         return getString(opts, RECENT_DATE_FORMAT);
198     }
199 
200     /**
201      * Gets whether to use remote verification.
202      *
203      * @param opts The FileSystemOptions.
204      * @return True if remote verification should be done.
205      */
206     public Boolean getRemoteVerification(final FileSystemOptions opts) {
207         return getBoolean(opts, REMOTE_VERIFICATION);
208     }
209 
210     /**
211      * Get the language code used by the server. See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and
212      * examples.
213      *
214      * @param opts The FilesystemOptions.
215      * @return The language code of the server.
216      */
217     public String getServerLanguageCode(final FileSystemOptions opts) {
218         return getString(opts, SERVER_LANGUAGE_CODE);
219     }
220 
221     /**
222      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
223      *
224      * @param opts The FileSystemOptions.
225      * @return The server timezone id.
226      */
227     public String getServerTimeZoneId(final FileSystemOptions opts) {
228         return getString(opts, SERVER_TIME_ZONE_ID);
229     }
230 
231     /**
232      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
233      *
234      * @param opts The FileSystemOptions.
235      * @return An array of short month names.
236      */
237     public String[] getShortMonthNames(final FileSystemOptions opts) {
238         return (String[]) getParam(opts, SHORT_MONTH_NAMES);
239     }
240 
241     /**
242      * @param opts The FileSystem options.
243      * @return The timeout value in milliseconds.
244      * @see #getDataTimeout
245      * @since 2.0
246      */
247     public Integer getSoTimeout(final FileSystemOptions opts) {
248         return getInteger(opts, SO_TIMEOUT);
249     }
250 
251     /**
252      * Returns {@link Boolean#TRUE} if VFS should treat the user directory as the root directory. Defaults to
253      * <code>Boolean.TRUE</code> if the method {@link #setUserDirIsRoot(FileSystemOptions, boolean)} has not been
254      * invoked.
255      *
256      * @param opts The FileSystemOptions.
257      * @return <code>Boolean.TRUE</code> if VFS treats the user directory as the root directory.
258      * @see #setUserDirIsRoot
259      */
260     public Boolean getUserDirIsRoot(final FileSystemOptions opts) {
261         return getBoolean(opts, USER_DIR_IS_ROOT, Boolean.TRUE);
262     }
263 
264     /**
265      * @param opts The FileSystem options.
266      * @return The list of reply codes (apart from 200) that are considered as OK when prematurely
267      * closing a stream.
268      * @since 2.4
269      */
270     @SuppressWarnings("unchecked")
271     public List<Integer> getTransferAbortedOkReplyCodes(final FileSystemOptions opts) {
272         return (List<Integer>) getParam(opts, TRANSFER_ABORTED_OK_REPLY_CODES);
273     }
274 
275     /**
276      * Sets whether to try to autodetect the server encoding (only UTF8 is supported).
277      *
278      * @param opts The FileSystemOptions.
279      * @param autodetectUTF8 true if autodetection should be done.
280      * @since 2.4
281      */
282     public void setAutodetectUtf8(final FileSystemOptions opts, final Boolean autodetectUTF8) {
283         setParam(opts, AUTODETECT_UTF8, autodetectUTF8);
284     }
285 
286     /**
287      * Sets the timeout for the initial control connection.
288      * <p>
289      * If you set the connectTimeout to {@code null} no connectTimeout will be set.
290      * </p>
291      *
292      * @param opts The FileSystemOptions.
293      * @param connectTimeout the timeout value in milliseconds
294      * @since 2.1
295      */
296     public void setConnectTimeout(final FileSystemOptions opts, final Integer connectTimeout) {
297         setParam(opts, CONNECT_TIMEOUT, connectTimeout);
298     }
299 
300     /**
301      * See {@link org.apache.commons.net.ftp.FTP#setControlEncoding} for details and examples.
302      *
303      * @param opts The FileSystemOptions.
304      * @param encoding the encoding to use
305      * @since 2.0
306      */
307     public void setControlEncoding(final FileSystemOptions opts, final String encoding) {
308         setParam(opts, ENCODING, encoding);
309     }
310 
311     /**
312      * Set the data timeout for the ftp client.
313      * <p>
314      * If you set the {@code dataTimeout} to {@code null}, no dataTimeout will be set on the ftp client.
315      * </p>
316      *
317      * @param opts The FileSystemOptions.
318      * @param dataTimeout The timeout value.
319      */
320     public void setDataTimeout(final FileSystemOptions opts, final Integer dataTimeout) {
321         setParam(opts, DATA_TIMEOUT, dataTimeout);
322     }
323 
324     /**
325      * Set the default date format used by the server. See {@link org.apache.commons.net.ftp.FTPClientConfig} for
326      * details and examples.
327      *
328      * @param opts The FileSystemOptions.
329      * @param defaultDateFormat The default date format.
330      */
331     public void setDefaultDateFormat(final FileSystemOptions opts, final String defaultDateFormat) {
332         setParam(opts, DEFAULT_DATE_FORMAT, defaultDateFormat);
333     }
334 
335     /**
336      * Set the FQCN of your FileEntryParser used to parse the directory listing from your server.
337      * <p>
338      * If you do not use the default commons-net FTPFileEntryParserFactory e.g. by using {@link #setEntryParserFactory}
339      * this is the "key" parameter passed as argument into your custom factory.
340      * </p>
341      *
342      * @param opts The FileSystemOptions.
343      * @param key The key.
344      */
345     public void setEntryParser(final FileSystemOptions opts, final String key) {
346         setParam(opts, FACTORY_KEY, key);
347     }
348 
349     /**
350      * FTPFileEntryParserFactory which will be used for ftp-entry parsing.
351      *
352      * @param opts The FileSystemOptions.
353      * @param factory instance of your factory
354      */
355     public void setEntryParserFactory(final FileSystemOptions opts, final FTPFileEntryParserFactory factory) {
356         setParam(opts, FTPFileEntryParserFactory.class.getName(), factory);
357     }
358 
359     /**
360      * Sets the file type parameter.
361      *
362      * @param opts The FileSystemOptions.
363      * @param ftpFileType A FtpFileType
364      * @since 2.1
365      */
366     public void setFileType(final FileSystemOptions opts, final FtpFileType ftpFileType) {
367         setParam(opts, FILE_TYPE, ftpFileType);
368     }
369 
370     /**
371      * Enter into passive mode.
372      *
373      * @param opts The FileSystemOptions.
374      * @param passiveMode true if passive mode should be used.
375      */
376     public void setPassiveMode(final FileSystemOptions opts, final boolean passiveMode) {
377         setParam(opts, PASSIVE_MODE, passiveMode ? Boolean.TRUE : Boolean.FALSE);
378     }
379 
380     /**
381      * Sets the Proxy.
382      * <p>
383      * You might need to make sure that {@link #setPassiveMode(FileSystemOptions, boolean) passive mode} is activated.
384      * </p>
385      *
386      * @param opts the FileSystem options.
387      * @param proxy the Proxy
388      * @since 2.1
389      */
390     public void setProxy(final FileSystemOptions opts, final Proxy proxy) {
391         setParam(opts, PROXY, proxy);
392     }
393 
394     /**
395      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
396      *
397      * @param opts The FileSystemOptions.
398      * @param recentDateFormat The recent date format.
399      */
400     public void setRecentDateFormat(final FileSystemOptions opts, final String recentDateFormat) {
401         setParam(opts, RECENT_DATE_FORMAT, recentDateFormat);
402     }
403 
404     /**
405      * Sets whether to use remote verification.
406      *
407      * @param opts The FileSystemOptions.
408      * @param remoteVerification True if verification should be done.
409      */
410     public void setRemoteVerification(final FileSystemOptions opts, final boolean remoteVerification) {
411         setParam(opts, REMOTE_VERIFICATION, remoteVerification);
412     }
413 
414     /**
415      * Set the language code used by the server. See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and
416      * examples.
417      *
418      * @param opts The FileSystemOptions.
419      * @param serverLanguageCode The servers language code.
420      */
421     public void setServerLanguageCode(final FileSystemOptions opts, final String serverLanguageCode) {
422         setParam(opts, SERVER_LANGUAGE_CODE, serverLanguageCode);
423     }
424 
425     /**
426      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
427      *
428      * @param opts The FileSystemOptions.
429      * @param serverTimeZoneId The server timezone id.
430      */
431     public void setServerTimeZoneId(final FileSystemOptions opts, final String serverTimeZoneId) {
432         setParam(opts, SERVER_TIME_ZONE_ID, serverTimeZoneId);
433     }
434 
435     /**
436      * See {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
437      *
438      * @param opts The FileSystemOptions.
439      * @param shortMonthNames an array of short month name Strings.
440      */
441     public void setShortMonthNames(final FileSystemOptions opts, final String[] shortMonthNames) {
442         String[] clone = null;
443         if (shortMonthNames != null) {
444             clone = new String[shortMonthNames.length];
445             System.arraycopy(shortMonthNames, 0, clone, 0, shortMonthNames.length);
446         }
447 
448         setParam(opts, SHORT_MONTH_NAMES, clone);
449     }
450 
451     /**
452      * Sets the socket timeout for the FTP client.
453      * <p>
454      * If you set the {@code soTimeout} to {@code null}, no socket timeout will be set on the ftp client.
455      * </p>
456      *
457      * @param opts The FileSystem options.
458      * @param soTimeout The timeout value in milliseconds.
459      * @since 2.0
460      */
461     public void setSoTimeout(final FileSystemOptions opts, final Integer soTimeout) {
462         setParam(opts, SO_TIMEOUT, soTimeout);
463     }
464 
465     /**
466      * Use user directory as root (do not change to fs root).
467      *
468      * @param opts The FileSystemOptions.
469      * @param userDirIsRoot true if the user directory should be treated as the root.
470      */
471     public void setUserDirIsRoot(final FileSystemOptions opts, final boolean userDirIsRoot) {
472         setParam(opts, USER_DIR_IS_ROOT, userDirIsRoot ? Boolean.TRUE : Boolean.FALSE);
473     }
474 
475     /**
476      * Sets the list of reply codes that are considered as OK when prematurely closing a stream.
477      * <p>
478      * If you set the {@code replyCodes} to an empty list, all reply codes besides 200 will be
479      * considered as an error.
480      * </p>
481      *
482      * @param opts The FileSystem options.
483      * @param replyCodes The reply codes.
484      * @since 2.4
485      */
486     public void setTransferAbortedOkReplyCodes(final FileSystemOptions opts, final List<Integer> replyCodes) {
487         setParam(opts, TRANSFER_ABORTED_OK_REPLY_CODES, replyCodes);
488     }
489 }