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 */
017
018package org.apache.commons.net.ftp.parser;
019
020import java.text.ParseException;
021import java.util.Calendar;
022
023import org.apache.commons.net.ftp.Configurable;
024import org.apache.commons.net.ftp.FTPClientConfig;
025
026/**
027 * <p>
028 * This abstract class implements the common timestamp parsing algorithm for all the concrete parsers. Classes derived from this one will parse file listings
029 * via a supplied regular expression that pulls out the date portion as a separate string which is passed to the underlying {@link FTPTimestampParser delegate}
030 * to handle parsing of the file timestamp.
031 * <p>
032 * This class also implements the {@link Configurable Configurable} interface to allow the parser to be configured from the outside.
033 *
034 * @since 1.4
035 */
036public abstract class ConfigurableFTPFileEntryParserImpl extends RegexFTPFileEntryParserImpl implements Configurable {
037
038    private final FTPTimestampParser timestampParser;
039
040    /**
041     * constructor for this abstract class.
042     *
043     * @param regex Regular expression used main parsing of the file listing.
044     */
045    public ConfigurableFTPFileEntryParserImpl(final String regex) {
046        super(regex);
047        this.timestampParser = new FTPTimestampParserImpl();
048    }
049
050    /**
051     * constructor for this abstract class.
052     *
053     * @param regex Regular expression used main parsing of the file listing.
054     * @param flags the flags to apply, see {@link java.util.regex.Pattern#compile(String, int) Pattern#compile(String, int)}. Use 0 for none.
055     * @since 3.4
056     */
057    public ConfigurableFTPFileEntryParserImpl(final String regex, final int flags) {
058        super(regex, flags);
059        this.timestampParser = new FTPTimestampParserImpl();
060    }
061
062    /**
063     * Implementation of the {@link Configurable Configurable} interface. Configures this parser by delegating to the underlying Configurable FTPTimestampParser
064     * implementation, ' passing it the supplied {@link FTPClientConfig FTPClientConfig} if that is non-null or a default configuration defined by each concrete
065     * subclass.
066     *
067     * @param config the configuration to be used to configure this parser. If it is null, a default configuration defined by each concrete subclass is used
068     *               instead.
069     */
070    @Override
071    public void configure(final FTPClientConfig config) {
072        if (this.timestampParser instanceof Configurable) {
073            final FTPClientConfig defaultCfg = getDefaultConfiguration();
074            if (config != null) {
075                if (null == config.getDefaultDateFormatStr()) {
076                    config.setDefaultDateFormatStr(defaultCfg.getDefaultDateFormatStr());
077                }
078                if (null == config.getRecentDateFormatStr()) {
079                    config.setRecentDateFormatStr(defaultCfg.getRecentDateFormatStr());
080                }
081                ((Configurable) this.timestampParser).configure(config);
082            } else {
083                ((Configurable) this.timestampParser).configure(defaultCfg);
084            }
085        }
086    }
087
088    /**
089     * Each concrete subclass must define this member to create a default configuration to be used when that subclass is instantiated without a
090     * {@link FTPClientConfig FTPClientConfig} parameter being specified.
091     *
092     * @return the default configuration for the subclass.
093     */
094    protected abstract FTPClientConfig getDefaultConfiguration();
095
096    /**
097     * This method is called by the concrete parsers to delegate timestamp parsing to the timestamp parser.
098     *
099     * @param timestampStr the timestamp string pulled from the file listing by the regular expression parser, to be submitted to the
100     *                     <code>timestampParser</code> for extracting the timestamp.
101     * @return a <code>java.util.Calendar</code> containing results of the timestamp parse.
102     * @throws ParseException on parse error
103     */
104    public Calendar parseTimestamp(final String timestampStr) throws ParseException {
105        return this.timestampParser.parseTimestamp(timestampStr);
106    }
107}