]> git.basschouten.com Git - openhab-addons.git/blob
47b504b83a46f8b9d7a37876bd4569e81dd6a0e3
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.knx.internal.i18n;
14
15 import java.text.MessageFormat;
16 import java.util.Locale;
17
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;
24
25 /**
26  * This class provides translations. It is a helper class for i18n / localization efforts.
27  *
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
32  *
33  */
34 @NonNullByDefault
35 public enum KNXTranslationProvider {
36     I18N;
37
38     private @Nullable LocaleProvider localeProvider;
39     private @Nullable TranslationProvider translationProvider;
40     private Bundle bundle;
41
42     private KNXTranslationProvider() {
43         localeProvider = null;
44         translationProvider = null;
45         bundle = FrameworkUtil.getBundle(this.getClass());
46     }
47
48     /**
49      * get translated text
50      *
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
55      */
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);
65             if (res != null) {
66                 return res;
67             }
68         }
69         // translating not possible, we still have the original text without any subsititutions
70         if (arguments == null || arguments.length == 0) {
71             return text;
72         }
73         // else execute pattern substitution in untranslated text
74         return MessageFormat.format(text, arguments);
75     }
76
77     /**
78      * get exception in user readable (and possibly localized) form
79      *
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.
83      */
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();
92         if (detail == null) {
93             detail = "";
94         }
95
96         if (foundTranslation) {
97             res.append(translatedDescription);
98             res.append(" (");
99             res.append(exName);
100             if (!detail.isBlank()) {
101                 res.append(", ");
102                 res.append(detail);
103             }
104             res.append(")");
105         } else {
106             res.append(exName);
107             if (!detail.isBlank()) {
108                 res.append(", ");
109                 res.append(detail);
110             }
111         }
112         return res.toString();
113     }
114
115     /**
116      * Set translation providers. To be called to make any translation work.
117      *
118      * @param localeProvider openHAB locale provider, can be generated via \@Activate / \@Reference LocaleProvider in
119      *            handler factory
120      * @param translationProvider openHAB locale provider, can be generated via \@Activate / \@Reference
121      *            TranslationProvider in handler factory
122      */
123     public void setProvider(@Nullable LocaleProvider localeProvider,
124             @Nullable TranslationProvider translationProvider) {
125         this.localeProvider = localeProvider;
126         this.translationProvider = translationProvider;
127     }
128 }