001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.vfs2.provider.ftp;
018
019import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
020import org.apache.commons.vfs2.FileSystem;
021import org.apache.commons.vfs2.FileSystemConfigBuilder;
022import org.apache.commons.vfs2.FileSystemOptions;
023
024/**
025 * The config builder for various ftp configuration options.
026 */
027public class FtpFileSystemConfigBuilder extends FileSystemConfigBuilder
028{
029    private static final String _PREFIX = FtpFileSystemConfigBuilder.class.getName();
030
031    private static final FtpFileSystemConfigBuilder BUILDER = new FtpFileSystemConfigBuilder();
032
033    private static final String CONNECT_TIMEOUT = _PREFIX + ".CONNECT_TIMEOUT";
034    private static final String DATA_TIMEOUT = _PREFIX + ".DATA_TIMEOUT";
035    private static final String DEFAULT_DATE_FORMAT = _PREFIX + ".DEFAULT_DATE_FORMAT";
036    private static final String ENCODING = _PREFIX + ".ENCODING";
037    private static final String FACTORY_KEY = FTPFileEntryParserFactory.class.getName() + ".KEY";
038    private static final String FILE_TYPE = _PREFIX + ".FILE_TYPE";
039    private static final String PASSIVE_MODE = _PREFIX + ".PASSIVE";
040
041    private static final String RECENT_DATE_FORMAT = _PREFIX + ".RECENT_DATE_FORMAT";
042    private static final String SERVER_LANGUAGE_CODE = _PREFIX + ".SERVER_LANGUAGE_CODE";
043    private static final String SERVER_TIME_ZONE_ID = _PREFIX + ".SERVER_TIME_ZONE_ID";
044    private static final String SHORT_MONTH_NAMES = _PREFIX + ".SHORT_MONTH_NAMES";
045    private static final String SO_TIMEOUT = _PREFIX + ".SO_TIMEOUT";
046    private static final String USER_DIR_IS_ROOT = _PREFIX + ".USER_DIR_IS_ROOT";
047
048    /**
049     * Gets the singleton instance.
050     *
051     * @return the singleton instance.
052     */
053    public static FtpFileSystemConfigBuilder getInstance()
054    {
055        return BUILDER;
056    }
057
058    private FtpFileSystemConfigBuilder()
059    {
060        super("ftp.");
061    }
062
063    /** @since 2.1 */
064    protected FtpFileSystemConfigBuilder(final String prefix) {
065        super(prefix);
066    }
067
068    @Override
069    protected Class<? extends FileSystem> getConfigClass()
070    {
071        return FtpFileSystem.class;
072    }
073
074    /**
075     * Gets the timeout in milliseconds to use for the socket connection.
076     *
077     * @param opts The FileSystemOptions.
078     * @return The timeout in milliseconds to use for the socket connection.
079     * @since 2.1
080     */
081    public Integer getConnectTimeout(final FileSystemOptions opts)
082    {
083        return getInteger(opts, CONNECT_TIMEOUT);
084    }
085
086    /**
087     * @param opts The FileSystemOptions.
088     * @return The encoding.
089     * @since 2.0
090     * */
091    public String getControlEncoding(final FileSystemOptions opts)
092    {
093        return getString(opts, ENCODING);
094    }
095
096    /**
097     * @param opts The FileSystemOptions.
098     * @return The timeout for opening the data channel as an Integer.
099     * @see #setDataTimeout
100     */
101    public Integer getDataTimeout(final FileSystemOptions opts)
102    {
103        return getInteger(opts, DATA_TIMEOUT);
104    }
105
106    /**
107     * get the default date format used by the server. see {@link org.apache.commons.net.ftp.FTPClientConfig}
108     * for details and examples.
109     * @param opts The FileSystemOptions
110     * @return The default date format.
111     */
112    public String getDefaultDateFormat(final FileSystemOptions opts)
113    {
114        return getString(opts, DEFAULT_DATE_FORMAT);
115    }
116
117    /**
118     * @param opts The FileSystemOptions.
119     * @see #setEntryParser
120     * @return the key to the EntryParser.
121     */
122    public String getEntryParser(final FileSystemOptions opts)
123    {
124        return getString(opts, FACTORY_KEY);
125    }
126
127    /**
128     * @param opts The FlleSystemOptions.
129     * @see #setEntryParserFactory
130     * @return An FTPFileEntryParserFactory.
131     */
132    public FTPFileEntryParserFactory getEntryParserFactory(final FileSystemOptions opts)
133    {
134        return (FTPFileEntryParserFactory) getParam(opts, FTPFileEntryParserFactory.class.getName());
135    }
136
137    /**
138     * Gets the file type parameter.
139     *
140     * @param opts The FileSystemOptions.
141     * @return A FtpFileType
142     * @since 2.1
143     */
144    public FtpFileType getFileType(final FileSystemOptions opts)
145    {
146        return getEnum(FtpFileType.class, opts, FILE_TYPE);
147    }
148
149    /**
150     * @param opts The FileSystemOptions.
151     * @return true if passive mode is set.
152     * @see #setPassiveMode
153     */
154    public Boolean getPassiveMode(final FileSystemOptions opts)
155    {
156        return getBoolean(opts, PASSIVE_MODE);
157    }
158
159    /**
160     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
161     * @param opts The FileSystemOptions.
162     * @return The recent date format.
163     */
164    public String getRecentDateFormat(final FileSystemOptions opts)
165    {
166        return getString(opts, RECENT_DATE_FORMAT);
167    }
168
169    /**
170     * get the language code used by the server. see {@link org.apache.commons.net.ftp.FTPClientConfig}
171     * for details and examples.
172     * @param opts The FilesystemOptions.
173     * @return The language code of the server.
174     */
175    public String getServerLanguageCode(final FileSystemOptions opts)
176    {
177        return getString(opts, SERVER_LANGUAGE_CODE);
178    }
179
180    /**
181     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
182     * @param opts The FileSystemOptions.
183     * @return The server timezone id.
184     */
185    public String getServerTimeZoneId(final FileSystemOptions opts)
186    {
187        return getString(opts, SERVER_TIME_ZONE_ID);
188    }
189
190    /**
191     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
192     * @param opts The FileSystemOptions.
193     * @return An array of short month names.
194     */
195    public String[] getShortMonthNames(final FileSystemOptions opts)
196    {
197        return (String[]) getParam(opts, SHORT_MONTH_NAMES);
198    }
199
200    /**
201     * @param opts The FileSystem options.
202     * @return The timeout value.
203     * @see #getDataTimeout
204     * @since 2.0
205     */
206    public Integer getSoTimeout(final FileSystemOptions opts)
207    {
208        return getInteger(opts, SO_TIMEOUT);
209    }
210
211    /**
212     * Returns {@link Boolean#TRUE} if VFS should treat the user directory as the root directory. Defaults to
213     * <code>Boolean.TRUE</code> if the method {@link #setUserDirIsRoot(FileSystemOptions, boolean)} has not been
214     * invoked.
215     * 
216     * @param opts
217     *            The FileSystemOptions.
218     * @return <code>Boolean.TRUE</code> if VFS treats the user directory as the root directory.
219     * @see #setUserDirIsRoot
220     */
221    public Boolean getUserDirIsRoot(final FileSystemOptions opts)
222    {
223        return getBoolean(opts, USER_DIR_IS_ROOT, Boolean.TRUE);
224    }
225
226    /**
227     * Sets the timeout for the initial control connection.
228     * <p>
229     * If you set the connectTimeout to {@code null} no connectTimeout will be set.
230     * </p>
231     *
232     * @param opts The FileSystemOptions.
233     * @param connectTimeout the timeout value in milliseconds
234     * @since 2.1
235     */
236    public void setConnectTimeout(final FileSystemOptions opts, final Integer connectTimeout)
237    {
238        setParam(opts, CONNECT_TIMEOUT, connectTimeout);
239    }
240
241    /**
242     * see {@link org.apache.commons.net.ftp.FTP#setControlEncoding} for details and examples.
243     * @param opts The FileSystemOptions.
244     * @param encoding the encoding to use
245     * @since 2.0
246     */
247    public void setControlEncoding(final FileSystemOptions opts, final String encoding)
248    {
249        setParam(opts, ENCODING, encoding);
250    }
251
252    /**
253     * set the data timeout for the ftp client.<br />
254     * If you set the dataTimeout to {@code null} no dataTimeout will be set on the
255     * ftp client.
256     *
257     * @param opts The FileSystemOptions.
258     * @param dataTimeout The timeout value.
259     */
260    public void setDataTimeout(final FileSystemOptions opts, final Integer dataTimeout)
261    {
262        setParam(opts, DATA_TIMEOUT, dataTimeout);
263    }
264
265    /**
266     * set the default date format used by the server. see {@link org.apache.commons.net.ftp.FTPClientConfig}
267     * for details and examples.
268     * @param opts The FileSystemOptions.
269     * @param defaultDateFormat The default date format.
270     */
271    public void setDefaultDateFormat(final FileSystemOptions opts, final String defaultDateFormat)
272    {
273        setParam(opts, DEFAULT_DATE_FORMAT, defaultDateFormat);
274    }
275
276    /**
277     * set the FQCN of your FileEntryParser used to parse the directory listing from your server.<br />
278     * <br />
279     * <i>If you do not use the default commons-net FTPFileEntryParserFactory e.g. by using
280     * {@link #setEntryParserFactory}
281     * this is the "key" parameter passed as argument into your custom factory</i>
282     *
283     * @param opts The FileSystemOptions.
284     * @param key The key.
285     */
286    public void setEntryParser(final FileSystemOptions opts, final String key)
287    {
288        setParam(opts, FACTORY_KEY, key);
289    }
290
291    /**
292     * FTPFileEntryParserFactory which will be used for ftp-entry parsing.
293     *
294     * @param opts The FileSystemOptions.
295     * @param factory instance of your factory
296     */
297    public void setEntryParserFactory(final FileSystemOptions opts, final FTPFileEntryParserFactory factory)
298    {
299        setParam(opts, FTPFileEntryParserFactory.class.getName(), factory);
300    }
301
302    /**
303     * Sets the file type parameter.
304     *
305     * @param opts The FileSystemOptions.
306     * @param ftpFileType A FtpFileType
307     * @since 2.1
308     */
309    public void setFileType(final FileSystemOptions opts, final FtpFileType ftpFileType)
310    {
311        setParam(opts, FILE_TYPE, ftpFileType);
312    }
313
314    /**
315     * enter into passive mode.
316     *
317     * @param opts The FileSystemOptions.
318     * @param passiveMode true if passive mode should be used.
319     */
320    public void setPassiveMode(final FileSystemOptions opts, final boolean passiveMode)
321    {
322        setParam(opts, PASSIVE_MODE, passiveMode ? Boolean.TRUE : Boolean.FALSE);
323    }
324
325    /**
326     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
327     * @param opts The FileSystemOptions.
328     * @param recentDateFormat The recent date format.
329     */
330    public void setRecentDateFormat(final FileSystemOptions opts, final String recentDateFormat)
331    {
332        setParam(opts, RECENT_DATE_FORMAT, recentDateFormat);
333    }
334
335    /**
336     * set the language code used by the server. see {@link org.apache.commons.net.ftp.FTPClientConfig}
337     * for details and examples.
338     * @param opts The FileSystemOptions.
339     * @param serverLanguageCode The servers language code.
340     */
341    public void setServerLanguageCode(final FileSystemOptions opts, final String serverLanguageCode)
342    {
343        setParam(opts, SERVER_LANGUAGE_CODE, serverLanguageCode);
344    }
345
346    /**
347     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
348     * @param opts The FileSystemOptions.
349     * @param serverTimeZoneId The server timezone id.
350     */
351    public void setServerTimeZoneId(final FileSystemOptions opts, final String serverTimeZoneId)
352    {
353        setParam(opts, SERVER_TIME_ZONE_ID, serverTimeZoneId);
354    }
355
356    /**
357     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
358     * @param opts The FileSystemOptions.
359     * @param shortMonthNames an array of short month name Strings.
360     */
361    public void setShortMonthNames(final FileSystemOptions opts, final String[] shortMonthNames)
362    {
363        String[] clone = null;
364        if (shortMonthNames != null)
365        {
366            clone = new String[shortMonthNames.length];
367            System.arraycopy(shortMonthNames, 0, clone, 0, shortMonthNames.length);
368        }
369
370        setParam(opts, SHORT_MONTH_NAMES, clone);
371    }
372
373    /**
374     * Sets the socket timeout for the FTP client.<br />
375     * If you set the socketTimeout to {@code null} no socketTimeout will be set on the
376     * ftp client.
377     *
378     * @param opts The FileSystem options.
379     * @param soTimeout The timeout value.
380     * @since 2.0
381     */
382    public void setSoTimeout(final FileSystemOptions opts, final Integer soTimeout)
383    {
384        setParam(opts, SO_TIMEOUT, soTimeout);
385    }
386
387    /**
388     * use user directory as root (do not change to fs root).
389     *
390     * @param opts The FileSystemOptions.
391     * @param userDirIsRoot true if the user directory should be treated as the root.
392     */
393    public void setUserDirIsRoot(final FileSystemOptions opts, final boolean userDirIsRoot)
394    {
395        setParam(opts, USER_DIR_IS_ROOT, userDirIsRoot ? Boolean.TRUE : Boolean.FALSE);
396    }
397
398}