001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.commons.crypto.utils; 019 020import java.io.File; 021import java.io.IOException; 022import java.io.InputStream; 023import java.net.URL; 024import java.security.GeneralSecurityException; 025import java.util.ArrayList; 026import java.util.Enumeration; 027import java.util.List; 028import java.util.Objects; 029import java.util.Properties; 030 031import org.apache.commons.crypto.Crypto; 032import org.apache.commons.crypto.cipher.CryptoCipher; 033import org.apache.commons.crypto.cipher.CryptoCipherFactory; 034 035/** 036 * General utility methods. 037 */ 038public final class Utils { 039 040 private static class DefaultPropertiesHolder { 041 static final Properties DEFAULT_PROPERTIES = createDefaultProperties(); 042 043 /** 044 * Loads system properties when configuration file of the name 045 * {@link #SYSTEM_PROPERTIES_FILE} is found. 046 * 047 * @return the default properties 048 */ 049 private static Properties createDefaultProperties() { 050 // default to system 051 final Properties defaultedProps = new Properties(System.getProperties()); 052 final URL url = Thread.currentThread().getContextClassLoader().getResource(SYSTEM_PROPERTIES_FILE); 053 if (url == null) { 054 // Fail early when the resource is not found which makes SpotBugs happy on Java 17. 055 return defaultedProps; 056 } 057 try { 058 final Properties fileProps = new Properties(); 059 try (InputStream is = url.openStream()) { 060 fileProps.load(is); 061 } 062 final Enumeration<?> names = fileProps.propertyNames(); 063 while (names.hasMoreElements()) { 064 final String name = (String) names.nextElement(); 065 // ensure System properties override ones in the file so one can override the file on the command line 066 if (System.getProperty(name) == null) { 067 defaultedProps.setProperty(name, fileProps.getProperty(name)); 068 } 069 } 070 } catch (final Exception ex) { 071 System.err.println("Could not load '" + SYSTEM_PROPERTIES_FILE + "' from classpath: " + ex.toString()); 072 } 073 return defaultedProps; 074 } 075 } 076 077 /** 078 * The file name of configuration file. 079 */ 080 private static final String SYSTEM_PROPERTIES_FILE = Crypto.CONF_PREFIX + "properties"; 081 082 /** 083 * Ensures the truth of an expression involving one or more parameters to 084 * the calling method. 085 * 086 * @param expression a boolean expression. 087 * @throws IllegalArgumentException if expression is false. 088 */ 089 public static void checkArgument(final boolean expression) { 090 if (!expression) { 091 throw new IllegalArgumentException(); 092 } 093 } 094 095 /** 096 * Checks the truth of an expression. 097 * 098 * @param expression a boolean expression. 099 * @param errorMessage the exception message to use if the check fails; will 100 * be converted to a string using <code>String 101 * .valueOf(Object)</code>. 102 * @throws IllegalArgumentException if expression is false. 103 */ 104 public static void checkArgument(final boolean expression, final Object errorMessage) { 105 if (!expression) { 106 throw new IllegalArgumentException(String.valueOf(errorMessage)); 107 } 108 } 109 110 /** 111 * Ensures that an object reference passed as a parameter to the calling 112 * method is not null. 113 * 114 * @param <T> the type of the object reference to be checked. 115 * @param reference an object reference. 116 * @return the non-null reference that was validated. 117 * @throws NullPointerException if reference is null. 118 * @deprecated Use {@link Objects#requireNonNull(Object)}. 119 */ 120 @Deprecated 121 public static <T> T checkNotNull(final T reference) { 122 return Objects.requireNonNull(reference, "reference"); 123 } 124 125 /** 126 * Ensures the truth of an expression involving the state of the calling 127 * instance, but not involving any parameters to the calling method. 128 * 129 * @param expression a boolean expression. 130 * @throws IllegalStateException if expression is false. 131 */ 132 public static void checkState(final boolean expression) { 133 checkState(expression, null); 134 } 135 136 /** 137 * Ensures the truth of an expression involving the state of the calling 138 * instance, but not involving any parameters to the calling method. 139 * 140 * @param expression a boolean expression. 141 * @param message Error message for the exception when the expression is false. 142 * @throws IllegalStateException if expression is false. 143 */ 144 public static void checkState(final boolean expression, final String message) { 145 if (!expression) { 146 throw new IllegalStateException(message); 147 } 148 } 149 150 /** 151 * Helper method to create a CryptoCipher instance and throws only 152 * IOException. 153 * 154 * @param properties The {@code Properties} class represents a set of 155 * properties. 156 * @param transformation the name of the transformation, e.g., 157 * <i>AES/CBC/PKCS5Padding</i>. 158 * See the Java Cryptography Architecture Standard Algorithm Name Documentation 159 * for information about standard transformation names. 160 * @return the CryptoCipher instance. 161 * @throws IOException if an I/O error occurs. 162 */ 163 public static CryptoCipher getCipherInstance(final String transformation, final Properties properties) throws IOException { 164 try { 165 return CryptoCipherFactory.getCryptoCipher(transformation, properties); 166 } catch (final GeneralSecurityException e) { 167 throw new IOException(e); 168 } 169 } 170 171 /** 172 * Gets a properties instance that defaults to the System Properties 173 * plus any other properties found in the file 174 * {@link #SYSTEM_PROPERTIES_FILE} 175 * @return a Properties instance with defaults 176 */ 177 public static Properties getDefaultProperties() { 178 return new Properties(DefaultPropertiesHolder.DEFAULT_PROPERTIES); 179 } 180 181 /** 182 * Gets the properties merged with default properties. 183 * @param newProp User-defined properties 184 * @return User-defined properties with the default properties 185 */ 186 public static Properties getProperties(final Properties newProp) { 187 final Properties properties = new Properties(DefaultPropertiesHolder.DEFAULT_PROPERTIES); 188 properties.putAll(newProp); 189 return properties; 190 } 191 192 /* 193 * Override the default DLL name if jni.library.path is a valid directory 194 * @param name - the default name, passed from native code 195 * @return the updated library path 196 * This method is designed for use from the DynamicLoader native code. 197 * Although it could all be implemented in native code, this hook method 198 * makes maintenance easier. 199 * The code is intended for use with macOS where SIP makes it hard to override 200 * the environment variables needed to override the DLL search path. It also 201 * works for Linux, but is not (currently) used or needed for Windows. 202 * Do not change the method name or its signature! 203 */ 204 static String libraryPath(final String name) { 205 final String override = System.getProperty("jni.library.path"); 206 if (override != null && new File(override).isDirectory()) { 207 return new File(override, name).getPath(); 208 } 209 return name; 210 } 211 212 /** 213 * Splits class names sequence into substrings, Trim each substring into an 214 * entry,and returns an list of the entries. 215 * 216 * @param clazzNames a string consist of a list of the entries joined by a 217 * delimiter, may be null or empty in which case an empty list is returned. 218 * @param separator a delimiter for the input string. 219 * @return a list of class entries. 220 */ 221 public static List<String> splitClassNames(final String clazzNames, final String separator) { 222 final List<String> res = new ArrayList<>(); 223 if (clazzNames == null || clazzNames.isEmpty()) { 224 return res; 225 } 226 227 for (String clazzName : clazzNames.split(separator)) { 228 clazzName = clazzName.trim(); 229 if (!clazzName.isEmpty()) { 230 res.add(clazzName); 231 } 232 } 233 return res; 234 } 235 236 /** 237 * The private constructor of {@link Utils}. 238 */ 239 private Utils() { 240 } 241 242}