1 package org.unicode.cldr.util; 2 3 import java.io.BufferedReader; 4 import org.unicode.cldr.util.CldrUtility.VariableReplacer; 5 6 /** 7 * Parses a file of regexes for use in RegexLookup or any other class that requires a list of 8 * regexes. 9 * 10 * @author jchye 11 */ 12 public class RegexFileParser { 13 private RegexLineParser lineParser; 14 private VariableProcessor varProcessor = DEFAULT_VARIABLE_PROCESSOR; 15 16 /** Parses a line given to it by the RegexFileParser. */ 17 public interface RegexLineParser { parse(String line)18 public void parse(String line); 19 } 20 21 /** Stores variables given to it by the RegexFileParser and performs replacements if needed. */ 22 public interface VariableProcessor { add(String variable, String variableName)23 public void add(String variable, String variableName); 24 replace(String str)25 public String replace(String str); 26 } 27 28 private static final VariableProcessor DEFAULT_VARIABLE_PROCESSOR = 29 new VariableProcessor() { 30 VariableReplacer variables = new VariableReplacer(); 31 32 @Override 33 public void add(String variableName, String value) { 34 variables.add(variableName, value); 35 } 36 37 @Override 38 public String replace(String str) { 39 return variables.replace(str); 40 } 41 }; 42 setLineParser(RegexLineParser lineParser)43 public void setLineParser(RegexLineParser lineParser) { 44 this.lineParser = lineParser; 45 } 46 setVariableProcessor(VariableProcessor varProcessor)47 public void setVariableProcessor(VariableProcessor varProcessor) { 48 this.varProcessor = varProcessor; 49 } 50 51 /** 52 * Parses the specified text file. 53 * 54 * @param a class relative to filename 55 * @param filename the name of the text file to be parsed 56 */ parse(Class<?> baseClass, String filename)57 public void parse(Class<?> baseClass, String filename) { 58 BufferedReader reader = FileReaders.openFile(baseClass, filename); 59 Iterable<String> rlsi = With.toIterable(new FileReaders.ReadLineSimpleIterator(reader)); 60 parseStrings(filename, rlsi); 61 } 62 63 /** 64 * Parses the specified lines, as if they came from a text file. 65 * 66 * @param a class relative to filename 67 * @param filename the name of the text file to be parsed 68 */ parseStrings(String source, Iterable<String> rlsi)69 public void parseStrings(String source, Iterable<String> rlsi) { 70 String line = null; 71 int lineNumber = 0; 72 try { 73 for (String lineItem : rlsi) { 74 line = lineItem; // copy for possible exception 75 lineNumber++; 76 line = line.trim(); 77 // Skip comments. 78 if (line.length() == 0 || line.startsWith("#")) continue; 79 // Read variables. 80 if (line.charAt(0) == '%') { 81 int pos = line.indexOf("="); 82 if (pos < 0) { 83 throw new IllegalArgumentException( 84 "Failed to read variable in " 85 + source 86 + "\t\t(" 87 + lineNumber 88 + ") " 89 + line); 90 } 91 String varName = line.substring(0, pos).trim(); 92 String varValue = line.substring(pos + 1).trim(); 93 varProcessor.add(varName, varValue); 94 continue; 95 } 96 if (line.contains("%")) { 97 line = varProcessor.replace(line); 98 } 99 // Process a line in the input file for xpath conversion. 100 lineParser.parse(line); 101 } 102 } catch (Exception e) { 103 throw new IllegalArgumentException( 104 "Error reading " + source + " at line " + lineNumber + ": " + line, e); 105 } 106 } 107 } 108