com.xceptance.common.util.PropertiesUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xlt Show documentation
Show all versions of xlt Show documentation
XLT (Xceptance LoadTest) is an extensive load and performance test tool developed and maintained by Xceptance.
/*
* Copyright (c) 2005-2023 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.FileNotFoundException;
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
{
try
{
ParameterCheckUtils.isReadableFile(file, "file");
}
catch(IllegalArgumentException e)
{
throw new FileNotFoundException(file.toString());
}
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