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