xref: /aosp_15_r20/external/cldr/tools/cldr-code/src/main/java/org/unicode/cldr/util/LocalePathValueListMatcher.java (revision 912701f9769bb47905792267661f0baf2b85bed5)
1 package org.unicode.cldr.util;
2 
3 import com.google.common.base.Splitter;
4 import com.google.common.collect.ImmutableList;
5 import java.io.IOException;
6 import java.io.UncheckedIOException;
7 import java.nio.file.Files;
8 import java.nio.file.Path;
9 import java.util.ArrayList;
10 import java.util.List;
11 import java.util.regex.Pattern;
12 import java.util.stream.Stream;
13 
14 public class LocalePathValueListMatcher {
15 
16     private static final Splitter SPLIT_SEMI_COLON = Splitter.on(';').trimResults();
17 
18     public static class LocalePathValueMatcher {
19         final Pattern localePattern;
20         final Pattern pathPattern;
21         final Pattern valuePattern;
22 
LocalePathValueMatcher(List<String> parts)23         public LocalePathValueMatcher(List<String> parts) {
24             localePattern =
25                     parts.size() < 1 || parts.get(0).isEmpty()
26                             ? null
27                             : Pattern.compile(parts.get(0));
28             pathPattern =
29                     parts.size() < 2 || parts.get(1).isEmpty()
30                             ? null
31                             : Pattern.compile(parts.get(1).replace("[@", "\\[@"));
32             valuePattern =
33                     parts.size() < 3 || parts.get(1).isEmpty()
34                             ? null
35                             : Pattern.compile(parts.get(2));
36         }
37 
38         public boolean lookingAt(String locale, String path, String value) {
39             return (localePattern == null || localePattern.matcher(locale).lookingAt())
40                     && (pathPattern == null || pathPattern.matcher(path).lookingAt())
41                     && (valuePattern == null || valuePattern.matcher(value).lookingAt());
42         }
43 
44         /**
45          * Just test the locale, to see if we need to bother looking at its path/values
46          *
47          * @param locale
48          * @param path
49          * @param value
50          * @return
51          */
52         public boolean lookingAt(String locale) {
53             return (localePattern == null || localePattern.matcher(locale).lookingAt());
54         }
55 
56         @Override
57         public String toString() {
58             return String.format("%s\t;\t%s\t%;\ts", localePattern, pathPattern, valuePattern);
59         }
60     }
61 
62     final List<LocalePathValueListMatcher.LocalePathValueMatcher> matchData;
63 
64     public LocalePathValueListMatcher(
65             List<LocalePathValueListMatcher.LocalePathValueMatcher> _matchData) {
66         matchData = ImmutableList.copyOf(_matchData);
67     }
68 
69     public static LocalePathValueListMatcher load(Path path) {
70         try {
71             return load(Files.lines(path));
72         } catch (IOException ex) {
73             throw new UncheckedIOException(ex);
74         }
75     }
76 
77     public static LocalePathValueListMatcher load(Stream<String> lines) {
78         List<LocalePathValueListMatcher.LocalePathValueMatcher> _matchData = new ArrayList<>();
79         lines.forEach(line -> load(line, _matchData));
80         return new LocalePathValueListMatcher(_matchData);
81     }
82 
83     public boolean lookingAt(String locale, String path, String value) {
84         for (LocalePathValueListMatcher.LocalePathValueMatcher lpv : matchData) {
85             if (lpv.lookingAt(locale, path, value)) {
86                 return true;
87             }
88         }
89         return false;
90     }
91 
92     /** Just test the locale, to see if we need to bother */
93     public boolean lookingAt(String locale) {
94         for (LocalePathValueListMatcher.LocalePathValueMatcher lpv : matchData) {
95             if (lpv.lookingAt(locale)) {
96                 return true;
97             }
98         }
99         return false;
100     }
101 
102     private static void load(
103             String line, List<LocalePathValueListMatcher.LocalePathValueMatcher> _matchData) {
104         line = line.trim();
105         if (line.startsWith("#") || line.isEmpty()) {
106             return;
107         }
108         final List<String> lineList = SPLIT_SEMI_COLON.splitToList(line);
109         if (lineList.size() < 2) {
110             throw new IllegalArgumentException(
111                     "Match lines must have at least locale ; path: «" + line + "»");
112         }
113         if (lineList.size() > 3) {
114             throw new IllegalArgumentException(
115                     "Match lines must have a maximum of 3 fields (locale; path; value): «"
116                             + line
117                             + "»");
118         }
119         _matchData.add(new LocalePathValueMatcher(lineList));
120     }
121 }
122