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