View Javadoc
1    /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.commons.crypto.utils;
19  
20  import java.io.File;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.net.URL;
24  import java.security.GeneralSecurityException;
25  import java.util.ArrayList;
26  import java.util.Enumeration;
27  import java.util.List;
28  import java.util.Objects;
29  import java.util.Properties;
30  
31  import org.apache.commons.crypto.Crypto;
32  import org.apache.commons.crypto.cipher.CryptoCipher;
33  import org.apache.commons.crypto.cipher.CryptoCipherFactory;
34  
35  /**
36   * General utility methods.
37   */
38  public final class Utils {
39  
40      private static class DefaultPropertiesHolder {
41          static final Properties DEFAULT_PROPERTIES = createDefaultProperties();
42  
43          /**
44           * Loads system properties when configuration file of the name
45           * {@link #SYSTEM_PROPERTIES_FILE} is found.
46           *
47           * @return the default properties
48           */
49          private static Properties createDefaultProperties() {
50            // default to system
51            final Properties defaultedProps = new Properties(System.getProperties());
52            final URL url = Thread.currentThread().getContextClassLoader().getResource(SYSTEM_PROPERTIES_FILE);
53            if (url == null) {
54                // Fail early when the resource is not found which makes SpotBugs happy on Java 17.
55                return defaultedProps;
56            }
57            try {
58                final Properties fileProps = new Properties();
59                try (InputStream is = url.openStream()) {
60                    fileProps.load(is);
61                }
62                final Enumeration<?> names = fileProps.propertyNames();
63                while (names.hasMoreElements()) {
64                    final String name = (String) names.nextElement();
65                    // ensure System properties override ones in the file so one can override the file on the command line
66                    if (System.getProperty(name) == null) {
67                        defaultedProps.setProperty(name, fileProps.getProperty(name));
68                    }
69                }
70            } catch (final Exception ex) {
71                System.err.println("Could not load '" + SYSTEM_PROPERTIES_FILE + "' from classpath: " + ex.toString());
72            }
73            return defaultedProps;
74        }
75     }
76  
77      /**
78       * The file name of configuration file.
79       */
80      private static final String SYSTEM_PROPERTIES_FILE = Crypto.CONF_PREFIX + "properties";
81  
82      /**
83       * Ensures the truth of an expression involving one or more parameters to
84       * the calling method.
85       *
86       * @param expression a boolean expression.
87       * @throws IllegalArgumentException if expression is false.
88       */
89      public static void checkArgument(final boolean expression) {
90          if (!expression) {
91              throw new IllegalArgumentException();
92          }
93      }
94  
95      /**
96       * Checks the truth of an expression.
97       *
98       * @param expression a boolean expression.
99       * @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 }