Java tutorial
/* * Copyright (c) 2004-2016 YAMJ Members * https://github.com/orgs/YAMJ/people * * This file is part of the Yet Another Movie Jukebox (YAMJ) project. * * YAMJ 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 3 of the License, or * any later version. * * YAMJ 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 YAMJ. If not, see <http://www.gnu.org/licenses/>. * * Web: https://github.com/YAMJ/yamj-v2 * */ package com.moviejukebox.tools; import static org.apache.commons.lang3.StringUtils.isBlank; import java.io.*; import java.util.*; import java.util.Map.Entry; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Properties processing class for YAMJ * * @author altman.matthew */ public final class PropertiesUtil { private static final Logger LOG = LoggerFactory.getLogger(PropertiesUtil.class); private static final String PROPERTIES_CHARSET = "UTF-8"; private static final String PREFERENCES_FILENAME = "preferences.xsl"; public static final String TRUE = "true"; public static final String FALSE = "false"; private static final Properties PROPS = new Properties(); private PropertiesUtil() { throw new UnsupportedOperationException("Class cannot be instantiated"); } /** * Set the properties filename * * @param streamName * @return */ public static boolean setPropertiesStreamName(String streamName) { return setPropertiesStreamName(streamName, Boolean.TRUE); } /** * Set the properties filename with a warning if the file is not found * * @param streamName * @param warnFatal * @return */ public static boolean setPropertiesStreamName(final String streamName, boolean warnFatal) { LOG.info("Using properties file '{}'", FilenameUtils.normalize(streamName)); InputStream propertiesStream = ClassLoader.getSystemResourceAsStream(streamName); try { if (propertiesStream == null) { propertiesStream = new FileInputStream(streamName); } try (Reader reader = new InputStreamReader(propertiesStream, PROPERTIES_CHARSET)) { PROPS.load(reader); } } catch (IOException error) { // Output a warning if required. if (warnFatal) { LOG.error( "Failed loading file {}: Please check your configuration. The properties file should be in the classpath.", streamName, error); } else { LOG.debug("Warning (non-fatal): User properties file '{}', not found.", streamName); } return Boolean.FALSE; } finally { try { if (propertiesStream != null) { propertiesStream.close(); } } catch (IOException e) { // Ignore } } return Boolean.TRUE; } /** * Get a property via a key. * * @param key * @return the value if found, otherwise null */ public static String getProperty(String key) { return PROPS.getProperty(key); } /** * Get a property via a key * * @param key * @param defaultValue * @return the value if found, otherwise the default value */ public static String getProperty(String key, String defaultValue) { return PROPS.getProperty(key, defaultValue); } /** * Return the key property as a boolean * * @param key * @param defaultValue * @return */ public static boolean getBooleanProperty(String key, boolean defaultValue) { return convertBooleanProperty(PROPS.getProperty(key), defaultValue); } /** * Return the key property as integer * * @param key * @param defaultValue * @return */ public static int getIntProperty(String key, int defaultValue) { return convertIntegerProperty(PROPS.getProperty(key), defaultValue); } /** * Return the key property as an long * * @param key * @param defaultValue * @return */ public static long getLongProperty(String key, long defaultValue) { return convertLongProperty(PROPS.getProperty(key), defaultValue); } /** * Return the key property as a float * * @param key * @param defaultValue * @return */ public static float getFloatProperty(String key, float defaultValue) { return convertFloatProperty(PROPS.getProperty(key), defaultValue); } /** * Returns the property specified by the newKey or oldKey. * * Outputs warning if the oldKey was found. * * @param newKey * @param oldKey * @param defaultValue * @return */ public static String getReplacedProperty(String newKey, String oldKey, String defaultValue) { return getReplacedKeyValue(newKey, oldKey); } /** * Returns the property specified by the newKey or oldKey. * * Outputs warning if the oldKey was found. * * @param newKey * @param oldKey * @param defaultValue * @return */ public static boolean getReplacedBooleanProperty(String newKey, String oldKey, boolean defaultValue) { String property = getReplacedKeyValue(newKey, oldKey); return convertBooleanProperty(property, defaultValue); } /** * Returns the property specified by the newKey or oldKey. * * Outputs warning if the oldKey was found. * * @param newKey * @param oldKey * @param defaultValue * @return */ public static int getReplacedIntProperty(String newKey, String oldKey, int defaultValue) { String property = getReplacedKeyValue(newKey, oldKey); return convertIntegerProperty(property, defaultValue); } /** * Returns the property specified by the newKey or oldKey. * * Outputs warning if the oldKey was found. * * @param newKey * @param oldKey * @param defaultValue * @return */ public static long getReplacedLongProperty(String newKey, String oldKey, long defaultValue) { String property = getReplacedKeyValue(newKey, oldKey); return convertLongProperty(property, defaultValue); } /** * Returns the property specified by the newKey or oldKey. * * Outputs warning if the oldKey was found. * * @param newKey * @param oldKey * @param defaultValue * @return */ public static float getReplacedFloatProperty(String newKey, String oldKey, float defaultValue) { String property = getReplacedKeyValue(newKey, oldKey); return convertFloatProperty(property, defaultValue); } /** * Look for both keys in the property list and warn if the old one was found * * @param newKey * @param oldKey * @return */ private static String getReplacedKeyValue(String newKey, String oldKey) { String oldProperty = StringUtils.trimToNull(PROPS.getProperty(oldKey)); String newProperty = StringUtils.trimToNull(PROPS.getProperty(newKey)); String returnValue; if (newProperty == null && oldProperty != null) { // We found the old property, but not the new LOG.warn("Property '{}' has been deprecated and will be removed; please use '{}' instead.", oldKey, newKey); returnValue = oldProperty; } else if (newProperty != null && oldProperty != null) { // We found both properties, so warn about the old one LOG.warn( "Property '{}' is no longer used, but was found in your configuration files, please remove it.", oldKey); returnValue = newProperty; } else { returnValue = newProperty; } return returnValue; } /** * Convert the value to a Float * * @param key * @param valueToConvert * @param defaultValue * @return */ private static float convertFloatProperty(String valueToConvert, float defaultValue) { return NumberUtils.toFloat(StringUtils.trimToEmpty(valueToConvert), defaultValue); } /** * Convert the value to a Long * * @param key * @param valueToConvert * @param defaultValue * @return */ private static long convertLongProperty(String valueToConvert, long defaultValue) { return NumberUtils.toLong(StringUtils.trimToEmpty(valueToConvert), defaultValue); } /** * Convert the value to a Integer * * @param key * @param valueToConvert * @param defaultValue * @return */ private static int convertIntegerProperty(String valueToConvert, int defaultValue) { return NumberUtils.toInt(StringUtils.trimToEmpty(valueToConvert), defaultValue); } /** * Convert the value to a Boolean * * @param key * @param valueToConvert * @param defaultValue * @return */ private static boolean convertBooleanProperty(String valueToConvert, boolean defaultValue) { boolean value = defaultValue; if (StringUtils.isNotBlank(valueToConvert)) { value = Boolean.parseBoolean(StringUtils.trimToEmpty(valueToConvert)); } return value; } /** * Get the properties as an entry set for iteration<br> * Issue 309 * * @return */ public static Set<Entry<Object, Object>> getEntrySet() { // Issue 728 // Shamelessly adapted from: http://stackoverflow.com/questions/54295/how-to-write-java-util-properties-to-xml-with-sorted-keys return new TreeMap<>(PROPS).entrySet(); } /** * Set a property key to the string value * * @param key * @param value */ public static void setProperty(String key, String value) { PROPS.setProperty(key, value); } /** * Set a property key to the boolean value * * @param key * @param value */ public static void setProperty(String key, boolean value) { PROPS.setProperty(key, Boolean.toString(value)); } /** * Set a property key to the integer value * * @param key * @param value */ public static void setProperty(String key, int value) { PROPS.setProperty(key, Integer.toString(value)); } /** * Set a property key to the long value * * @param key * @param value */ public static void setProperty(String key, long value) { PROPS.setProperty(key, Long.toString(value)); } /** * Store list (ordered) and keyword map. */ public static class KeywordMap extends HashMap<String, String> { private static final long serialVersionUID = 1L; private final transient List<String> keywords = new ArrayList<>(); /** * Get the list of keywords * * @return */ public List<String> getKeywords() { return keywords; } } /** * Collect keywords list and appropriate keyword values. <br> * Example: my.languages = EN,FR my.languages.EN = English my.languages.FR = * French * * @param prefix Key for keywords list and prefix for value searching. * @param defaultValue * @return Ordered keyword list and map. */ public static KeywordMap getKeywordMap(String prefix, String defaultValue) { KeywordMap keywordMap = new KeywordMap(); String languages = getProperty(prefix, defaultValue); if (!isBlank(languages)) { for (String lang : languages.split("[ ,]+")) { lang = StringUtils.trimToNull(lang); if (lang == null) { continue; } keywordMap.keywords.add(lang); String values = getProperty(prefix + "." + lang); if (values != null) { keywordMap.put(lang, values); } } } return keywordMap; } /** * Output a warning message about the property being no longer used * * @param prop Property to warn about */ public static void warnDeprecatedProperty(final String prop) { String value = StringUtils.trimToNull(PROPS.getProperty(prop)); if (StringTools.isValidString(value)) { LOG.warn( "Property '{}' is no longer used, but was found in your configuration files, please remove it.", prop); } } /** * Write the properties out to a file */ public static void writeProperties() { // Save the properties in order List<String> propertiesList = new ArrayList<>(); propertiesList.add("homePage"); for (Object propertyObject : PROPS.keySet()) { propertiesList.add((String) propertyObject); } // Sort the properties Collections.sort(propertiesList); LOG.debug("Writing skin preferences file to {}", getPropertiesFilename(Boolean.TRUE)); try (FileOutputStream fos = new FileOutputStream(getPropertiesFilename(Boolean.TRUE)); OutputStreamWriter osw = new OutputStreamWriter(fos, PROPERTIES_CHARSET); Writer out = new BufferedWriter(osw)) { out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); out.write("<!-- This file is written automatically by YAMJ -->\n"); out.write("<!-- Last updated: " + (new Date()) + " -->\n"); out.write("<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n"); out.write(" <xsl:output method=\"xml\" omit-xml-declaration=\"yes\" />\n"); for (String property : propertiesList) { if (!property.startsWith("API_KEY") && !property.contains("#")) { out.write(" <xsl:param name=\"" + property + "\" />\n"); } } out.write("</xsl:stylesheet>\n"); out.flush(); } catch (IOException error) { // Can't write to file LOG.error("Can't write to file"); LOG.error(SystemTools.getStackTrace(error)); } } /** * Get the skin properties filename * * @param fullPath * @return */ public static String getPropertiesFilename(boolean fullPath) { if (fullPath) { return StringTools.appendToPath(getProperty("mjb.skin.dir", "./skins/default"), PREFERENCES_FILENAME); } return PREFERENCES_FILENAME; } }