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