All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.echocat.jsu.AutoCloseableUtils Maven / Gradle / Ivy

package org.echocat.jsu;

import org.echocat.jsu.support.Callable;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.Closeable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import static java.lang.reflect.Proxy.newProxyInstance;

public final class AutoCloseableUtils {

    @Nonnull
    private static final Method CLOSE_METHOD = resolveCloseMethodOf(AutoCloseable.class);
    @Nonnull
    private static final Method CLOSEABLE_CLOSE_METHOD = resolveCloseMethodOf(Closeable.class);
    @Nonnull
    private static final Method RESULT_SET_CLOSE_METHOD = resolveCloseMethodOf(ResultSet.class);
    @Nonnull
    private static final Method STATEMENT_CLOSE_METHOD = resolveCloseMethodOf(Statement.class);
    @Nonnull
    private static final Method CONNECTION_CLOSE_METHOD = resolveCloseMethodOf(Connection.class);

    public static void closeQuietly(@Nullable Object closeable) {
        try {
            if (closeable instanceof AutoCloseable) {
                ((AutoCloseable) closeable).close();
            }
        } catch (final Exception ignored) {}
    }

    @Nonnull
    public static  T doOnClose(@Nonnull Class type, @Nonnull T instance, @Nullable Callable... callablesExecuteOnClose) {
        if (callablesExecuteOnClose == null || callablesExecuteOnClose.length == 0) {
            return instance;
        }
        final Method specificCloseMethod = typeSpecificCloseMethodOf(instance);
        //noinspection unchecked
        return (T) newProxyInstance(type.getClassLoader(), new Class[]{type}, (proxy, method, args) -> {
            try {
                return method.invoke(instance, args);
            } catch (final InvocationTargetException e) {
                //noinspection ThrowInsideCatchBlockWhichIgnoresCaughtException
                throw e.getTargetException();
            } finally {
                if (CLOSE_METHOD.equals(method) || method.equals(specificCloseMethod)) {
                    call(callablesExecuteOnClose);
                }
            }
        });
    }

    @Nullable
    static Method typeSpecificCloseMethodOf(@Nonnull Object instance) {
        if (instance instanceof ResultSet) {
            return RESULT_SET_CLOSE_METHOD;
        }
        if (instance instanceof Statement) {
            return STATEMENT_CLOSE_METHOD;
        }
        if (instance instanceof Connection) {
            return CONNECTION_CLOSE_METHOD;
        }
        if (instance instanceof Closeable) {
            return CLOSEABLE_CLOSE_METHOD;
        }
        return null;
    }

    static void call(@Nullable Callable... callablesExecuteOnClose) throws Exception {
        if (callablesExecuteOnClose != null) {
            for (final Callable callable : callablesExecuteOnClose) {
                callable.call();
            }
        }
    }

    @Nonnull
    static Method resolveCloseMethodOf(@Nonnull Class type) {
        try {
            return type.getMethod("close");
        } catch (final NoSuchMethodException e) {
            throw new IllegalStateException("Could not find close() method of " + type.getName() + ".", e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy