//
// This software is now distributed according to
// the Lesser Gnu Public License. Please see
// http://www.gnu.org/copyleft/lesser.txt for
// the details.
// -- Happy Computing!
//
package com.stevesoft.pat;
import java.io.*;
import java.util.*;
/** This class is a different form of Regex designed to work more
like the file matching utility of a Unix shell. It is implemented
by some simple string transformations:
FileRegex | Regex |
* | .* |
. | \. |
{ | (?: |
{?! | (?! |
{?= | (?= |
{?? | (?? |
} | ) |
? | . |
{,} | (|) |
Note that a FileRegex pattern always ends with the Regex
pattern element "$". If you like to experiment, try making
FileRegex's and then printing them out. The toString() method
does a decompile of the pattern to a standard Regex. Here are
some more complete examples:
FileRegex | Regex |
*.java | .*\.java$ |
*.{java,html} | .*\.(java|html)$ |
foo.[chC] | foo.[chC]$ |
*/
public class FileRegex extends Regex {
/** Build an unitialized FileRegex. */
public FileRegex() { dirflag=EITHER; }
/** Build a FileRegex form String s. */
public FileRegex(String s) {
super(s);
dirflag = EITHER;
}
/** Compile a new pattern.
Throws @exception com.stevesoft.pat.RegSyntax for
nonsensical patterns like "[9-0]+" just as Regex does.
@see com.stevesoft.pat#compile(java.lang.String)
*/
public void compile(String s) throws RegSyntax {
String npat = toFileRegex(s);
super.compile(npat);
if(File.separatorChar == '\\') // MS-DOS
ignoreCase = true;
}
/** This is the method required by FileNameFilter.
To get a listing of files in the current directory
ending in .java, do this:
File dot = new File(".");
FileRegex java_files = new FileRegex("*.java");
String[] file_list = dot.list(java_files);
*/
public boolean accept(File dir,String s) {
if(dirflag != EITHER) {
File f = new File(s);
if(f.isDirectory() && dirflag == NONDIR)
return false;
if(!f.isDirectory() && dirflag == DIR)
return false;
}
return matchAt(s,0);
}
int dirflag = 0;
final static int EITHER=0,DIR=1,NONDIR=2;
/** Provides an alternative to File.list -- this
separates its argument according to File.pathSeparator.
To each path, it splits off a directory -- all characters
up to and including the first instance of File.separator --
and a file pattern -- the part that comes after the directory.
It then produces a list of all the pattern matches on all
the paths. Thus "*.java:../*.java" would produce a list of
all the java files in this directory and in the ".." directory
on a Unix machine. "*.java;..\\*.java" would do the same thing
on a Dos machine. */
public static String[] list(String f) {
return list(f,EITHER);
}
static String[] list(String f,int df) {
//return list_(f,new FileRegex());
StringTokenizer st = new StringTokenizer(f,File.pathSeparator);
Vector v = new Vector();
while(st.hasMoreTokens()) {
String path = st.nextToken();
list1(path,v,df,true);
}
String[] sa = new String[v.size()];
v.copyInto(sa);
return sa;
}
final static Regex root=new Regex(File.separatorChar=='/' ?
"/$" : "(?:.:|)\\\\$");
static void list1(String path,Vector v,int df,boolean rec) {
// if path looks like a/b/c/ or d:\ then add .
if(root.matchAt(path,0)) {
v.addElement(path+".");
return;
}
File f = new File(path);
if(f.getParent() != null && rec) {
Vector v2 = new Vector();
list1(f.getParent(),v2,DIR,true);
for(int i=0;i