/**
* The contents of this file are subject to the OpenMRS Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://license.openmrs.org
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* Copyright (C) OpenMRS, LLC. All Rights Reserved.
*/
package org.openmrs.util;
import java.util.Locale;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.api.context.Context;
import org.springframework.util.StringUtils;
/**
* A utility class for working with Locales.
*/
public class LocaleUtility {
private static Log log = LogFactory.getLog(LocaleUtility.class);
/**
* Default internal locale.
*
* @deprecated use {@link #getDefaultLocale()} now
*/
public static final Locale DEFAULT_LOCALE = Locale.UK;
/**
* Gets the default locale specified as a global property.
*
* @return default locale object.
* @since 1.5
* @should not return null if global property does not exist
* @should not fail with empty global property value
* @should not fail with bogus global property value
* @should return locale object for global property
*/
public static Locale getDefaultLocale() {
if (Context.isSessionOpen()) {
try {
String locale = Context.getAdministrationService().getGlobalProperty(
OpenmrsConstants.GLOBAL_PROPERTY_DEFAULT_LOCALE);
if (StringUtils.hasLength(locale)) {
try {
return fromSpecification(locale);
}
catch (Exception t) {
log.warn("Unable to parse default locale global property value: " + locale, t);
}
}
}
catch (Throwable t) {
// swallow most of the stack trace for most users
log.warn("Unable to get locale global property value. " + t.getMessage());
log.trace("Unable to get locale global property value", t);
}
}
return fromSpecification(OpenmrsConstants.GLOBAL_PROPERTY_DEFAULT_LOCALE_DEFAULT_VALUE);
}
/**
* Compatible is a looser matching than that provided by Locale.equals(). Two locales are
* considered equal if they are equal, or if either does not have a country specified and the
* languages match.
*
* @param lhs left hand side Locale
* @param rhs right hand side Locale
* @return true if the two locales are compatible, false otherwise
* @should confirm different language missing country as compatible
* @should confirm same language missing country as compatible
* @should not confirm different country as compatible
* @should confirm matching country as compatible
* @should not confirm different language as compatible
* @should confirm matching language as compatible
*/
public static boolean areCompatible(Locale lhs, Locale rhs) {
if (lhs.equals(rhs)) {
return true;
} else if (("".equals(lhs.getCountry())) || ("".equals(rhs.getCountry()))) {
// no country specified, so language match is good enough
if (lhs.getLanguage().equals(rhs.getLanguage())) {
return true;
}
}
return false;
}
/**
* Creates a locale based on a string specification. The specification must be conform with the
* following format: ll_CC_vv <br/>
* <ul>
* <li>ll: two-character lowercase ISO-639 language code
* <li>CC: two-character uppercase ISO-3166 country code optional
* <li>vv: arbitrary length variant code
* </ul>
* For example: en_US_Traditional_WIN ...represents English language in the United States with
* the traditional collation for windows.
*
* @param localeSpecification encoded locale specification
* @return the representative Locale, or null if the specification is invalid
* @should get locale from two character language code
* @should get locale from language code and country code
* @should get locale from language code country code and variant
*/
public static Locale fromSpecification(String localeSpecification) {
Locale createdLocale = null;
localeSpecification = localeSpecification.trim();
String[] localeComponents = localeSpecification.split("_");
if (localeComponents.length == 1) {
createdLocale = new Locale(localeComponents[0]);
} else if (localeComponents.length == 2) {
createdLocale = new Locale(localeComponents[0], localeComponents[1]);
} else if (localeComponents.length > 2) {
String variant = localeSpecification.substring(localeSpecification.indexOf(localeComponents[2])); // gets everything after the second underscore
createdLocale = new Locale(localeComponents[0], localeComponents[1], variant);
}
return createdLocale;
}
}