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
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2016 ForgeRock AS.
015 */
016
017package org.forgerock.util;
018
019import static org.forgerock.util.Reject.checkNotNull;
020
021import java.io.Closeable;
022
023/**
024 * {@link Function} that silently closes an input-parameter after a delegate-function's {@link Function#apply(Object)}
025 * is invoked. The static {@link #closeSilently(Function)} method is provided for convenience.
026 *
027 * @param <VIN>
028 *            The type of the function input-parameter, which implements {@code Closeable}.
029 * @param <VOUT>
030 *            The type of the function result, or {@link Void} if the function
031 *            does not return anything (i.e. it only has side-effects).
032 * @param <E>
033 *            The type of the exception thrown by the function, or
034 *            {@link org.forgerock.util.promise.NeverThrowsException} if no exception is thrown by the
035 *            function.
036 */
037public class CloseSilentlyFunction<VIN extends Closeable, VOUT, E extends Exception> implements Function<VIN, VOUT, E> {
038
039    private final Function<VIN, VOUT, E> delegate;
040
041    /**
042     * Creates a new {@code CloseSilentlyFunction} instance.
043     *
044     * @param delegate Delegate function.
045     */
046    public CloseSilentlyFunction(final Function<VIN, VOUT, E> delegate) {
047        this.delegate = checkNotNull(delegate);
048    }
049
050    /**
051     * Invokes the delegate function's {@link Function#apply(Object)} with the input parameter {@code value}, closes it,
052     * and returns the result.
053     *
054     * @param value {@code Closeable} input parameter.
055     * @return The result of applying delegate function to {@code value}.
056     * @throws E Propagates {@code Exception} thrown by delegate {@link Function}.
057     */
058    @Override
059    public VOUT apply(final VIN value) throws E {
060        try {
061            return delegate.apply(value);
062        } finally {
063            Utils.closeSilently(value);
064        }
065    }
066
067    /**
068     * Wraps a delegate function in a {@code CloseSilentlyFunction}.
069     *
070     * @param delegate Delegate function.
071     * @param <IN>
072     *          The type of the function input-parameter, which implements {@code Closeable}.
073     * @param <OUT>
074     *          The type of the function result, or {@link Void} if the function does not return anything
075     *          (i.e. it only has side-effects).
076     * @param <EX> The type of the exception thrown by the function, or
077     *            {@link org.forgerock.util.promise.NeverThrowsException} if no exception is thrown by the function.
078     * @return New {@code CloseSilentlyFunction} instance.
079     */
080    public static <IN extends Closeable, OUT, EX extends Exception> Function<IN, OUT, EX> closeSilently(
081            final Function<IN, OUT, EX> delegate) {
082        return new CloseSilentlyFunction<>(delegate);
083    }
084
085}