There already is a <containsregexp> in the latest version of Ant. I'm
not sure how the implementations compare. Could you compare yours with
it and offer any benefits yours has as a patch against the HEAD version
of Ant's codebase?
Erik
On Friday, September 5, 2003, at 02:18 PM, Thorsten Möller wrote:
Hi,
I wrote a new selector named "ContainsRegexpSelector". It works pretty
much
the same like the "ContainsSelector" except that it uses a regular
expression to decide wheter including a file in a particular fileset.
Because I think there is a commond need for such a selector I would
donate
the code to the Ant project. I did not test the code very exhaustive
but I
think it works ok (the code is mostly a composition from different Ant
classes, i.e. I copied a lot Also there is no documentation except the
Java Doc comments.
At the end you will find the code.
I would be very pleased to see the selector as a "normal" part in the
project some day.
Thorsten Möller
-------------------------------------------
/*
* Created on 05.09.2003
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software
itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "Ant" and "Apache Software
* Foundation" must not be used to endorse or promote products
derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.types.selectors;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import org.apache.tools.ant.types.Parameter;
import org.apache.tools.ant.types.selectors.BaseExtendSelector;
import org.apache.tools.ant.util.regexp.Regexp;
import org.apache.tools.ant.util.regexp.RegexpFactory;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
/**
* Selector that filters files based on whether they contain a
* particular pattern expressed with a regular expression.
*
* Note: This class was directly copied from the Apache Ant project
* <code>org.apache.tools.ant.types.selectors.ContainsSelector</code>
* class. This results in the Apache reference at the beginning of
* this file.
*
* @author Thorsten Möller - [EMAIL PROTECTED]
*
* $Revision: $; $Author: $; $Date: $
*/
public class ContainsRegexpSelector extends BaseExtendSelector
{
private boolean byline;
private String flags;
private Regexp regexp = null;
private static final RegexpFactory factory = new RegexpFactory();
public static final String PATTERN_KEY = "pattern";
public static final String FLAGS_KEY = "flags";
public static final String BYLINE_KEY = "byline";
public ContainsRegexpSelector()
{
this.regexp = factory.newRegexp();
}
public String toString()
{
StringBuffer buf = new StringBuffer("{containsRegexpSelector
pattern: ");
buf.append(regexp.getPattern());
buf.append(" byline: ");
buf.append(Boolean.toString(byline));
buf.append(" flags: ");
buf.append(flags);
buf.append("}");
return buf.toString();
}
/**
* Process the file(s) one line at a time, executing the replacement
* on one line at a time. This is useful if you
* want to only replace the first occurence of a regular expression on
* each line, which is not easy to do when processing the file as a
whole.
* Defaults to <i>false</i>.</td>
*/
public void setByLine(String byline)
{
Boolean res = Boolean.valueOf(byline);
if (res == null)
{
res = Boolean.FALSE;
}
this.byline = res.booleanValue();
}
/**
* The flags to use when matching the regular expression. For more
* information, consult the Perl5 syntax.
* <ul>
* <li>g : Global replacement. Replace all occurences found
* <li>i : Case Insensitive. Do not consider case in the match
* <li>m : Multiline. Treat the string as multiple lines of input,
* using "^" and "$" as the start or end of any line,
respectively,
rather than start or end of string.
* <li> s : Singleline. Treat the string as a single line of input,
using
* "." to match any character, including a newline, which
normally,
it would not match.
*</ul>
*/
public void setFlags(String flags)
{
this.flags = flags;
}
/**
* The pattern to search for within a file.
*
* @param regexp the string that a file must contain to be selected.
*/
public void setRegexp(String pattern)
{
this.regexp.setPattern(pattern);
}
/**
* When using this as a custom selector, this method will be called.
* It translates each parameter into the appropriate setXXX() call.
*
* @param parameters the complete set of parameters for this selector
*/
public void setParameters(Parameter[] parameters)
{
super.setParameters(parameters);
if (parameters != null)
{
for (int i = 0; i < parameters.length; i++)
{
String paramname = parameters[i].getName();
if (PATTERN_KEY.equalsIgnoreCase(paramname))
{
setRegexp(parameters[i].getValue());
}
else if (BYLINE_KEY.equalsIgnoreCase(paramname))
{
setByLine(parameters[i].getValue());
}
else if (FLAGS_KEY.equalsIgnoreCase(paramname))
{
setFlags(parameters[i].getValue());
}
else
{
setError("Invalid parameter " + paramname);
}
}
}
}
/**
* Checks to make sure all settings are kosher. In this case, it
* means that the pattern attribute has been set.
*
*/
public void verifySettings()
{
if (regexp == null)
{
setError("The pattern attribute is required");
}
}
/**
* The heart of the matter. This is where the selector gets to decide
* on the inclusion of a file in a particular fileset.
*
* @param basedir the base directory the scan is being done from
* @param filename is the name of the file to check
* @param file is a java.io.File object the selector can use
* @return whether the file should be selected or not
*/
public boolean isSelected(File basedir, String filename, File file)
{
// throw BuildException on error
validate();
if (file.isDirectory())
{
return true;
}
int options = 0;
// if (flags.indexOf('g') != -1) options |= Regexp.REPLACE_ALL;
if (flags.indexOf('i') != -1) options |=
Regexp.MATCH_CASE_INSENSITIVE;
if (flags.indexOf('m') != -1) options |= Regexp.MATCH_MULTILINE;
if (flags.indexOf('s') != -1) options |= Regexp.MATCH_SINGLELINE;
FileReader r = null;
try
{
r = new FileReader(file);
BufferedReader br = new BufferedReader(r);
log("Searching pattern '" + regexp.getPattern()
+ "' in '" + file.getPath() + "'"
+ (byline ? " by line" : "")
+ (flags.length() > 0 ? " with flags: '" + flags + "'" : "")
+ ".",
Project.MSG_VERBOSE);
if (byline)
{
StringBuffer linebuf = new StringBuffer();
String line = null;
int c;
boolean hasCR = false;
do
{
c = br.read();
if (c == '\r')
{
if (hasCR)
{
// second CR -> EOL + possibly empty line
line = linebuf.toString();
if (regexp.matches(line, options))
{
return true;
}
linebuf.setLength(0);
// hasCR is still true (for the second one)
}
else
{
// first CR in this line
hasCR = true;
}
}
else if (c == '\n')
{
// LF -> EOL
line = linebuf.toString();
if (regexp.matches(line, options))
{
return true;
}
if (hasCR)
{
hasCR = false;
}
linebuf.setLength(0);
}
else
{ // any other char
if ((hasCR) || (c < 0))
{
// Mac-style linebreak or EOF (or both)
line = linebuf.toString();
if (regexp.matches(line, options))
{
return true;
}
if (hasCR)
{
hasCR = false;
}
linebuf.setLength(0);
}
if (c >= 0)
{
linebuf.append((char) c);
}
}
}
while (c >= 0);
}
else
{
int flen = (int) file.length();
char tmpBuf[] = new char[flen];
int numread = 0;
int totread = 0;
while (numread != -1 && totread < flen)
{
numread = br.read(tmpBuf, totread, flen);
totread += numread;
}
if (regexp.matches(new String(tmpBuf), options))
{
return true;
}
}
r.close();
r = null;
}
catch (IOException ioe)
{
throw new BuildException("Could not read file " + filename);
}
finally
{
try
{
if (r != null)
{
r.close();
}
}
catch (Exception e)
{
throw new BuildException("Could not close file " + filename);
}
}
return false;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]