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]



Reply via email to