View Javadoc
1   package org.djunits.locale;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertTrue;
5   
6   import java.io.File;
7   import java.io.IOException;
8   import java.lang.reflect.InvocationTargetException;
9   import java.lang.reflect.Method;
10  import java.nio.charset.StandardCharsets;
11  import java.nio.file.Files;
12  import java.nio.file.Path;
13  import java.nio.file.Paths;
14  import java.util.ArrayList;
15  import java.util.HashMap;
16  import java.util.HashSet;
17  import java.util.List;
18  import java.util.Map;
19  import java.util.Set;
20  import java.util.TreeSet;
21  
22  import org.junit.Test;
23  
24  /**
25   * Verify that all localizations contain all keys.
26   * <p>
27   * @author <a href="https://www.tudelft.nl/p.knoppers">Peter Knoppers</a>
28   */
29  public class VerifyLocalizations
30  {
31  
32      /**
33       * Replace unicode escapes by the corresponding character. Based on
34       * https://stackoverflow.com/questions/37502058/replace-unicode-escapes-with-the-corresponding-character
35       * @param in String; the input string to process
36       * @return String the processed input string
37       */
38      static String fixUnicodeEscapes(final String in)
39      {
40          StringBuilder result = new StringBuilder();
41          for (int i = 0; i < in.length(); i++)
42          {
43              if (in.length() >= i + 6 && in.substring(i, i + 2).equals("\\u"))
44              {
45                  result.append(Character.toChars(Integer.parseInt(in.substring(i + 2, i + 6), 16)));
46                  i += 5;
47              }
48              else
49              {
50                  result.append(in.charAt(i));
51              }
52          }
53          return result.toString();
54      }
55  
56      /**
57       * Verify that all localizations have the same set of keys as the localeunit.properties file and check that a string using
58       * each of the acceptable unit names is correctly parsed.
59       * @throws IOException when a file could not be read
60       * @throws ClassNotFoundException ...
61       * @throws SecurityException ...
62       * @throws NoSuchMethodException ...
63       * @throws InvocationTargetException ...
64       * @throws IllegalArgumentException ...
65       * @throws IllegalAccessException ...
66       */
67      @Test
68      public void verifyLocalizations() throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException,
69              IllegalAccessException, IllegalArgumentException, InvocationTargetException
70      {
71          // TODO The way that this code finds the files may need fixing to work in the deploy environment.
72          String pathToResources = "src/main/resources";
73          String referenceFileName = "localeunit.properties";
74          // Parse the localeunit.properties file and store all the keys
75          List<String> reference =
76                  Files.readAllLines(Paths.get(pathToResources + "/" + referenceFileName), StandardCharsets.ISO_8859_1);
77          // Replace unicode escapes by the corresponding character
78          for (int index = 0; index < reference.size(); index++)
79          {
80              reference.set(index, fixUnicodeEscapes(reference.get(index)));
81          }
82          Map<String, Integer> keys = new HashMap<>();
83          Map<String, String> values = new HashMap<>();
84          for (int lineNo = 0; lineNo < reference.size(); lineNo++)
85          {
86              String line = reference.get(lineNo);
87              if (line.startsWith("#"))
88              {
89                  continue;
90              }
91              String[] parts = line.split("\\=");
92              assertTrue(referenceFileName + "(" + (lineNo + 1) + ") should contain a equals sign", parts.length > 1);
93              String key = parts[0].trim();
94              keys.put(parts[0].trim(), (lineNo + 1));
95              if (parts.length > 1)
96              {
97                  values.put(key, parts[1]);
98              }
99          }
100         System.out.println("Collected " + keys.size() + " keys from reference file " + referenceFileName);
101         System.out.println("Verifying that the valueOf method of each unit correctly parses all writing styles into a Scalar");
102         for (String key : new TreeSet<>(keys.keySet()))
103         {
104             int positionOfPoint = key.indexOf('.');
105             if (positionOfPoint < 0)
106             {
107                 continue;
108             }
109             String className = key.substring(0, positionOfPoint);
110             double testValue = 123.456;
111             String abbreviationsString = values.get(key);
112             String[] abbreviations = abbreviationsString.split("\\|");
113             for (int index = 0; index < abbreviations.length; index++)
114             {
115                 if (index == 1)
116                 {
117                     continue;
118                 }
119                 String input = testValue + " " + abbreviations[index].trim();
120                 System.out.print(String.format("%-30s: %-20s", key, input));
121                 Class<?> c = Class.forName("org.djunits.value.vdouble.scalar." + className);
122                 Method valueOf = c.getMethod("valueOf", String.class);
123                 Object result = valueOf.invoke(null, input);
124                 System.out.println(" got parsed into " + result);
125             }
126         }
127         List<Path> paths = new ArrayList<>();
128         Files.list(new File(pathToResources).toPath()).forEach(path -> paths.add(path));
129         for (Path path : paths)
130         {
131             // System.out.println(path);
132             if (path.getFileName().toString().startsWith("localeunit_")
133                     && path.getFileName().toString().endsWith(".properties"))
134             {
135                 System.out.println("Verifying locale file " + path.getFileName().toString());
136                 Set<String> missingKeys = new TreeSet<>(keys.keySet());
137                 Set<String> foundKeys = new HashSet<>();
138                 int lineNo = 0;
139                 int errors = 0;
140                 for (String line : Files.readAllLines(path, StandardCharsets.ISO_8859_1))
141                 {
142                     lineNo++;
143                     line = fixUnicodeEscapes(line);
144                     if (line.startsWith("#"))
145                     {
146                         continue;
147                     }
148                     String[] parts = line.split("\\=");
149                     if (parts.length < 2)
150                     {
151                         System.err.println(path.getFileName() + "(" + (lineNo) + ") does not contain an equals sign");
152                         errors++;
153                         continue;
154                     }
155                     String key = parts[0].trim();
156                     if (!keys.containsKey(key))
157                     {
158                         System.err.println(path.getFileName() + "(" + lineNo + "): key " + key + " is not a valid key");
159                         errors++;
160                     }
161                     if (foundKeys.contains(key))
162                     {
163                         System.err.println(path.getFileName() + "(" + lineNo + "): duplicate key " + key);
164                         errors++;
165                     }
166                     missingKeys.remove(key);
167                     foundKeys.add(key);
168                 }
169                 for (String key : missingKeys)
170                 {
171                     System.err.println("file " + path.getFileName() + " misses key " + key);
172                     errors++;
173                 }
174                 assertEquals("No errors in file " + path.getFileName(), 0, errors);
175             }
176         }
177     }
178 
179 }