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 }