001 /*
002 * Copyright 2004-2005 The Apache Software Foundation
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.apache.commons.net.ftp.parser;
018 import org.apache.commons.net.ftp.FTPFileEntryParserImpl;
019 import org.apache.oro.text.regex.MalformedPatternException;
020 import org.apache.oro.text.regex.MatchResult;
021 import org.apache.oro.text.regex.Pattern;
022 import org.apache.oro.text.regex.PatternMatcher;
023 import org.apache.oro.text.regex.Perl5Compiler;
024 import org.apache.oro.text.regex.Perl5Matcher;
025
026
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 for all regular based FTPFileEntryParser
034 *
035 * @author Steve Cohen <scohen@apache.org>
036 */
037 public abstract class RegexFTPFileEntryParserImpl extends FTPFileEntryParserImpl
038 {
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 PatternMatcher _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 {
072 super();
073 try
074 {
075 _matcher_ = new Perl5Matcher();
076 pattern = new Perl5Compiler().compile(regex);
077 }
078 catch (MalformedPatternException e)
079 {
080 throw new IllegalArgumentException (
081 "Unparseable regex supplied: " + regex);
082 }
083 }
084
085 /**
086 * Convenience method delegates to the internal MatchResult's matches()
087 * method.
088 *
089 * @param s the String to be matched
090 * @return true if s matches this object's regular expression.
091 */
092
093 public boolean matches(String s)
094 {
095 this.result = null;
096 if (_matcher_.matches(s.trim(), this.pattern))
097 {
098 this.result = _matcher_.getMatch();
099 }
100 return null != this.result;
101 }
102
103
104
105 /**
106 * Convenience method delegates to the internal MatchResult's groups()
107 * method.
108 *
109 * @return the number of groups() in the internal MatchResult.
110 */
111
112 public int getGroupCnt()
113 {
114 if (this.result == null)
115 {
116 return 0;
117 }
118 return this.result.groups();
119 }
120
121
122
123 /**
124 * Convenience method delegates to the internal MatchResult's group()
125 * method.
126 *
127 * @param matchnum match group number to be retrieved
128 *
129 * @return the content of the <code>matchnum'th<code> group of the internal
130 * match or null if this method is called without a match having
131 * been made.
132 */
133 public String group(int matchnum)
134 {
135 if (this.result == null)
136 {
137 return null;
138 }
139 return this.result.group(matchnum);
140 }
141
142 /**
143 * For debugging purposes - returns a string shows each match group by
144 * number.
145 *
146 * @return a string shows each match group by number.
147 */
148
149 public String getGroupsAsString()
150 {
151 StringBuffer b = new StringBuffer();
152 for (int i = 1; i <= this.result.groups(); i++)
153 {
154 b.append(i).append(") ").append(this.result.group(i))
155 .append(System.getProperty("line.separator"));
156 }
157 return b.toString();
158 }
159
160 }
161
162