2 * Copyright (c) 2010-2022 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.knx.internal.i18n;
15 import java.text.MessageFormat;
16 import java.util.Locale;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.core.i18n.LocaleProvider;
21 import org.openhab.core.i18n.TranslationProvider;
22 import org.osgi.framework.Bundle;
23 import org.osgi.framework.FrameworkUtil;
26 * This class provides translations. It is a helper class for i18n / localization efforts.
28 * @implNote It is implemented as a static singleton, enforced by the single-element enum pattern.
29 * @apiNote @set() must be called to provide tanslation service, otherwise all functions will return untranslated text.
30 * Thread safety is ensured.
31 * @author Holger Friedrich - Initial contribution
35 public enum KNXTranslationProvider {
38 private @Nullable LocaleProvider localeProvider;
39 private @Nullable TranslationProvider translationProvider;
40 private Bundle bundle;
42 private KNXTranslationProvider() {
43 localeProvider = null;
44 translationProvider = null;
45 bundle = FrameworkUtil.getBundle(this.getClass());
51 * @param text text to be translated, may contain placeholders \{n\} for the n-th optional argument of this function
52 * @param arguments any optional arguments, will be inserted
53 * @return translated text with subsitutions if translationprovide is set and provides a translation, otherwise
54 * returns original text with substitutions
56 public String get(final String text, @Nullable Object @Nullable... arguments) {
57 // ensure thread safety: calls to set(..) should not lead to race condition
58 final TranslationProvider translationProvider = this.translationProvider;
59 final LocaleProvider localeProvider = this.localeProvider;
60 if (translationProvider != null) {
61 // localeProvider might be null, but if not, getLocale will return NonNull Locale
62 // locale cannot be cached, as getLocale() will return different result once locale is changed by user
63 final Locale locale = (localeProvider != null) ? localeProvider.getLocale() : Locale.getDefault();
64 final String res = translationProvider.getText(bundle, text, text, locale, arguments);
69 // translating not possible, we still have the original text without any subsititutions
70 if (arguments == null || arguments.length == 0) {
73 // else execute pattern substitution in untranslated text
74 return MessageFormat.format(text, arguments);
78 * get exception in user readable (and possibly localized) form
80 * @param e any exception
81 * @return localized message in form <description (translated)> (<class name>, <e.getLocalizedMessage (not
82 * translated)>), empty string for null. May possibly change in further releases.
84 public String getLocalizedException(final Throwable e) {
85 StringBuffer res = new StringBuffer();
86 final String exName = e.getClass().getSimpleName();
87 final String key = "exception." + exName;
88 final String translatedDescription = KNXTranslationProvider.I18N.get(key);
89 Boolean foundTranslation = !key.equals(translatedDescription);
90 // detailed message cannot be translated, e.getLocalizedMessage will likely return English
91 String detail = e.getLocalizedMessage();
96 if (foundTranslation) {
97 res.append(translatedDescription);
100 if (!detail.isBlank()) {
107 if (!detail.isBlank()) {
112 return res.toString();
116 * Set translation providers. To be called to make any translation work.
118 * @param localeProvider openHAB locale provider, can be generated via \@Activate / \@Reference LocaleProvider in
120 * @param translationProvider openHAB locale provider, can be generated via \@Activate / \@Reference
121 * TranslationProvider in handler factory
123 public void setProvider(@Nullable LocaleProvider localeProvider,
124 @Nullable TranslationProvider translationProvider) {
125 this.localeProvider = localeProvider;
126 this.translationProvider = translationProvider;