blob: c7aecca64049e51baa0f27de29077bdf4f6e316a [file] [log] [blame]
Simon Hunt0c85f112017-06-12 21:02:17 -07001/*
2 * Copyright 2017-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.onosproject.ui.lion;
19
Simon Hunt7379a3d2017-06-20 16:50:39 -070020import com.google.common.collect.ImmutableList;
21import org.onosproject.ui.lion.stitch.BundleStitcher;
Simon Huntb8042032017-06-13 15:03:23 -070022import org.slf4j.Logger;
23import org.slf4j.LoggerFactory;
24
Simon Hunt7379a3d2017-06-20 16:50:39 -070025import java.util.ArrayList;
26import java.util.List;
Simon Huntb8042032017-06-13 15:03:23 -070027import java.util.Locale;
Simon Hunt0c85f112017-06-12 21:02:17 -070028import java.util.ResourceBundle;
Simon Huntb8042032017-06-13 15:03:23 -070029import java.util.Set;
Simon Hunt0c85f112017-06-12 21:02:17 -070030
31/**
32 * Utility methods for dealing with Localization Bundles etc.
33 */
34public final class LionUtils {
35
Simon Huntb8042032017-06-13 15:03:23 -070036 private static final Logger log = LoggerFactory.getLogger(LionUtils.class);
37
38 private static final String USER_LANGUAGE = "user.language";
39 private static final String USER_COUNTRY = "user.country";
40 private static final String ONOS_LOCALE = "ONOS_LOCALE";
41 private static final String EMPTY = "";
Simon Hunt0c85f112017-06-12 21:02:17 -070042 private static final String DOT = ".";
Simon Huntb8042032017-06-13 15:03:23 -070043 private static final String LOBAR = "_";
Simon Hunt0c85f112017-06-12 21:02:17 -070044
45 // no instantiation
46 private LionUtils() {
47 }
48
49 /**
Simon Huntb8042032017-06-13 15:03:23 -070050 * Parses the given string into language and country codes, and returns
51 * a {@link Locale} instance initialized with those parameters.
52 * For example:
53 * <pre>
54 * Locale locale = LionUtils.localeFromString("en_GB");
55 * locale.getLanguage(); // "en"
56 * locale.getCountry(); // "GB"
57 *
58 * locale = LionUtils.localeFromString("ru");
59 * locale.getLanguage(); // "ru"
60 * locale.getCountry(); // ""
61 * </pre>
62 *
63 * @param s the locale string
64 * @return a locale instance
65 */
66 public static Locale localeFromString(String s) {
67
68 if (!s.contains(LOBAR)) {
69 return new Locale(s);
70 }
71 String[] items = s.split(LOBAR);
72 return new Locale(items[0], items[1]);
73 }
74
75 /**
76 * Sets the default locale, based on the Java properties shown below.
77 * <pre>
78 * user.language
79 * user.country
80 * </pre>
81 * It is expected that the host system will have set these properties
82 * appropriately. Note, however, that the default values can be
83 * overridden by use of the environment variable {@code ONOS_LOCALE}.
84 * <p>
85 * For example, to set the Locale to French-Canadian one can invoke
86 * (from the shell)...
87 * <pre>
88 * $ ONOS_LOCALE=fr_CA {command-to-invoke-onos} ...
89 * </pre>
90 *
91 * @return the runtime locale
92 */
93 public static Locale setupRuntimeLocale() {
94 Locale systemDefault = Locale.getDefault();
95 log.info("System Default Locale: [{}]", systemDefault);
96 // TODO: Review- do we need to store the system default anywhere?
97
98 // Useful to log the "user.*" properties for debugging...
99 Set<String> pn = System.getProperties().stringPropertyNames();
100 pn.removeIf(f -> !(f.startsWith("user.")));
101 for (String ukey : pn) {
102 log.debug(" {}: {}", ukey, System.getProperty(ukey));
103 }
104
105 String language = System.getProperty(USER_LANGUAGE);
106 String country = System.getProperty(USER_COUNTRY);
107 log.info("Language: [{}], Country: [{}]", language, country);
108 Locale runtime = new Locale(language != null ? language : EMPTY,
109 country != null ? country : EMPTY);
110
111 String override = System.getenv(ONOS_LOCALE);
112 if (override != null) {
113 log.warn("Override with ONOS_LOCALE: [{}]", override);
114 runtime = localeFromString(override);
115 }
116
117 log.info("Setting runtime locale to: [{}]", runtime);
118 Locale.setDefault(runtime);
119 return runtime;
120 }
121
122 /**
Simon Hunt0c85f112017-06-12 21:02:17 -0700123 * This method takes a fully qualified name and returns a
124 * {@link ResourceBundle} which is loaded from a properties file with
125 * that base name.
126 * <p>
127 * For example, supposing the jar file contains:
Simon Hunt0c85f112017-06-12 21:02:17 -0700128 * <pre>
129 * org/onosproject/util/example/SomeBundle.properties
130 * </pre>
131 * <p>
132 * Then, to correctly load the resource bundle associated with
133 * <code>SomeBundle</code>, call:
134 * <pre>
135 * String fqname = "org.onosproject.util.example.SomeBundle";
136 * ResourceBundle res = ResourceUtils.getBundledResource(fqname);
137 * </pre>
138 * <p>
139 * Note that no error is thrown if the properties file does not exist.
140 * This condition will not become apparent until you try and access
141 * a property from the bundle, at which time a
142 * {@link java.util.MissingResourceException} will be thrown.
143 *
144 * @param basename the (fully qualified) basename of the bundle properties
145 * file
146 * @return the associated resource bundle
147 */
148 public static ResourceBundle getBundledResource(String basename) {
149 return ResourceBundle.getBundle(basename);
150 }
151
152 /**
153 * This method takes a class and returns a {@link ResourceBundle} which is
154 * loaded from a properties file with the same base name as the class.
155 * Note that both the class and the properties file(s) need to be in
156 * the same jar file.
157 * <p>
158 * For example, supposing the jar file contains:
Simon Hunt0c85f112017-06-12 21:02:17 -0700159 * <pre>
160 * org/onosproject/util/example/SomeObject.class
161 * org/onosproject/util/example/SomeObject.properties
162 * </pre>
163 * <p>
164 * Then, to correctly load the resource bundle associated with
165 * <code>SomeObject</code>, call:
166 * <pre>
167 * ResourceBundle res = ResourceUtils.getBundledResource(SomeObject.class);
168 * </pre>
169 * <p>
170 * Note that no error is thrown if the properties file does not exist.
171 * This condition will not become apparent until you try and access
172 * a property from the bundle, at which time a
173 * {@link java.util.MissingResourceException} will be thrown.
174 *
175 * @param c the class
176 * @return the associated resource bundle
177 */
178 public static ResourceBundle getBundledResource(Class<?> c) {
179 return ResourceBundle.getBundle(c.getName());
180 }
181
182 /**
183 * This method returns a {@link ResourceBundle} which is loaded from
184 * a properties file with the specified base name from the same package
185 * as the specified class.
186 * Note that both the class and the properties file(s) need to be in
187 * the same jar file.
188 * <p>
189 * For example, supposing the jar file contains:
Simon Hunt0c85f112017-06-12 21:02:17 -0700190 * <pre>
191 * org/onosproject/util/example/SomeObject.class
192 * org/onosproject/util/example/DisplayStrings.properties
193 * </pre>
194 * <p>
195 * Then, to correctly load the resource bundle call:
196 * <pre>
197 * ResourceBundle res = ResourceUtils.getBundledResource(SomeObject.class,
198 * "DisplayStrings");
199 * </pre>
200 * <p>
201 * Note that no error is thrown if the properties file does not exist.
202 * This condition will not become apparent until you try and access
203 * a property from the bundle, at which time a
204 * {@link java.util.MissingResourceException} will be thrown.
205 *
206 * @param c the class requesting the bundle
207 * @param baseName the base name of the resource bundle
208 * @return the associated resource bundle
209 */
210 public static ResourceBundle getBundledResource(Class<?> c, String baseName) {
211 String className = c.getName();
212 StringBuilder sb = new StringBuilder();
213 int dot = className.lastIndexOf(DOT);
214 sb.append(className.substring(0, dot));
215 sb.append(DOT).append(baseName);
216 return ResourceBundle.getBundle(sb.toString());
217 }
Simon Hunt7379a3d2017-06-20 16:50:39 -0700218
219 /**
220 * Generates an immutable list of localization bundles, using the specified
221 * resource tree (base) and localization configuration file names (tags).
222 * <p>
223 * As an example, you might invoke:
224 * <pre>
225 * private static final String LION_BASE = "/org/onosproject/ui/lion";
226 *
227 * private static final String[] LION_TAGS = {
228 * "core.view.App",
229 * "core.view.Settings",
230 * "core.view.Cluster",
231 * "core.view.Processor",
232 * "core.view.Partition",
233 * };
234 *
235 * List&lt;LionBundle&gt; bundles =
236 * LionUtils.generateLionBundles(LION_BASE, LION_TAGS);
237 * </pre>
238 * It is expected that in the "LION_BASE" directory there is a subdirectory
239 * named "_config" which contains the configuration files listed in the
240 * "LION_TAGS" array, each with a ".lioncfg" suffix...
241 * <pre>
242 * /org/onosproject/ui/lion/
243 * |
244 * +-- _config
245 * |
246 * +-- core.view.App.lioncfg
247 * +-- core.view.Settings.lioncfg
248 * :
249 * </pre>
250 * These files collate a localization bundle for their particular view
251 * by referencing resource bundles and their keys.
252 *
253 * @param base the base resource directory path
254 * @param tags the list of bundles to generate
255 * @return a list of generated localization bundles
256 */
257 public static List<LionBundle> generateLionBundles(String base,
258 String... tags) {
259 List<LionBundle> result = new ArrayList<>(tags.length);
260 BundleStitcher stitcher = new BundleStitcher(base);
261 for (String tag : tags) {
262 try {
263 LionBundle b = stitcher.stitch(tag);
264 result.add(b);
265
266 } catch (IllegalArgumentException e) {
267 log.warn("Unable to generate bundle: {} / {}", base, tag);
268 }
269 }
270 return ImmutableList.copyOf(result);
271 }
Simon Hunt0c85f112017-06-12 21:02:17 -0700272}