    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
    018
    019    package org.apache.commons.net.ftp.parser;
    020
    021    import java.util.regex.MatchResult;
    022    import java.util.regex.Matcher;
    023    import java.util.regex.Pattern;
    024    import java.util.regex.PatternSyntaxException;
    025
    026    import org.apache.commons.net.ftp.FTPFileEntryParserImpl;
    027
    028    /**
    029     * This abstract class implements both the older FTPFileListParser and
    030     * newer FTPFileEntryParser interfaces with default functionality.
    031     * All the classes in the parser subpackage inherit from this.
    032     *
    033     * This is the base class for all regular expression based FTPFileEntryParser classes
    034     *
    035     * @author Steve Cohen <scohen@apache.org>
    036     */
    037    public abstract class RegexFTPFileEntryParserImpl extends
    038            FTPFileEntryParserImpl {
    039        /**
    040         * internal pattern the matcher tries to match, representing a file
    041         * entry
    042         */
    043        private Pattern pattern = null;
    044
    045        /**
    046         * internal match result used by the parser
    047         */
    048        private MatchResult result = null;
    049
    050        /**
    051         * Internal PatternMatcher object used by the parser.  It has protected
    052         * scope in case subclasses want to make use of it for their own purposes.
    053         */
    054        protected Matcher _matcher_ = null;
    055
    056        /**
    057         * The constructor for a RegexFTPFileEntryParserImpl object.
    058         *
    059         * @param regex  The regular expression with which this object is
    060         * initialized.
    061         *
    062         * @exception IllegalArgumentException
    063         * Thrown if the regular expression is unparseable.  Should not be seen in
    064         * normal conditions.  It it is seen, this is a sign that a subclass has
    065         * been created with a bad regular expression.   Since the parser must be
    066         * created before use, this means that any bad parser subclasses created
    067         * from this will bomb very quickly,  leading to easy detection.
    068         */
    069
    070        public RegexFTPFileEntryParserImpl(String regex) {
    071            super();
    072            setRegex(regex);
    073        }
    074
    075        /**
    076         * Convenience method delegates to the internal MatchResult's matches()
    077         * method.
    078         *
    079         * @param s the String to be matched
    080         * @return true if s matches this object's regular expression.
    081         */
    082
    083        public boolean matches(String s) {
    084            this.result = null;
    085            _matcher_ = pattern.matcher(s);
    086            if (_matcher_.matches()) {
    087                this.result = _matcher_.toMatchResult();
    088            }
    089            return null != this.result;
    090        }
    091
    092        /**
    093         * Convenience method
    094         *
    095         * @return the number of groups() in the internal MatchResult.
    096         */
    097
    098        public int getGroupCnt() {
    099            if (this.result == null) {
    100                return 0;
    101            }
    102            return this.result.groupCount();
    103        }
    104
    105        /**
    106         * Convenience method delegates to the internal MatchResult's group()
    107         * method.
    108         *
    109         * @param matchnum match group number to be retrieved
    110         *
    111         * @return the content of the <code>matchnum'th</code> group of the internal
    112         *         match or null if this method is called without a match having
    113         *         been made.
    114         */
    115        public String group(int matchnum) {
    116            if (this.result == null) {
    117                return null;
    118            }
    119            return this.result.group(matchnum);
    120        }
    121
    122        /**
    123         * For debugging purposes - returns a string shows each match group by
    124         * number.
    125         *
    126         * @return a string shows each match group by number.
    127         */
    128
    129        public String getGroupsAsString() {
    130            StringBuilder b = new StringBuilder();
    131            for (int i = 1; i <= this.result.groupCount(); i++) {
    132                b.append(i).append(") ").append(this.result.group(i)).append(
    133                        System.getProperty("line.separator"));
    134            }
    135            return b.toString();
    136        }
    137
    138        /**
    139         * Alter the current regular expression being utilised for entry parsing
    140         * and create a new {@link Pattern} instance.
    141         * @param regex The new regular expression
    142         * @return  true if the compiled pattern is not null
    143         * @since 2.0
    144         */
    145        public boolean setRegex(String regex) {
    146            try {
    147                pattern = Pattern.compile(regex);
    148            } catch (PatternSyntaxException pse) {
    149                throw new IllegalArgumentException("Unparseable regex supplied: "
    150                        + regex);
    151            }
    152            return (pattern != null);
    153        }
    154
    155    }