Note that the colors may look strange on your screen, but they look very nice on mine.
import com.oroinc.text.regex.*;
import java.io.*;
import java.util.*;
/**
* Reads the different files containing the rules. The rules
* are interpreted differently by looking at the file name.
* To find the files the imgae path is checked for files with special names.
* @author Claudio Fleiner <cfl@zurich.ibm.com>
*/
public class Rules {
/** list of filesnames interpreted as facebiff files */
static public String[] rcfiles={ ".faces","_faces","faces" };
/** list of filesnames interpreted as faces files */
static public String[] facebifffiles={ ".facealiases" };
/** we use the oroinc perl pattern matcher */
static private Perl5Compiler pc=new Perl5Compiler();
/** the rules are initially stored in a vector */
private Vector vrules=new Vector();
/** when all rules have been read they are copied to an array */
private Rule[] rules;
/**
* Constuctor with a list of path names formated the same way as the
* CLASSPATH.
* @param path list of directories separated by the path separater
* character
*/
public Rules(String path) {
StringTokenizer st=new StringTokenizer(path,File.pathSeparator);
while(st.hasMoreTokens()) {
init(st.nextToken(),true);
}
rules=new Rule[vrules.size()];
for(int i=0;i<rules.length;i++)
rules[i]=(Rule)vrules.elementAt(i);
vrules=null;
}
/**
* Search within a directory if there is a file with rules.
* @param d directory to be searched
* @param perl true if regular expressions are perl expressions,
* but false if they are simple unix file regular
* expressions
*/
private void init(String d,boolean perl) {
File f=new File(d);
if(f.isDirectory()) {
for(int i=0;i<rcfiles.length;i++)
init(d+File.separator+rcfiles[i],true);
for(int i=0;i<facebifffiles.length;i++)
init(d+File.separator+facebifffiles[i],false);
} else if(f.canRead()) {
try {
FileReader fr=new FileReader(f);
BufferedReader bfr=new BufferedReader(fr);
String l;
while((l=bfr.readLine())!=null)
addRule(l,perl);
bfr.close();
fr.close();
} catch(Exception e) { }
}
}
/**
* Add a rule to the list of rules
* @param l rule to be added
* @param perl set to true i fperl regular expression should be used,
* false if unix file regular expression are needed.
*/
private void addRule(String l,boolean perl) {
if(l==null || l.length()<2 || l.startsWith("#")) return;
int b=l.indexOf(':');
int s=l.lastIndexOf(' ');
int t=l.lastIndexOf('\t');
if(b<0 || (s<0 && t<0)) return;
if(t>s) s=t;
String h=l.substring(0,b);
String i=l.substring(s+1);
b++;
while(l.charAt(b)==' ' || l.charAt(b)=='\t') b++;
while(l.charAt(s)==' ' || l.charAt(s)=='\t') s--;
String p=l.substring(b,s+1);
Rule rule=new Rule();
if(!perl) {
p=toPerl(p);
h=toPerl(h);
}
try {
rule.header=(Perl5Pattern)pc.compile(h,Perl5Compiler.CASE_INSENSITIVE_MASK|Perl5Compiler.MULTILINE_MASK);
} catch(MalformedPatternException e) {
System.err.println("Error compiling pattern "+h);
return;
}
try {
rule.value=(Perl5Pattern)pc.compile(p,Perl5Compiler.CASE_INSENSITIVE_MASK|Perl5Compiler.MULTILINE_MASK);
} catch(MalformedPatternException e) {
System.err.println("Error compiling pattern "+p);
return;
}
rule.image=i;
vrules.addElement(rule);
}
/**
* Convert a standard unix file regular expression to perl syntax.
* i.e. replace '*' with ".*"
* '?' with '.'
* and add a bunch of '\'
*/
static private String toPerl(String r) {
StringBuffer b=new StringBuffer();
for(int i=0;i<r.length();i++) {
switch(r.charAt(i)) {
case '\\': if(i+1<r.length()) b.append('\\').append(r.charAt(++i));
break;
case '.': b.append("\\.");break;
case '?': b.append('.');break;
case '*': b.append(".*");break;
case '(':
case ')':
case '{':
case '}':
case '+': b.append('\\'); // break missing on purpose
default: b.append(r.charAt(i));
}
}
return b.toString();
}
}