/* ================================================================== * SetupResourceUtils.java - 23/09/2016 10:20:14 AM * * Copyright 2007-2016 SolarNetwork.net Dev Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * ================================================================== */ package net.solarnetwork.node.setup; import java.util.Collections; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.springframework.util.StringUtils; /** * Utility methods for setup resources. * * @author matt * @version 1.0 */ public final class SetupResourceUtils { private SetupResourceUtils() { // don't construct me } /** * A pattern to match locale specifications in filenames. Matches with 2 * groups: the language, the country. The country is a nested group, so is * actually referred by as group {code 3}. */ public static final Pattern LOCALE_PAT = Pattern.compile("_([a-z]{2,3})(_([A-Z]{2,3}))?(?:\\..*)$"); /** * Get a default mapping of file extensions to associated content types. */ public static final Map<String, String> DEFAULT_FILENAME_EXTENSION_CONTENT_TYPES = defaultFilenameExtensionContentTypeMap(); private static Map<String, String> defaultFilenameExtensionContentTypeMap() { Map<String, String> m = new HashMap<String, String>(); m.put("js", SetupResource.JAVASCRIPT_CONTENT_TYPE); m.put("css", SetupResource.CSS_CONTENT_TYPE); m.put("html", SetupResource.HTML_CONTENT_TYPE); m.put("txt", "text/plain"); m.put("xml", "text/xml"); return Collections.unmodifiableMap(m); } /** * Get a {@link Locale} based on a path. * * The path is expected to follow {@link java.util.ResourceBundle} naming * conventions, for example {@code file.txt} for no locale, * {@code file_en.txt} for a specific language, and {@code file_en_US.txt} * for a language plus country variant. * * @param path * The path to derive a locale from. * @return The Locale, or {@code null} if not appropriate or none found. */ public static Locale localeForPath(String path) { if ( path == null ) { return null; } Matcher m = LOCALE_PAT.matcher(path); if ( m.find() ) { String lang = m.group(1); String country = m.group(3); if ( country != null ) { return new Locale(lang, country); } return localeForLanguage(lang); } return null; } /** * Get a base filename for a given path, without any extension or locale * specifier. * * @param path * The path to get the base filename from. * @return The base filename, or {@code null} if {@code path} is * {@code null}. */ public static String baseFilenameForPath(String path) { if ( path == null ) { return null; } Matcher m = LOCALE_PAT.matcher(path); if ( m.find() ) { int end = m.end(2); if ( end < 0 ) { end = m.end(1); } String result = StringUtils.getFilename(path.substring(0, m.start())) + path.substring(end); return result; } return StringUtils.getFilename(path); } /** * Get a locale for just a language. * * @param lang * The language to get the locale for. * @return The Locale, or {@code null} if {@code lang} is {@code null}. */ public static Locale localeForLanguage(String lang) { if ( lang == null ) { return null; } if ( Locale.ENGLISH.getLanguage().equals(lang) ) { return Locale.ENGLISH; } return new Locale(lang); } /** * Assign a score to a resource for how closely it matches the desired * locale. * * @param rsrc * The resource to test * @param desiredLocale * The desired locale. * @param defaultLocale * The default locale to use for resources where * {@link SetupResource#getLocale()} returns {@code null}. * @return A matching score. Higher values more closely match. If * {@link Integer#MAX_VALUE} is returned then the match is exact. */ public static int localeScore(SetupResource rsrc, Locale desiredLocale, Locale defaultLocale) { if ( rsrc == null ) { return Integer.MIN_VALUE; } if ( defaultLocale == null ) { defaultLocale = Locale.getDefault(); } if ( desiredLocale == null ) { desiredLocale = defaultLocale; } Locale rsrcLocale = rsrc.getLocale(); if ( rsrcLocale == null ) { rsrcLocale = defaultLocale; } if ( desiredLocale.equals(rsrcLocale) ) { return Integer.MAX_VALUE; } boolean lMatch = desiredLocale.getLanguage().equals(rsrcLocale.getLanguage()); boolean cMatch = desiredLocale.getCountry().equals(rsrcLocale.getCountry()); if ( lMatch && cMatch ) { return 2; } else if ( lMatch ) { return 1; } return -1; } }