• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmrs / openmrs-core / 10290281517

07 Aug 2024 07:08PM CUT coverage: 64.834% (-0.1%) from 64.952%
10290281517

push

github

web-flow
maven(deps): bump org.apache.commons:commons-lang3 from 3.15.0 to 3.16.0 (#4707)

Bumps org.apache.commons:commons-lang3 from 3.15.0 to 3.16.0.

---
updated-dependencies:
- dependency-name: org.apache.commons:commons-lang3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

22918 of 35349 relevant lines covered (64.83%)

0.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.0
/api/src/main/java/org/openmrs/util/LocaleUtility.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.util;
11

12
import java.util.LinkedHashSet;
13
import java.util.List;
14
import java.util.Locale;
15
import java.util.MissingResourceException;
16
import java.util.Set;
17

18
import org.apache.commons.lang3.LocaleUtils;
19
import org.openmrs.GlobalProperty;
20
import org.openmrs.api.GlobalPropertyListener;
21
import org.openmrs.api.context.Context;
22
import org.slf4j.Logger;
23
import org.slf4j.LoggerFactory;
24
import org.springframework.util.StringUtils;
25

26
/**
27
 * A utility class for working with Locales.
28
 */
29
public class LocaleUtility implements GlobalPropertyListener {
1✔
30
        
31
        private static final Logger log = LoggerFactory.getLogger(LocaleUtility.class);
1✔
32
        
33
        /**
34
         * Cached version of the default locale. This is cached so that we don't have to look it up in
35
         * the global property table every page load
36
         */
37
        private static Locale defaultLocaleCache = null;
1✔
38
        
39
        /**
40
         * Cached version of the localeAllowedList. This is cached so that we don't have to look it up
41
         * in the global property table every page load
42
         */
43
        private static List<Locale> localesAllowedListCache = null;
1✔
44
        
45
        /**
46
         * Gets the default locale specified as a global property.
47
         *
48
         * @return default locale object.
49
         * @since 1.5
50
         * <strong>Should</strong> not return null if global property does not exist
51
         * <strong>Should</strong> not fail with empty global property value
52
         * <strong>Should</strong> not fail with bogus global property value
53
         * <strong>Should</strong> return locale object for global property
54
         * <strong>Should</strong> not cache locale when session is not open
55
         */
56
        public static Locale getDefaultLocale() {
57
                if (defaultLocaleCache == null) {
1✔
58
                        if (Context.isSessionOpen()) {
1✔
59
                                try {
60
                                        String locale = Context.getAdministrationService().getGlobalProperty(
1✔
61
                                            OpenmrsConstants.GLOBAL_PROPERTY_DEFAULT_LOCALE);
62
                                        
63
                                        if (StringUtils.hasLength(locale)) {
1✔
64
                                                try {
65
                                                        defaultLocaleCache = fromSpecification(locale);
1✔
66
                                                }
67
                                                catch (Exception t) {
×
68
                                                        log.warn("Unable to parse default locale global property value: " + locale, t);
×
69
                                                }
1✔
70
                                        }
71
                                }
72
                                catch (Exception e) {
×
73
                                        // swallow most of the stack trace for most users
74
                                        log.warn("Unable to get locale global property value. " + e.getMessage());
×
75
                                        log.trace("Unable to get locale global property value", e);
×
76
                                }
1✔
77
                                
78
                                // if we weren't able to load the locale from the global property,
79
                                // use the default one
80
                                if (defaultLocaleCache == null) {
1✔
81
                                        defaultLocaleCache = fromSpecification(OpenmrsConstants.GLOBAL_PROPERTY_DEFAULT_LOCALE_DEFAULT_VALUE);
1✔
82
                                }
83
                        } else {
84
                                // if session is not open, return the default locale without caching
85
                                return fromSpecification(OpenmrsConstants.GLOBAL_PROPERTY_DEFAULT_LOCALE_DEFAULT_VALUE);
1✔
86
                        }
87
                        
88
                }
89
                
90
                return defaultLocaleCache;
1✔
91
        }
92
        
93
        /**
94
         * Compatible is a looser matching than that provided by Locale.equals(). Two locales are
95
         * considered equal if they are equal, or if either does not have a country specified and the
96
         * languages match.
97
         *
98
         * @param lhs left hand side Locale
99
         * @param rhs right hand side Locale
100
         * @return true if the two locales are compatible, false otherwise
101
         * <strong>Should</strong> confirm different language missing country as compatible
102
         * <strong>Should</strong> confirm same language missing country as compatible
103
         * <strong>Should</strong> not confirm different country as compatible
104
         * <strong>Should</strong> confirm matching country as compatible
105
         * <strong>Should</strong> not confirm different language as compatible
106
         * <strong>Should</strong> confirm matching language as compatible
107
         */
108
        public static boolean areCompatible(Locale lhs, Locale rhs) {
109
                return lhs.equals(rhs) || (("".equals(lhs.getCountry())) || ("".equals(rhs.getCountry()))) && lhs.getLanguage()
1✔
110
                                .equals(rhs.getLanguage());
1✔
111
        }
112
        
113
        /**
114
         * Creates a locale based on a string specification. The specification must be conform with the
115
         * following format: ll_CC_vv <br>
116
         * <ul>
117
         * <li>ll: two-character lowercase ISO-639 language code
118
         * <li>CC: two-character uppercase ISO-3166 country code optional
119
         * <li>vv: arbitrary length variant code
120
         * </ul>
121
         * For example: en_US_Traditional_WIN ...represents English language in the United States with
122
         * the traditional collation for windows.
123
         *
124
         * @param localeSpecification encoded locale specification
125
         * @return the representative Locale, or null if the specification is invalid
126
         * <strong>Should</strong> get locale from two character language code
127
         * <strong>Should</strong> get locale from language code and country code
128
         * <strong>Should</strong> get locale from language code country code and variant
129
         */
130
        public static Locale fromSpecification(String localeSpecification) {
131
                Locale createdLocale;
132
                
133
                localeSpecification = localeSpecification.trim();
1✔
134
                
135
                try {
136
                        createdLocale = LocaleUtils.toLocale(localeSpecification);
1✔
137
                } catch (IllegalArgumentException e) {
1✔
138
                        if (localeSpecification.matches("[a-zA-Z]{2}[-_][a-zA-Z]{2,}")) {
1✔
139
                                return null;
1✔
140
                        } else {
141
                                createdLocale = generateLocaleFromLegacyFormat(localeSpecification);
1✔
142
                        }
143
                }
1✔
144
                
145
                return createdLocale;
1✔
146
        }
147
        
148
        private static Locale generateLocaleFromLegacyFormat(String localeSpecification) {
149
                Locale createdLocale = null;
1✔
150
                
151
                String[] localeComponents = localeSpecification.split("_");
1✔
152
                if (localeComponents.length == 1) {
1✔
153
                        createdLocale = new Locale(localeComponents[0]);
1✔
154
                } else if (localeComponents.length == 2) {
×
155
                        createdLocale = new Locale(localeComponents[0], localeComponents[1]);
×
156
                } else if (localeComponents.length > 2) {
×
157
                        String variant = localeSpecification.substring(localeSpecification.indexOf(localeComponents[2]));
×
158
                        createdLocale = new Locale(localeComponents[0], localeComponents[1], variant);
×
159
                }
160
                
161
                return createdLocale;
1✔
162
        }
163
        
164
        /**
165
         * Utility method that returns a collection of all openmrs system locales, the set includes the
166
         * current logged in user's preferred locale if any is set, the default locale, allowed locales
167
         * in the order they are specified in the 'allowed.locale.list' global property and 'en' at the
168
         * very end of the set if it isn't yet among them.
169
         *
170
         * @return a collection of all specified and allowed locales with no duplicates.
171
         * <strong>Should</strong> return a set of locales with a predictable order
172
         * <strong>Should</strong> return a set of locales with no duplicates
173
         * <strong>Should</strong> have default locale as the first element if user has no preferred locale
174
         * <strong>Should</strong> have default locale as the second element if user has a preferred locale
175
         * <strong>Should</strong> always have english included in the returned collection
176
         * <strong>Should</strong> always have default locale default value included in the returned collection
177
         * @since 1.7
178
         */
179
        public static Set<Locale> getLocalesInOrder() {
180
                
181
                Set<Locale> locales = new LinkedHashSet<>();
1✔
182
                locales.add(Context.getLocale());
1✔
183
                locales.add(getDefaultLocale());
1✔
184
                if (localesAllowedListCache == null) {
1✔
185
                        localesAllowedListCache = Context.getAdministrationService().getAllowedLocales();
1✔
186
                }
187
                
188
                if (localesAllowedListCache != null) {
1✔
189
                        locales.addAll(localesAllowedListCache);
1✔
190
                }
191
                
192
                locales.add(Locale.ENGLISH);
1✔
193
                locales.add(fromSpecification(OpenmrsConstants.GLOBAL_PROPERTY_DEFAULT_LOCALE_DEFAULT_VALUE));
1✔
194
                
195
                return locales;
1✔
196
        }
197
        
198
        public static void setDefaultLocaleCache(Locale defaultLocaleCache) {
199
                LocaleUtility.defaultLocaleCache = defaultLocaleCache;
1✔
200
        }
1✔
201
        
202
        public static void setLocalesAllowedListCache(List<Locale> localesAllowedListCache) {
203
                LocaleUtility.localesAllowedListCache = localesAllowedListCache;
1✔
204
        }
1✔
205
        
206
        @Override
207
        public void globalPropertyChanged(GlobalProperty newValue) {
208
                // reset the value
209
                setDefaultLocaleCache(null);
1✔
210
                setLocalesAllowedListCache(null);
1✔
211
        }
1✔
212
        
213
        @Override
214
        public void globalPropertyDeleted(String propertyName) {
215
                // reset the value
216
                setDefaultLocaleCache(null);
1✔
217
                setLocalesAllowedListCache(null);
1✔
218
        }
1✔
219
        
220
        @Override
221
        public boolean supportsPropertyName(String propertyName) {
222
                return propertyName.equals(OpenmrsConstants.GLOBAL_PROPERTY_DEFAULT_LOCALE)
1✔
223
                        || propertyName.equals(OpenmrsConstants.GLOBAL_PROPERTY_LOCALE_ALLOWED_LIST);
1✔
224
                
225
        }
226
        
227
        /**
228
         * Checks if specified locale object is valid
229
         *
230
         * @param locale
231
         *            object for validation
232
         * @return true if locale is available
233
         */
234
        public static boolean isValid(Locale locale) {
235
                try {
236
                        return locale.getISO3Language() != null && locale.getISO3Country() != null;
×
237
                }
238
                catch (MissingResourceException e) {
×
239
                        return false;
×
240
                }
241
        }
242
        
243
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc