Utils.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.commons.crypto.utils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import org.apache.commons.crypto.Crypto;
import org.apache.commons.crypto.cipher.CryptoCipher;
import org.apache.commons.crypto.cipher.CryptoCipherFactory;
/**
* General utility methods.
*/
public final class Utils {
private static class DefaultPropertiesHolder {
static final Properties DEFAULT_PROPERTIES = createDefaultProperties();
/**
* Loads system properties when configuration file of the name
* {@link #SYSTEM_PROPERTIES_FILE} is found.
*
* @return the default properties
*/
private static Properties createDefaultProperties() {
// default to system
final Properties defaultedProps = new Properties(System.getProperties());
final URL url = Thread.currentThread().getContextClassLoader().getResource(SYSTEM_PROPERTIES_FILE);
if (url == null) {
// Fail early when the resource is not found which makes SpotBugs happy on Java 17.
return defaultedProps;
}
try {
final Properties fileProps = new Properties();
try (InputStream is = url.openStream()) {
fileProps.load(is);
}
final Enumeration<?> names = fileProps.propertyNames();
while (names.hasMoreElements()) {
final String name = (String) names.nextElement();
// ensure System properties override ones in the file so one can override the file on the command line
if (System.getProperty(name) == null) {
defaultedProps.setProperty(name, fileProps.getProperty(name));
}
}
} catch (final Exception ex) {
System.err.println("Could not load '" + SYSTEM_PROPERTIES_FILE + "' from classpath: " + ex.toString());
}
return defaultedProps;
}
}
/**
* The file name of configuration file.
*/
private static final String SYSTEM_PROPERTIES_FILE = Crypto.CONF_PREFIX + "properties";
/**
* Ensures the truth of an expression involving one or more parameters to
* the calling method.
*
* @param expression a boolean expression.
* @throws IllegalArgumentException if expression is false.
*/
public static void checkArgument(final boolean expression) {
if (!expression) {
throw new IllegalArgumentException();
}
}
/**
* Checks the truth of an expression.
*
* @param expression a boolean expression.
* @param errorMessage the exception message to use if the check fails; will
* be converted to a string using <code>String
* .valueOf(Object)</code>.
* @throws IllegalArgumentException if expression is false.
*/
public static void checkArgument(final boolean expression, final Object errorMessage) {
if (!expression) {
throw new IllegalArgumentException(String.valueOf(errorMessage));
}
}
/**
* Ensures that an object reference passed as a parameter to the calling
* method is not null.
*
* @param <T> the type of the object reference to be checked.
* @param reference an object reference.
* @return the non-null reference that was validated.
* @throws NullPointerException if reference is null.
* @deprecated Use {@link Objects#requireNonNull(Object)}.
*/
@Deprecated
public static <T> T checkNotNull(final T reference) {
return Objects.requireNonNull(reference, "reference");
}
/**
* Ensures the truth of an expression involving the state of the calling
* instance, but not involving any parameters to the calling method.
*
* @param expression a boolean expression.
* @throws IllegalStateException if expression is false.
*/
public static void checkState(final boolean expression) {
checkState(expression, null);
}
/**
* Ensures the truth of an expression involving the state of the calling
* instance, but not involving any parameters to the calling method.
*
* @param expression a boolean expression.
* @param message Error message for the exception when the expression is false.
* @throws IllegalStateException if expression is false.
*/
public static void checkState(final boolean expression, final String message) {
if (!expression) {
throw new IllegalStateException(message);
}
}
/**
* Helper method to create a CryptoCipher instance and throws only
* IOException.
*
* @param properties The {@code Properties} class represents a set of
* properties.
* @param transformation the name of the transformation, e.g.,
* <i>AES/CBC/PKCS5Padding</i>.
* See the Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard transformation names.
* @return the CryptoCipher instance.
* @throws IOException if an I/O error occurs.
*/
public static CryptoCipher getCipherInstance(final String transformation, final Properties properties) throws IOException {
try {
return CryptoCipherFactory.getCryptoCipher(transformation, properties);
} catch (final GeneralSecurityException e) {
throw new IOException(e);
}
}
/**
* Gets a properties instance that defaults to the System Properties
* plus any other properties found in the file
* {@link #SYSTEM_PROPERTIES_FILE}
* @return a Properties instance with defaults
*/
public static Properties getDefaultProperties() {
return new Properties(DefaultPropertiesHolder.DEFAULT_PROPERTIES);
}
/**
* Gets the properties merged with default properties.
* @param newProp User-defined properties
* @return User-defined properties with the default properties
*/
public static Properties getProperties(final Properties newProp) {
final Properties properties = new Properties(DefaultPropertiesHolder.DEFAULT_PROPERTIES);
properties.putAll(newProp);
return properties;
}
/*
* Override the default DLL name if jni.library.path is a valid directory
* @param name - the default name, passed from native code
* @return the updated library path
* This method is designed for use from the DynamicLoader native code.
* Although it could all be implemented in native code, this hook method
* makes maintenance easier.
* The code is intended for use with macOS where SIP makes it hard to override
* the environment variables needed to override the DLL search path. It also
* works for Linux, but is not (currently) used or needed for Windows.
* Do not change the method name or its signature!
*/
static String libraryPath(final String name) {
final String override = System.getProperty("jni.library.path");
if (override != null && new File(override).isDirectory()) {
return new File(override, name).getPath();
}
return name;
}
/**
* Splits class names sequence into substrings, Trim each substring into an
* entry,and returns an list of the entries.
*
* @param clazzNames a string consist of a list of the entries joined by a
* delimiter, may be null or empty in which case an empty list is returned.
* @param separator a delimiter for the input string.
* @return a list of class entries.
*/
public static List<String> splitClassNames(final String clazzNames, final String separator) {
final List<String> res = new ArrayList<>();
if (clazzNames == null || clazzNames.isEmpty()) {
return res;
}
for (String clazzName : clazzNames.split(separator)) {
clazzName = clazzName.trim();
if (!clazzName.isEmpty()) {
res.add(clazzName);
}
}
return res;
}
/**
* The private constructor of {@link Utils}.
*/
private Utils() {
}
}