From 4ba33abd9104d715c6e3f53c1d2b23398cc196d6 Mon Sep 17 00:00:00 2001
From: Kai Reinhard <K.Reinhard@micromata.de>
Date: Sun, 09 Dec 2018 22:20:07 +0000
Subject: [PATCH] web...
---
borgbutler-server/src/main/java/de/micromata/borgbutler/server/ServerConfiguration.java | 2
borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle.properties | 88 +++++++++++
borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/I18nRest.java | 7
borgbutler-core/src/main/java/de/micromata/borgbutler/I18n.java | 109 +++++++++++++
borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle_de.properties | 88 +++++++++++
borgbutler-webapp/src/components/views/Start.jsx | 8
borgbutler-server/src/main/java/de/micromata/borgbutler/server/I18nClientMessages.java | 55 ++++++
borgbutler-core/src/main/resources/BorgButlerCoreMessagesBundle.properties | 1
borgbutler-core/src/main/java/de/micromata/borgbutler/CoreI18n.java | 84 ++++++++++
9 files changed, 436 insertions(+), 6 deletions(-)
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/CoreI18n.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/CoreI18n.java
new file mode 100644
index 0000000..4c1d7d4
--- /dev/null
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/CoreI18n.java
@@ -0,0 +1,84 @@
+package de.micromata.borgbutler;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+/**
+ * For internationalization.
+ */
+public class CoreI18n extends I18n {
+ private static Logger log = LoggerFactory.getLogger(CoreI18n.class);
+ private static Locale[] DEFAULT_LOCALES = {Locale.ROOT, Locale.GERMAN};
+
+ private static CoreI18n defaultInstance = new CoreI18n();
+ public static final String BUNDLE_NAME = "BorgButlerCoreMessagesBundle";
+ private static List<I18n> allResourceBundles = new ArrayList<>();
+
+ public static CoreI18n getDefault() {
+ return defaultInstance;
+ }
+
+ /**
+ * Use this if only one locale is used (in a none multi user system).
+ * At default the default message bundle "MessagesBundle" of the class path with the system's default locale is used.
+ *
+ * @param instance
+ */
+ public static void setDefault(CoreI18n instance) {
+ defaultInstance = instance;
+ }
+
+ /**
+ * Use this if only one locale is used (in a none multi user system).
+ * Uses bundle "MessagesBundle" of the class path with the given locale.
+ *
+ * @param locale
+ * @return new default instance for chaining.
+ */
+ public static CoreI18n setDefault(Locale locale) {
+ defaultInstance = new CoreI18n(locale);
+ return defaultInstance;
+ }
+
+ public static Set<String> getAllTranslations(String key) {
+ Set<String> set = new HashSet<>();
+ for (I18n i18n : getAllResourceBundles()) {
+ String translation = i18n.getMessage(key);
+ if (StringUtils.isNotBlank(translation))
+ set.add(translation);
+ }
+ return set;
+ }
+
+ private static List<I18n> getAllResourceBundles() {
+ if (!allResourceBundles.isEmpty()) {
+ return allResourceBundles;
+ }
+ synchronized (allResourceBundles) {
+ for (Locale locale : DEFAULT_LOCALES) {
+ allResourceBundles.add(new CoreI18n(locale));
+ }
+ }
+ return allResourceBundles;
+ }
+
+ /**
+ * Uses the default message bundle "MessagesBundle" of class path with systems default locale.
+ */
+ public CoreI18n() {
+ super(BUNDLE_NAME);
+ }
+
+ public CoreI18n(Locale locale) {
+ super(BUNDLE_NAME, locale);
+ }
+
+ @Override
+ protected I18n create(Locale locale) {
+ return new CoreI18n(locale);
+ }
+
+}
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/I18n.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/I18n.java
new file mode 100644
index 0000000..7d797cf
--- /dev/null
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/I18n.java
@@ -0,0 +1,109 @@
+package de.micromata.borgbutler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.MessageFormat;
+import java.util.*;
+
+/**
+ * For internationalization.
+ */
+public class I18n {
+ private Logger log = LoggerFactory.getLogger(I18n.class);
+ private ResourceBundle resourceBundle;
+ private Map<Locale, I18n> i18nMap;
+
+ public I18n get(Locale locale) {
+ if (i18nMap == null) {
+ i18nMap = new HashMap<>();
+ }
+ I18n i18n = i18nMap.get(locale);
+ if (i18n == null) {
+ i18n = create(locale);
+ i18nMap.put(locale, i18n);
+ }
+ return i18n;
+ }
+
+ protected I18n create(Locale locale) {
+ return new I18n(this.resourceBundle.getBaseBundleName(), locale);
+ }
+
+ /**
+ * Uses the default message bundle "MessagesBundle" of class path with systems default locale.
+ */
+ public I18n(String bundleName) {
+ this.resourceBundle = I18n.getBundle(bundleName);
+ }
+
+ public I18n(String bundleName, Locale locale) {
+ this.resourceBundle = I18n.getBundle(bundleName, locale);
+ }
+
+ /**
+ * Throws an error if messageId not found.
+ *
+ * @param messageId
+ * @return localized message.
+ */
+ public String getMessage(String messageId) {
+ return resourceBundle.getString(messageId);
+ }
+
+ /**
+ * @param messageId
+ * @return true, if the messageId is found in the bundle, otherwise false.
+ */
+ public boolean containsMessage(String messageId) {
+ return resourceBundle.containsKey(messageId);
+ }
+
+ /**
+ * @param messageId
+ * @param params Message parameter to replace in message.
+ * @return localized message.
+ * @see MessageFormat#format(String, Object...)
+ */
+ public String formatMessage(String messageId, Object... params) {
+ if (params == null || params.length == 0) {
+ return getMessage(messageId);
+ }
+ try {
+ return MessageFormat.format(resourceBundle.getString(messageId), params);
+ } catch (MissingResourceException ex) {
+ log.error("Missing resource '" + messageId + "': " + ex.getMessage(), ex);
+ return messageId;
+ }
+ }
+
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+
+ /**
+ *
+ * @param bundleName
+ * @param locale
+ * @return The root bundle if the given locale's language is "en" or language not found, otherwise the desired bundle for the given locale.
+ */
+ public static ResourceBundle getBundle(String bundleName, Locale locale) {
+ if ("en".equals(locale.getLanguage())) {
+ return ResourceBundle.getBundle(bundleName, Locale.ROOT);
+ }
+ return ResourceBundle.getBundle(bundleName, locale);
+ //return ResourceBundle.getBundle(bundleName, locale,
+ // ResourceBundle.Control.getNoFallbackControl(ResourceBundle.Control.FORMAT_PROPERTIES));
+ }
+
+ /**
+ * Simply calls {@link ResourceBundle#getBundle(String)}.
+ * @param bundleName
+ * @return The bundle for {@link Locale#getDefault()} or root bundle if not found..
+ */
+ public static ResourceBundle getBundle(String bundleName) {
+ return ResourceBundle.getBundle(bundleName);
+ //return ResourceBundle.getBundle(bundleName, locale,
+ // ResourceBundle.Control.getNoFallbackControl(ResourceBundle.Control.FORMAT_PROPERTIES));
+ }
+}
diff --git a/borgbutler-core/src/main/resources/BorgButlerCoreMessagesBundle.properties b/borgbutler-core/src/main/resources/BorgButlerCoreMessagesBundle.properties
new file mode 100644
index 0000000..0716330
--- /dev/null
+++ b/borgbutler-core/src/main/resources/BorgButlerCoreMessagesBundle.properties
@@ -0,0 +1 @@
+# Prepared for i18n.
\ No newline at end of file
diff --git a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/I18nClientMessages.java b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/I18nClientMessages.java
new file mode 100644
index 0000000..60692bd
--- /dev/null
+++ b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/I18nClientMessages.java
@@ -0,0 +1,55 @@
+package de.micromata.borgbutler.server;
+
+import de.micromata.borgbutler.CoreI18n;
+import de.micromata.borgbutler.I18n;
+
+import java.text.MessageFormat;
+import java.util.*;
+
+/**
+ * For internationalization.
+ */
+public class I18nClientMessages {
+ private static final String BUNDLE_NAME = "BorgButlerClientMessagesBundle";
+ private static String[] params = {"{0}", "{1}", "{2}", "{3}", "{4}", "{5}", "{6}", "{7}", "{8}", "{9}"};
+ private static final I18nClientMessages instance = new I18nClientMessages();
+
+ public static I18nClientMessages getInstance() {
+ return instance;
+ }
+
+ private I18nClientMessages() {
+ }
+
+ /**
+ *
+ * @param locale
+ * @param keysOnly If true, only the keys will be returned. Default is false.
+ * @return
+ */
+ public Map<String, String> getAllMessages(Locale locale, boolean keysOnly) {
+ Map<String, String> map = new HashMap<>();
+ //addAllMessages(map, new AppI18n(locale).getResourceBundle(), keysOnly);
+ addAllMessages(map, new CoreI18n(locale).getResourceBundle(), keysOnly);
+ ResourceBundle bundle = I18n.getBundle(BUNDLE_NAME, locale);
+ addAllMessages(map, bundle, keysOnly);
+ return new TreeMap<>(map); // Sorted by keys.
+ }
+
+ private Map<String, String> addAllMessages(Map<String, String> map, ResourceBundle bundle, boolean keysOnly) {
+ for (String key : bundle.keySet()) {
+ String value = bundle.getString(key);
+ map.put(key, keysOnly ? "" : prepareForReactClient(value));
+ }
+ return map;
+ }
+
+ /**
+ * @param str
+ * @return
+ * @see MessageFormat#format(Object)
+ */
+ static String prepareForReactClient(String str) {
+ return MessageFormat.format(str, (Object[])params);
+ }
+}
diff --git a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/ServerConfiguration.java b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/ServerConfiguration.java
index 3d2023b..53c01d6 100644
--- a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/ServerConfiguration.java
+++ b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/ServerConfiguration.java
@@ -8,7 +8,7 @@
public class ServerConfiguration {
private static Logger log = LoggerFactory.getLogger(ServerConfiguration.class);
- private final static String[] SUPPORTED_LANGUAGES = {"en"};
+ private final static String[] SUPPORTED_LANGUAGES = {"en", "de"};
private static String applicationHome;
private int port;
diff --git a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/I18nRest.java b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/I18nRest.java
index f71cb84..7e060d6 100644
--- a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/I18nRest.java
+++ b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/I18nRest.java
@@ -1,5 +1,7 @@
package de.micromata.borgbutler.server.rest;
+import de.micromata.borgbutler.json.JsonUtils;
+import de.micromata.borgbutler.server.I18nClientMessages;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -12,6 +14,7 @@
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.util.Locale;
+import java.util.Map;
@Path("/i18n")
public class I18nRest {
@@ -36,6 +39,8 @@
} else {
localeObject = RestUtils.getUserLocale(requestContext);
}
- return ""; // i18n not yet supported.
+ Map<String, String> translations = I18nClientMessages.getInstance().getAllMessages(localeObject, keysOnly);
+ String json = JsonUtils.toJson(translations, prettyPrinter);
+ return json;
}
}
diff --git a/borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle.properties b/borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle.properties
new file mode 100644
index 0000000..8ce4d6b
--- /dev/null
+++ b/borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle.properties
@@ -0,0 +1,88 @@
+common.browse=Browse
+common.browse.hint=Browse local filesystem
+common.cancel=Cancel
+common.comment=Comment
+common.common=Common
+common.description=Description
+common.droparea.title=Select a file or drop one here.
+common.droparea.hint=Drop or open your files here, such as serial definition files (Excel).
+common.filename=File name
+common.fileSize=File size
+common.information=Information
+common.lastModified=Last modified
+common.limitsResultSize=Limits result size.
+common.loading=Loading...
+common.new=New
+common.none=none
+common.required=Required
+common.path=Path
+common.run=Run
+common.save=Save
+common.unique=Unique
+common.update=Update
+common.alert.cantLoadData=Can't load data
+common.alert.genericRestAPIFailure=Something went wrong with the server call. Is the server available?
+common.alert.tryAgain=Try again
+
+configuration=Configuration
+configuration.account=Account
+configuration.addDirectory=Add directory
+configuration.addDirectory.hint=Add new template directory.
+configuration.application.dateFormat=Date format
+configuration.application.dateFormat.option.auto=Auto
+configuration.application.language=Application language
+configuration.application.language.option.default=Default (browser)
+configuration.cancel.hint=Discard changes and go to Start page.
+configuration.expertSettings=Expert settings
+configuration.forExpertsOnly=For experts only
+configuration.reloadDictionary.hint=Force reloading all translations for this app.
+configuration.removeItem=Remove item
+configuration.resetAllSettings=Reset all settings
+configuration.resetAllSettings.question=Are you sure you want to reset all settings? All settings will be resetted on server. Template files will not be deleted.
+configuration.resetAllSettings.hint=Reset factory settings.
+configuration.save.hint=Save changes and go to Start page.
+configuration.server=Server
+configuration.showTestData=Show test data
+configuration.templatesDirectory=Directory
+configuration.webDevelopmentMode=Web development
+configuration.webDevelopmentMode.hint=Activate this checkbox only for web development of BorgButler (with yarn or npm). The CrossOriginFilter will be set. A restart of BorgButler is required.
+
+language.english=English
+language.german=German
+
+logviewer=Log viewer
+logviewer.filter=Filter
+logviewer.filter.level.hint=Minimum displayed log level.
+logviewer.filter.location.hint=Show location of message in source code.
+logviewer.filter.location.option.short=short
+logviewer.filter.location.option.normal=long
+logviewer.filter.stacktraces=Stacktraces
+logviewer.filter.stacktraces.showHide.hint=Show/hide stack traces.
+logviewer.level=Level
+logviewer.location=Location in source code
+logviewer.message=Message
+logviewer.timestamp=Timestamp
+
+startscreen.welcome.title=Welcome to BorgButler
+startscreen.welcome.text=Congratulations. With BorgButler you have started a smart assistant for your work with borg backups.
+startscreen.welcome.enjoy=Enjoy your work!
+startscreen.welcome.documentation=Go to Documentation
+
+update=Update
+update.installerUrl=Installer url
+update.newVersion=New version
+update.newVersionAvailable=The new version {0} is available.
+update.newVersion.simplyClickButton=You can start the update process by simply clicking the update button.
+update.noUpdateAvailable=No update available.
+update.update.button.hint=Download and execute update.
+update.description.line1=The update button works only if your browser is running on the same computer as your BorgBackup server.
+update.description.line2=If the installer doesn't start after clicking the update button, please proceed manually by downloading the installer from the given url below.
+
+validation.requiredField=Value is required. Please insert a value.
+validation.numberExpected=Value must be a number.
+validation.numberMustBeLower=The number can't be higher than {0}.
+validation.numberMustBeHigher=The number can't be lower than {0}.
+
+version=Version
+version.buildDate=Build date
+version.updateAvailable=Update available!
diff --git a/borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle_de.properties b/borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle_de.properties
new file mode 100644
index 0000000..ac02000
--- /dev/null
+++ b/borgbutler-server/src/main/resources/BorgButlerClientMessagesBundle_de.properties
@@ -0,0 +1,88 @@
+common.browse=Browse
+common.browse.hint=Öffne lokales Dateisystem
+common.cancel=Abbrechen
+common.comment=Kommentar
+common.common=Allgemein
+common.description=Beschreibung
+common.droparea.title=Datei hierhin ziehen oder auswählen.
+common.droparea.hint=Ziehen Sie Ihre Dateien hierhin, wie beispielsweise Seriendefinitionen(Excel).
+common.filename=Dateiname
+common.fileSize=Dateigröße
+common.information=Information
+common.lastModified=Letzte Änderung
+common.limitsResultSize=Ergebnisliste begrenzen.
+common.loading=Lädt gerade...
+common.new=Neu
+common.none=keine
+common.required=Erforderlich
+common.path=Pfad
+common.run=Ausführen
+common.save=Speichern
+common.unique=Eindeuting
+common.update=Aktualisieren
+common.alert.cantLoadData=Fehler beim Laden von Daten
+common.alert.genericRestAPIFailure=Ein allgemeiner Fehler ist beim Serveraufruf aufgetreten. Ist der Server erreichbar?
+common.alert.tryAgain=Erneut probieren
+
+configuration=Konfiguration
+configuration.account=Zugang
+configuration.addDirectory=Verzeichnis hinzufügen
+configuration.addDirectory.hint=Ein neues Template-Verzeichnis hinzufügen.
+configuration.application.dateFormat=Datumsformat
+configuration.application.dateFormat.option.auto=Automatisch
+configuration.application.language=Anwendungssprache
+configuration.application.language.option.default=Standard (Browser)
+configuration.cancel.hint=Änderungen verwerfen und zur Startseite.
+configuration.expertSettings=Experteneinstellungen
+configuration.forExpertsOnly=Nur für Experten
+configuration.reloadDictionary.hint=Erzwingt das Neuladen aller Übersetzungstexte dieser Anwendung.
+configuration.removeItem=Eintrag entfernen
+configuration.resetAllSettings=Alles zurücksetzen
+configuration.resetAllSettings.question=Sind Sie sich wirklich sicher, dass Sie alle Einstellungen zurücksetzen wollen? Alle Einstellungen werden auf dem Server zurückgesetzt. Templatedateien werden nicht gelöscht.
+configuration.resetAllSettings.hint=Alle Einstellungen zurücksetzen.
+configuration.save.hint=Änderungen speichern und zur Startseite.
+configuration.server=Server
+configuration.showTestData=Testdaten anzeigen
+configuration.templatesDirectory=Verzeichnis
+configuration.webDevelopmentMode=Webentwicklung
+configuration.webDevelopmentMode.hint=Aktivieren Sie diese Funktion nur, wenn Sie die Webentwicklung für BorgButler durchführen (yarn oder npm). Der CrossOriginFilter wird hierüber aktiviert. Ein Neustart von BorgButler ist erforderlich.
+
+language.english=Englisch
+language.german=Deutsch
+
+logviewer=Protokolldateien
+logviewer.filter=Filter
+logviewer.filter.level.hint=Zeige nur Meldungen ab diesem Level.
+logviewer.filter.location.hint=Zeige den Ort der Meldung im Quellcode.
+logviewer.filter.location.option.short=kurz
+logviewer.filter.location.option.normal=lang
+logviewer.filter.stacktraces=Stacktraces
+logviewer.filter.stacktraces.showHide.hint=Zeige/verstecke Stacktraces.
+logviewer.level=Level
+logviewer.location=Stelle im Quellcode
+logviewer.message=Meldung
+logviewer.timestamp=Zeitstempel
+
+startscreen.welcome.title=Willkommen zu BorgButler
+startscreen.welcome.text=Herzlichen Glückwunsch. Mit BorgButler haben Sie einen smarten Assistenten für Ihre tägliche Arbeit mit Borg-Backups gestartet.
+startscreen.welcome.enjoy=Viel Spaß!
+startscreen.welcome.documentation=Gehe zur Dokumentation
+
+update=Aktualisierung
+update.installerUrl=Webadresse Installation
+update.newVersion=Neue Version
+update.newVersionAvailable=Die neue Version {0} ist verfügbar.
+update.newVersion.simplyClickButton=Sie können die Aktualisierung auf Knopfdruck automatisch starten.
+update.noUpdateAvailable=Keine Aktualisierung verfügbar.
+update.update.button.hint=Aktualisierung herunterladen und ausführen.
+update.description.line1=Der Aktualisierungsknopf funktioniert nur, wenn Ihr Browser auf dem gleichen Computer läuft wie der BorgButler-Server.
+update.description.line2=Wenn das Installationsprogramm nicht auf Knopfdruck startet, fahren Sie bitte mit dem manuellen Download von der unten angegebenen Webadresse fort.
+
+validation.requiredField=Der Wert ist erforderlich. Bitte geben Sie einen Wert ein.
+validation.numberExpected=Der Wert muss eine Zahl sein.
+validation.numberMustBeLower=Die Zahl muss kleiner als {0} sein.
+validation.numberMustBeHigher=Die Zahl muss größer als {0} sein.
+
+version=Version
+version.buildDate=Erzeugt am
+version.updateAvailable=Aktualisierung verfügbar!
diff --git a/borgbutler-webapp/src/components/views/Start.jsx b/borgbutler-webapp/src/components/views/Start.jsx
index c058232..ef337ee 100644
--- a/borgbutler-webapp/src/components/views/Start.jsx
+++ b/borgbutler-webapp/src/components/views/Start.jsx
@@ -7,11 +7,11 @@
return (
<React.Fragment>
<PageHeader>
- Welcome to BorgButler
+ <I18n name={'startscreen.welcome.title'}/>
</PageHeader>
- <div className="welcome-intro">BorgButler is the frontend for BorgBackup.</div>
- <div className="welcome-enjoy">Enjoy your work with BorgButler.</div>
- <div className="welcome-documentation-link"><a className={'btn btn-link btn-outline-primary'} href={'https://github.com/micromata/borgbackup-butler'} target="_blank" rel="noopener noreferrer">Documentation</a></div>
+ <div className="welcome-intro"><I18n name={'startscreen.welcome.text'}/></div>
+ <div className="welcome-enjoy"><I18n name={'startscreen.welcome.enjoy'}/></div>
+ <div className="welcome-documentation-link"><a className={'btn btn-link btn-outline-primary'} href={'https://github.com/micromata/borgbackup-butler'} target="_blank" rel="noopener noreferrer"><I18n name={'startscreen.welcome.documentation'}/></a></div>
</React.Fragment>
);
}
--
Gitblit v1.10.0