001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the License.
004 *
005 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
006 * specific language governing permission and limitations under the License.
007 *
008 * When distributing Covered Software, include this CDDL Header Notice in each file and include
009 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
010 * Header, with the fields enclosed by brackets [] replaced by your own identifying
011 * information: "Portions copyright [year] [name of copyright owner]".
012 *
013 * Copyright 2015 ForgeRock AS.
014 */
015package org.forgerock.util;
016
017/**
018 * A input parameter-validating utility class using fluent invocation:
019 *
020 * <pre>
021 * public int divide(int dividend, int divisor) {
022 *     Reject.ifTrue(divisor == 0, &quot;Division by zero not supported&quot;);
023 *     return dividend / divisor;
024 * }
025 * </pre>
026 *
027 * The example above will cause an {@code IllegalArgumentException} to be thrown
028 * with the message given.
029 * <p>
030 * Another use case is validating constructor parameters:
031 *
032 * <pre>
033 * public TokenManager(final TokenFactory factory) {
034 *     Reject.ifNull(factory, &quot;Cannot instantiate TokenManager with null TokenFactory&quot;);
035 * }
036 * </pre>
037 *
038 * Sometimes, constructor parameters are passed to ancestor constructors which
039 * must be called first--thus, the {@code checkNotNull} syntax is available:
040 *
041 * <pre>
042 *     import static org.forgerock.util.Reject.checkNotNull;
043 *
044 *     public TokenManager(final TokenFactory factory) {
045 *         super(checkNotNull(factory));
046 *     }
047 * </pre>
048 *
049 * Note that the methods herein throw generic RuntimeExceptions as opposed to
050 * custom, application-specific error Exceptions. This class is intended for
051 * wide use among multiple projects whose Exception frameworks may differ. The
052 * implementer is encouraged to catch the generic exceptions thrown by this
053 * class and rethrow exceptions appropriate to the target application.
054 */
055public final class Reject {
056
057    /**
058     * Throws a {@code NullPointerException} if the <tt>object</tt> parameter is
059     * null, returns the object otherwise.
060     *
061     * @param <T>
062     *            The type of object to test.
063     * @param object
064     *            the object to test
065     * @return the object
066     * @throws NullPointerException
067     *             if {@code object} is null
068     */
069    public static <T> T checkNotNull(final T object) {
070        return checkNotNull(object, null);
071    }
072
073    /**
074     * Throws a {@code NullPointerException} if the <tt>object</tt> parameter is
075     * null, returns the object otherwise.
076     *
077     * @param <T>
078     *            The type of object to test.
079     * @param object
080     *            the object to test
081     * @param message
082     *            a custom exception message to use
083     * @return the object
084     * @throws NullPointerException
085     *             if {@code object} is null
086     */
087    public static <T> T checkNotNull(final T object, final String message) {
088        if (object == null) {
089            throw new NullPointerException(message);
090        }
091        return object;
092    }
093
094    /**
095     * Throws an {@code IllegalArgumentException} if the <tt>condition</tt>
096     * parameter is false.
097     *
098     * @param condition
099     *            the condition to test
100     * @throws IllegalArgumentException
101     *             if {@code condition} is false
102     */
103    public static void ifFalse(final boolean condition) {
104        ifFalse(condition, "Expected condition was true, found false");
105    }
106
107    /**
108     * Throws an {@code IllegalArgumentException} with a custom {@code message}
109     * if the <tt>condition</tt> parameter is false.
110     *
111     * @param condition
112     *            the condition to test
113     * @param message
114     *            a custom exception message to use
115     * @throws IllegalArgumentException
116     *             if {@code condition} is false
117     */
118    public static void ifFalse(final boolean condition, final String message) {
119        if (!condition) {
120            throw new IllegalArgumentException(message);
121        }
122    }
123
124    /**
125     * Alias for {@code checkNotNull} to be used in fluent {@code Reject.ifNull}
126     * syntax. Throws a {@code NullPointerException} if the <tt>object</tt>
127     * parameter is null.
128     *
129     * @param object
130     *            the object to test
131     * @throws NullPointerException
132     *             if {@code object} is null
133     */
134    public static void ifNull(final Object object) {
135        ifNull(object, null);
136    }
137
138    /**
139     * Throws a {@code NullPointerException} if any of the provided arguments
140     * are {@code null}.
141     *
142     * @param <T>
143     *            The type of object to test.
144     * @param objects
145     *            The objects to test.
146     * @throws NullPointerException
147     *             If any of the provided arguments are {@code null}.
148     */
149    @SafeVarargs
150    public static <T> void ifNull(final T... objects) {
151        /*
152         * This method is generic in order to play better with varargs.
153         * Otherwise invoking this method with an array of Strings will be
154         * flagged with a warning because of the potential ambiguity. See
155         * org.forgerock.util.RejectTest.ifNullVarArgsStrings().
156         */
157        for (final Object o : objects) {
158            if (o == null) {
159                throw new NullPointerException();
160            }
161        }
162    }
163
164    /**
165     * Alias for {@code checkNotNull} to be used in fluent {@code Reject.ifNull}
166     * syntax. Throws a {@code NullPointerException} if the <tt>object</tt>
167     * parameter is null.
168     *
169     * @param object
170     *            the object to test
171     * @param message
172     *            a custom exception message to use
173     * @throws NullPointerException
174     *             if {@code object} is null
175     */
176    public static void ifNull(final Object object, final String message) {
177        checkNotNull(object, message);
178    }
179
180    /**
181     * Throws an {@code IllegalArgumentException} if the <tt>condition</tt>
182     * parameter is true.
183     *
184     * @param condition
185     *            the condition to test
186     * @throws IllegalArgumentException
187     *             if {@code condition} is true
188     */
189    public static void ifTrue(final boolean condition) {
190        ifTrue(condition, "Expected condition was false, found true");
191    }
192
193    /**
194     * Throws an {@code IllegalArgumentException} with a custom {@code message}
195     * if the <tt>condition</tt> parameter is true.
196     *
197     * @param condition
198     *            the condition to test
199     * @param message
200     *            a custom exception message to use
201     * @throws IllegalArgumentException
202     *             if {@code condition} is true
203     */
204    public static void ifTrue(final boolean condition, final String message) {
205        if (condition) {
206            throw new IllegalArgumentException(message);
207        }
208    }
209
210    // Prevent instantiation
211    private Reject() {
212        // nothing to do
213    }
214
215}