All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xceptance.common.util.PropertiesUtils Maven / Gradle / Ivy

/*
 * Copyright (c) 2005-2022 Xceptance Software Technologies GmbH
 *
 * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.xceptance.common.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.VFS;

/**
 * The PropertiesUtils helps in dealing with properties files.
 * 
 * @author Jörg Werner (Xceptance Software Technologies GmbH)
 */
public final class PropertiesUtils
{
    /**
     * Default constructor. Declared private to prevent external instantiation.
     */
    private PropertiesUtils()
    {
    }

    /**
     * Start delimiter for variable name.
     */
    private static final String DELIMITER_START = "${";

    /**
     * End delimiter for variable name.
     */
    private static final String DELIMITER_STOP = "}";

    /**
     * Loads the properties from the given file and returns them as a Properties object.
     * 
     * @param file
     *            the properties file
     * @return the resulting Properties object
     * @throws IOException
     *             if an I/O error occurs
     */
    public static Properties loadProperties(final File file) throws IOException
    {
        ParameterCheckUtils.isReadableFile(file, "file");

        return loadProperties(VFS.getManager().toFileObject(file));
    }

    /**
     * Loads the properties from the given file and puts them into the specified Properties object.
     * 
     * @param file
     *            the properties file
     * @param props
     *            the properties object to load the properties into
     * @throws IOException
     *             if an I/O error occurs
     */
    public static void loadProperties(final File file, final Properties props) throws IOException
    {
        ParameterCheckUtils.isReadableFile(file, "file");
        ParameterCheckUtils.isNotNull(props, "props");

        loadProperties(VFS.getManager().toFileObject(file), props);
    }

    /**
     * Loads the properties from the given file and returns them as a Properties object.
     * 
     * @param file
     *            the properties file
     * @return the resulting Properties object
     * @throws IOException
     *             if an I/O error occurs
     */
    public static Properties loadProperties(final FileObject file) throws IOException
    {
        final Properties props = new Properties();

        loadProperties(file, props);

        return props;
    }

    /**
     * Loads the properties from the given file and puts them into the specified Properties object.
     * 
     * @param file
     *            the properties file
     * @param props
     *            the properties object to load the properties into
     * @throws IOException
     *             if an I/O error occurs
     */
    public static void loadProperties(final FileObject file, final Properties props) throws IOException
    {
        ParameterCheckUtils.isReadableFile(file, "file");
        ParameterCheckUtils.isNotNull(props, "props");

        try (final InputStream is = file.getContent().getInputStream())
        {
            props.load(is);
        }
    }

    /**
     * Perform variable substitution in string value from the values of keys found in the system
     * properties.
     * 

* The variable substitution delimiters are ${ and }. *

* For example, if the System properties contains "key=value", then the call * *

     * String s = OptionConverter.substituteVars("Value of key is ${key}.");
     * 
* * will set the variable s to "Value of key is value.". *

* If no value could be found for the specified key, then the props parameter is searched, if the value * could not be found there, then substitution defaults to the empty string. *

* For example, if system properties contains no value for the key "inexistentKey", then the call * *

     * String s = OptionConverter.subsVars("Value of nonexistentKey is [${nonexistentKey}]");
     * 
* * will set s to "Value of nonexistentKey is []" *

* An {@link java.lang.IllegalArgumentException} is thrown if value contains a start delimiter "${" * which is not balanced by a stop delimiter "}". *

* * @param value * the string on which variable substitution is performed * @param properties * properties object to be used for variable lookup * @return argument string where variable have been substituted * @throws IllegalArgumentException * if value is malformed */ public static String substituteVariables(final String value, final Properties properties) throws IllegalArgumentException { // parameter validation ParameterCheckUtils.isNotNull(value, "value"); ParameterCheckUtils.isNotNull(properties, "props"); if (value.length() == 0 || properties.size() == 0) { return value; } // recursively resolve the variables in the value return resolveVariables(value, properties, new HashSet()); } /** * Resolves the given value as variable reference using the given properties object and set of already known * variables. * * @param value * variable reference to be resolved * @param props * properties object to be used to resolve the variable reference * @param variables * set of already known variables in current lookup path * @return resolved variable reference */ private static String resolveVariables(final String value, final Properties props, final Set variables) { String result = value; // list of all variable reference matches final List matches = RegExUtils.getAllMatches(value, RegExUtils.escape(DELIMITER_START) + "(.*?)" + RegExUtils.escape(DELIMITER_STOP), 1); // loop through variable references for (final String key : matches) { if (variables.contains(key)) { continue; } // add found variable to set of known variables in order to // prevent cyclic lookup paths variables.add(key); // resolve variable // 1st: Try to get value using system properties String substitution = System.getProperty(key, null); if (substitution == null) { // 2nd: Try to get value using passed properties substitution = props.getProperty(key); if (substitution == null) { // 3rd: Try to get value using system environment substitution = System.getenv(key); } } if (substitution != null) { // recursively replace any variable in the substitution string substitution = resolveVariables(substitution, props, new HashSet(variables)); // replace variable reference with its substitution value result = RegExUtils.replaceAll(result, RegExUtils.escape(DELIMITER_START + key + DELIMITER_STOP), Matcher.quoteReplacement(substitution)); } } return result; } /** * Returns all properties for this domain key, strips the key from the property name, e.g. * ClassName.Testproperty=ABC --> TestProperty=ABC Attention: Properties without a domain (e.g. foobar=test) or * domain only properties are invalid and will be ignored. A property has to have at least this form: * domain.propertyname=value * * @param domainKey * domain for the properties * @param properties * the properties from which to return the matching entries * @return map with all key value pairs of properties */ public static Map getPropertiesForKey(final String domainKey, final Properties properties) { // initialize map final Map result = new HashMap(); // maybe we are finished yet if (domainKey == null || domainKey.isEmpty()) { return result; } // assemble prefix: append a dot to the domainKey if it does not end // with a dot final String prefix = domainKey.endsWith(".") ? domainKey : domainKey + "."; // go through all property entries for (final Entry entry : properties.entrySet()) { // get property name final String fullKey = (String) entry.getKey(); // get property value final String propVal = (String) entry.getValue(); // check if there is something to do at all if (propVal == null || propVal.length() == 0) { continue; } // if property name starts with the prefix and if property name is // not only the prefix... if (fullKey.startsWith(prefix) && fullKey.length() > prefix.length()) { // put its name remainder into the map result.put(fullKey.substring(prefix.length()), properties.getProperty(fullKey)); } } return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy