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.IOException;
021import java.io.InputStream;
022import java.security.GeneralSecurityException;
023import java.util.ArrayList;
024import java.util.Enumeration;
025import java.util.List;
026import java.util.Objects;
027import java.util.Properties;
028
029import org.apache.commons.crypto.Crypto;
030import org.apache.commons.crypto.cipher.CryptoCipher;
031import org.apache.commons.crypto.cipher.CryptoCipherFactory;
032
033/**
034 * General utility methods.
035 */
036public final class Utils {
037
038    private static class DefaultPropertiesHolder {
039        static final Properties DEFAULT_PROPERTIES = createDefaultProperties();
040     }
041
042    /**
043     * The file name of configuration file.
044     * TODO is there any need for it to have the CONF_PREFIX?
045     */
046    private static final String SYSTEM_PROPERTIES_FILE = Crypto.CONF_PREFIX
047            + "properties";
048
049    /**
050     * The private constructor of {@link Utils}.
051     */
052    private Utils() {
053    }
054
055    /**
056     * Loads system properties when configuration file of the name
057     * {@link #SYSTEM_PROPERTIES_FILE} is found.
058     *
059     * @return the default properties
060     */
061    private static Properties createDefaultProperties() {
062        // default to system
063        final Properties defaultedProps = new Properties(System.getProperties());
064        try {
065            final Properties fileProps = new Properties();
066            try (final InputStream is = Thread.currentThread().getContextClassLoader()
067                .getResourceAsStream(SYSTEM_PROPERTIES_FILE)) {
068
069                if (is == null) {
070                    return defaultedProps; // no configuration file is found
071                }
072                // Load property file
073                fileProps.load(is);
074            }
075            final Enumeration<?> names = fileProps.propertyNames();
076            while (names.hasMoreElements()) {
077                final String name = (String) names.nextElement();
078                // ensure System properties override ones in the file so one can override the file on the command line
079                if (System.getProperty(name) == null) {
080                    defaultedProps.setProperty(name, fileProps.getProperty(name));
081                }
082            }
083        } catch (final Exception ex) {
084            System.err.println("Could not load '"
085                    + SYSTEM_PROPERTIES_FILE
086                    + "' from classpath: " + ex.toString());
087        }
088        return defaultedProps;
089    }
090
091    /**
092     * Gets a properties instance that defaults to the System Properties
093     * plus any other properties found in the file
094     * {@link #SYSTEM_PROPERTIES_FILE}
095     * @return a Properties instance with defaults
096     */
097    public static Properties getDefaultProperties() {
098        return new Properties(DefaultPropertiesHolder.DEFAULT_PROPERTIES);
099    }
100
101    /**
102     * Gets the properties merged with default properties.
103     * @param newProp  User-defined properties
104     * @return User-defined properties with the default properties
105     */
106    public static Properties getProperties(final Properties newProp) {
107        final Properties properties = new Properties(DefaultPropertiesHolder.DEFAULT_PROPERTIES);
108        properties.putAll(newProp);
109        return properties;
110     }
111
112    /**
113     * Helper method to create a CryptoCipher instance and throws only
114     * IOException.
115     *
116     * @param properties The {@code Properties} class represents a set of
117     *        properties.
118     * @param transformation the name of the transformation, e.g.,
119     * <i>AES/CBC/PKCS5Padding</i>.
120     * See the Java Cryptography Architecture Standard Algorithm Name Documentation
121     * for information about standard transformation names.
122     * @return the CryptoCipher instance.
123     * @throws IOException if an I/O error occurs.
124     */
125    public static CryptoCipher getCipherInstance(
126            final String transformation, final Properties properties)
127            throws IOException {
128        try {
129            return CryptoCipherFactory.getCryptoCipher(transformation, properties);
130        } catch (final GeneralSecurityException e) {
131            throw new IOException(e);
132        }
133    }
134
135    /**
136     * Ensures the truth of an expression involving one or more parameters to
137     * the calling method.
138     *
139     * @param expression a boolean expression.
140     * @throws IllegalArgumentException if expression is false.
141     */
142    public static void checkArgument(final boolean expression) {
143        if (!expression) {
144            throw new IllegalArgumentException();
145        }
146    }
147
148    /**
149     * Checks the truth of an expression.
150     *
151     * @param expression a boolean expression.
152     * @param errorMessage the exception message to use if the check fails; will
153     *        be converted to a string using <code>String
154     *                     .valueOf(Object)</code>.
155     * @throws IllegalArgumentException if expression is false.
156     */
157    public static void checkArgument(final boolean expression, final Object errorMessage) {
158        if (!expression) {
159            throw new IllegalArgumentException(String.valueOf(errorMessage));
160        }
161    }
162
163    /**
164     * Ensures that an object reference passed as a parameter to the calling
165     * method is not null.
166     *
167     * @param <T> the type of the object reference to be checked.
168     * @param reference an object reference.
169     * @return the non-null reference that was validated.
170     * @throws NullPointerException if reference is null.
171     * @deprecated Use {@link Objects#requireNonNull(Object)}.
172     */
173    @Deprecated
174    public static <T> T checkNotNull(final T reference) {
175        return Objects.requireNonNull(reference, "reference");
176    }
177
178    /**
179     * Ensures the truth of an expression involving the state of the calling
180     * instance, but not involving any parameters to the calling method.
181     *
182     * @param expression a boolean expression.
183     * @throws IllegalStateException if expression is false.
184     */
185    public static void checkState(final boolean expression) {
186        checkState(expression, null);
187    }
188
189    /**
190     * Ensures the truth of an expression involving the state of the calling
191     * instance, but not involving any parameters to the calling method.
192     *
193     * @param expression a boolean expression.
194     * @param message Error message for the exception when the expression is false.
195     * @throws IllegalStateException if expression is false.
196     */
197    public static void checkState(final boolean expression, final String message) {
198        if (!expression) {
199            throw new IllegalStateException(message);
200        }
201    }
202
203    /**
204     * Splits class names sequence into substrings, Trim each substring into an
205     * entry,and returns an list of the entries.
206     *
207     * @param clazzNames a string consist of a list of the entries joined by a
208     *        delimiter, may be null or empty in which case an empty list is returned.
209     * @param separator a delimiter for the input string.
210     * @return a list of class entries.
211     */
212    public static List<String> splitClassNames(final String clazzNames, final String separator) {
213        final List<String> res = new ArrayList<>();
214        if (clazzNames == null || clazzNames.isEmpty()) {
215            return res;
216        }
217
218        for (String clazzName : clazzNames.split(separator)) {
219            clazzName = clazzName.trim();
220            if (!clazzName.isEmpty()) {
221                res.add(clazzName);
222            }
223        }
224        return res;
225    }
226
227}