View Javadoc
1   package com.jsql.util;
2   
3   import com.jsql.model.exception.JSqlRuntimeException;
4   import org.apache.commons.lang3.StringUtils;
5   import org.apache.logging.log4j.LogManager;
6   import org.apache.logging.log4j.Logger;
7   import org.apache.logging.log4j.util.Strings;
8   
9   import java.io.IOException;
10  import java.io.InputStream;
11  import java.io.StringReader;
12  import java.math.BigDecimal;
13  import java.math.RoundingMode;
14  import java.nio.charset.StandardCharsets;
15  import java.util.Arrays;
16  import java.util.Locale;
17  import java.util.Properties;
18  import java.util.concurrent.atomic.AtomicInteger;
19  import java.util.regex.Matcher;
20  import java.util.regex.Pattern;
21  
22  public class PropertiesUtil {
23      
24      private static final Logger LOGGER = LogManager.getRootLogger();
25  
26      private final Properties properties = new Properties();
27  
28      public PropertiesUtil() {
29          var filename = "config.properties";
30          try (InputStream input = PropertiesUtil.class.getClassLoader().getResourceAsStream(filename)) {
31              if (input == null) {
32                  LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Properties file {} not found", filename);
33                  return;
34              }
35              this.properties.load(input);  // load a properties file from class path, inside static method
36          } catch (IOException e) {
37              LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
38          }
39      }
40  
41      public void displayI18nStatus(Locale newLocale) {
42          if (!Arrays.asList(StringUtils.EMPTY, "en").contains(newLocale.getLanguage())) {
43              AtomicInteger countGui = new AtomicInteger();
44              var bundleRoot = PropertiesUtil.getProperties("/i18n/jsql.properties");
45              // fall working as uppercase regional matches lowercase bundle (eg. es_AN)
46              var bundleUser = PropertiesUtil.getProperties("/i18n/jsql_" + newLocale.getLanguage() + ".properties");
47              bundleRoot.entrySet().stream().filter(
48                  key -> bundleUser.isEmpty() || !bundleUser.containsKey(key.getKey())
49              ).forEach(
50                  key -> countGui.getAndIncrement()
51              );
52              if (countGui.get() > 0) {
53                  LOGGER.log(
54                      LogLevelUtil.CONSOLE_SUCCESS,
55                      "Switched to {}{} with {}% translated, contribute and translate any of remaining {} items in menu Community",
56                      () -> newLocale.getDisplayLanguage(newLocale),
57                      () -> Strings.isBlank(newLocale.getCountry()) ? StringUtils.EMPTY : " ("+ newLocale.getCountry() +")",  // should be nameEnglish from Language
58                      () -> BigDecimal.valueOf(
59                          100.0 - countGui.get() * 100.0 / bundleRoot.size()
60                      ).setScale(1, RoundingMode.HALF_UP).doubleValue(),
61                      countGui::get
62                  );
63              }
64          }
65      }
66  
67      private static Properties getProperties(String name) {
68          var properties = new Properties();
69          try (InputStream in = PropertiesUtil.class.getResourceAsStream(name)) {  // do not use path as resources in .jar may not be files
70              if (in != null) {
71                  byte[] root = in.readAllBytes(); // usable in Java 9+
72                  var rootI18n = new String(root, StandardCharsets.UTF_8);
73                  String rootI18nFixed = Pattern.compile("\\\\[\n\r]+")
74                      .matcher(Matcher.quoteReplacement(rootI18n))
75                      .replaceAll("a");
76                  properties.load(new StringReader(rootI18nFixed));
77              } else {
78                  throw new JSqlRuntimeException("Resource not found: "+ name);
79              }
80          } catch (IOException e) {
81              throw new JSqlRuntimeException(e);
82          }
83          return properties;
84      }
85  
86      public String getVersionJsql() {
87          return this.properties.getProperty("jsql.version");
88      }
89  
90      public String getProperty(String property) {
91          return this.properties.getProperty(property);
92      }
93  }