View Javadoc
1   package com.jsql.view.swing.dialog.translate;
2   
3   import com.jsql.util.ConnectionUtil;
4   import com.jsql.util.I18nUtil;
5   import com.jsql.util.LogLevelUtil;
6   import com.jsql.util.PropertiesUtil;
7   import com.jsql.view.swing.dialog.DialogTranslate;
8   import com.jsql.view.swing.util.MediatorHelper;
9   import org.apache.commons.lang3.StringUtils;
10  import org.apache.logging.log4j.LogManager;
11  import org.apache.logging.log4j.Logger;
12  import org.apache.logging.log4j.util.Strings;
13  
14  import javax.swing.*;
15  import java.io.IOException;
16  import java.io.StringReader;
17  import java.math.BigDecimal;
18  import java.math.RoundingMode;
19  import java.net.URISyntaxException;
20  import java.nio.charset.StandardCharsets;
21  import java.nio.file.Files;
22  import java.nio.file.Paths;
23  import java.util.Locale;
24  import java.util.Properties;
25  import java.util.ResourceBundle;
26  import java.util.regex.Matcher;
27  import java.util.regex.Pattern;
28  
29  public class WorkerTranslateInto extends SwingWorker<Object, Object> {
30      
31      private static final Logger LOGGER = LogManager.getRootLogger();
32      
33      private final Properties propertiesLanguageToTranslate = new Properties();
34      private final SortedProperties propertiesRoot = new SortedProperties();
35      private final StringBuilder propertiesToTranslate = new StringBuilder();
36      private final DialogTranslate dialogTranslate;
37      
38      private final ConnectionUtil connectionUtil = MediatorHelper.model().getMediatorUtils().connectionUtil();
39      private final PropertiesUtil propertiesUtil = MediatorHelper.model().getMediatorUtils().propertiesUtil();
40      
41      private static final String LINE_FEED_ESCAPE = "{@|@}";
42      private static final String LINE_FEED = "\\\\[\n\r]+";
43      
44      public WorkerTranslateInto(DialogTranslate dialogTranslate) {
45          this.dialogTranslate = dialogTranslate;
46      }
47  
48      @Override
49      protected Object doInBackground() throws Exception {
50          Thread.currentThread().setName("SwingWorkerDialogTranslate");
51          this.dialogTranslate.getProgressBarTranslation().setVisible(this.dialogTranslate.getLanguageInto() != Language.OT);
52          try {
53              this.loadFromGithub();
54          } catch (IOException eGithub) {
55              this.logFileNotFound(eGithub);
56          } finally {
57              this.displayDiff();
58          }
59          var localeInto = Locale.forLanguageTag(this.dialogTranslate.getLanguageInto().getLanguageTag());
60          LOGGER.log(
61              LogLevelUtil.CONSOLE_SUCCESS,
62              "Remaining text to translate into {}{} loaded, send any part translated to contribute",
63              () -> localeInto.getDisplayLanguage(localeInto),
64              () -> Strings.isBlank(localeInto.getCountry()) ? StringUtils.EMPTY : " ("+ localeInto.getCountry() +")"
65          );
66          return null;
67      }
68  
69      private void displayDiff() {
70          this.propertiesRoot.entrySet().stream()
71              .filter(key ->
72                  this.dialogTranslate.getLanguageInto() == Language.OT
73                  || this.propertiesLanguageToTranslate.isEmpty()
74                  || !this.propertiesLanguageToTranslate.containsKey(key.getKey())
75              )
76              .forEach(key -> this.propertiesToTranslate.append(
77                  String.format("%n%n%s=%s", key.getKey(), key.getValue().toString().replace(WorkerTranslateInto.LINE_FEED_ESCAPE,"\\\n"))
78              ));
79          
80          this.dialogTranslate.setTextBeforeChange(this.propertiesToTranslate.toString().trim());
81          this.dialogTranslate.getButtonSend().setEnabled(true);
82          this.dialogTranslate.getTextToTranslate().setText(this.dialogTranslate.getTextBeforeChange());
83          this.dialogTranslate.getTextToTranslate().setCaretPosition(0);
84          this.dialogTranslate.getTextToTranslate().setEditable(true);
85          if (this.dialogTranslate.getLanguageInto() != Language.OT) {
86              double percentTranslated = 100.0 * this.propertiesLanguageToTranslate.size() / this.propertiesRoot.size();
87              this.dialogTranslate.getProgressBarTranslation().setValue((int) percentTranslated);
88  
89              var bundleInto = ResourceBundle.getBundle(I18nUtil.BASE_NAME, Locale.forLanguageTag(this.dialogTranslate.getLanguageInto().getLanguageTag()));
90              var localeInto = Locale.forLanguageTag(this.dialogTranslate.getLanguageInto().getLanguageTag());
91              this.dialogTranslate.getProgressBarTranslation().setString(
92                  String.format(
93                      "%s%% %s %s",
94                      BigDecimal.valueOf(percentTranslated).setScale(1, RoundingMode.HALF_UP).doubleValue(),
95                      bundleInto.getString("TRANSLATION_PROGRESS"),
96                      localeInto.getDisplayLanguage(localeInto)
97                  )
98              );
99          }
100     }
101 
102     private void loadFromGithub() throws IOException, URISyntaxException {
103         this.loadRootFromGithub();
104         if (this.dialogTranslate.getLanguageInto() != Language.OT) {
105             this.loadLanguageFromGithub();
106         }
107     }
108 
109     private void logFileNotFound(IOException e) throws IOException {
110         if (this.propertiesLanguageToTranslate.isEmpty()) {
111             LOGGER.log(LogLevelUtil.CONSOLE_INFORM, () -> I18nUtil.valueByKey("LOG_I18N_TEXT_NOT_FOUND"), e);
112         } else if (this.propertiesRoot.isEmpty()) {
113             throw new IOException("Reference language not found");
114         }
115     }
116     
117     private void loadRootFromGithub() throws IOException, URISyntaxException {
118         try {
119             String pageSourceRoot = this.connectionUtil.getSourceLineFeed(
120                 this.propertiesUtil.getProperty("github.webservice.i18n.root")
121             );
122             String pageSourceRootFixed = Pattern.compile(WorkerTranslateInto.LINE_FEED).matcher(Matcher.quoteReplacement(pageSourceRoot)).replaceAll(WorkerTranslateInto.LINE_FEED_ESCAPE);
123             this.propertiesRoot.load(new StringReader(pageSourceRootFixed));
124         } catch (IOException e) {
125             var uri = ClassLoader.getSystemResource("i18n/jsql.properties").toURI();
126             var path = Paths.get(uri);
127             byte[] root = Files.readAllBytes(path);
128             var rootI18n = new String(root, StandardCharsets.UTF_8);
129             String rootI18nFixed = Pattern.compile(WorkerTranslateInto.LINE_FEED).matcher(Matcher.quoteReplacement(rootI18n)).replaceAll(WorkerTranslateInto.LINE_FEED_ESCAPE);
130             this.propertiesRoot.load(new StringReader(rootI18nFixed));
131             LOGGER.log(LogLevelUtil.CONSOLE_INFORM, "Reference language loaded from local");
132             LOGGER.log(LogLevelUtil.IGNORE, e);
133         }
134     }
135     
136     private void loadLanguageFromGithub() throws IOException, URISyntaxException {
137         try {
138             String pageSourceLanguage = this.connectionUtil.getSourceLineFeed(
139                 String.format(
140                     "%sjsql_%s.properties",
141                     this.propertiesUtil.getProperty("github.webservice.i18n.locale"),
142                     this.dialogTranslate.getLanguageInto().getLanguageTag().replace("-", "_")  // for regional languages
143                 )
144             );
145             this.propertiesLanguageToTranslate.load(new StringReader(pageSourceLanguage));
146         } catch (IOException e) {
147             var uri = ClassLoader.getSystemResource(
148                 String.format(
149                     "i18n/jsql_%s.properties",
150                     this.dialogTranslate.getLanguageInto().getLanguageTag().replace("-", "_")  // for regional languages
151                 )
152             ).toURI();
153             
154             var path = Paths.get(uri);
155             byte[] root = Files.readAllBytes(path);
156             var localeI18n = new String(root, StandardCharsets.UTF_8);
157             String localeI18nFixed = Pattern.compile(WorkerTranslateInto.LINE_FEED).matcher(localeI18n).replaceAll(WorkerTranslateInto.LINE_FEED_ESCAPE);
158             
159             this.propertiesLanguageToTranslate.load(new StringReader(localeI18nFixed));
160             LOGGER.log(
161                 LogLevelUtil.CONSOLE_INFORM,
162                 String.format("GitHub failure, %s translation loaded from local", this.dialogTranslate.getLanguageInto())
163             );
164             LOGGER.log(LogLevelUtil.IGNORE, e);
165         }
166     }
167 }