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 }