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