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

io.mats3.util.wrappers.DataSourceWrapper Maven / Gradle / Ivy

Go to download

Mats^3 Utilities - notably the MatsFuturizer, which provides a bridge from synchronous processes to the highly asynchronous Mats^3 services.

There is a newer version: 0.19.22-2024-11-09
Show newest version
package io.mats3.util.wrappers;

import io.mats3.MatsFactory.MatsWrapper;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

import javax.sql.DataSource;

/**
 * A base Wrapper for a JDBC {@link DataSource}, which simply implements DataSource, takes a DataSource instance and
 * forwards all calls to that. Meant to be extended to add extra functionality, e.g. Spring integration.
 *
 * @author Endre Stølsvik 2021-01-26 23:45 - http://stolsvik.com/, [email protected]
 */
public class DataSourceWrapper implements DataSource, MatsWrapper {
    /**
     * This field is private - if you in extensions need the instance, invoke {@link #unwrap()}. If you want to take
     * control of the wrapped DataSource instance, then override {@link #unwrap()}.
     */
    private DataSource _targetDataSource;

    /**
     * Standard constructor, taking the wrapped {@link DataSource} instance.
     *
     * @param targetDataSource
     *            the {@link DataSource} instance which {@link #unwrap()} will return (and hence all forwarded methods
     *            will use).
     */
    public DataSourceWrapper(DataSource targetDataSource) {
        setWrappee(targetDataSource);
    }

    /**
     * No-args constructor, which implies that you either need to invoke {@link #setWrappee(DataSource)} before
     * publishing the instance (making it available for other threads), or override {@link #unwrap()} to provide the
     * desired {@link DataSource} instance. In these cases, make sure to honor memory visibility semantics - i.e.
     * establish a happens-before edge between the setting of the instance and any other threads getting it.
     */
    public DataSourceWrapper() {
        /* no-op */
    }

    /**
     * Sets the wrapped {@link DataSource}, e.g. in case you instantiated it with the no-args constructor. Do note
     * that the field holding the wrapped instance is not volatile nor synchronized. This means that if you want to
     * set it after it has been published to other threads, you will have to override both this method and
     * {@link #unwrap()} to provide for needed memory visibility semantics, i.e. establish a happens-before edge between
     * the setting of the instance and any other threads getting it.
     *
     * @param targetDataSource
     *            the {@link DataSource} which is returned by {@link #unwrap()}, unless that is overridden.
     */
    public void setWrappee(DataSource targetDataSource) {
        _targetDataSource = targetDataSource;
    }

    /**
     * @return the wrapped {@link DataSource}. All forwarding methods invokes this method to get the wrapped
     *         {@link DataSource}, thus if you want to get creative wrt. how and when the DataSource is decided, you can
     *         override this method.
     */
    public DataSource unwrap() {
        if (_targetDataSource == null) {
            throw new IllegalStateException("DataSourceWrapper.getTarget():"
                    + " The target DataSource is not set!");
        }
        return _targetDataSource;
    }

    @Override
    public Connection getConnection() throws SQLException {
        return unwrap().getConnection();
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return unwrap().getConnection(username, password);
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return unwrap().getLogWriter();
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        unwrap().setLogWriter(out);
    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        unwrap().setLoginTimeout(seconds);
    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return unwrap().getLoginTimeout();
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return unwrap().getParentLogger();
    }

    @Override
    public  T unwrap(Class iface) throws SQLException {
        if (iface.isInstance(this)) {
            @SuppressWarnings("unchecked")
            T t = (T) this;
            return t;
        }
        return unwrap().unwrap(iface);
    }

    @Override
    public boolean isWrapperFor(Class iface) throws SQLException {
        return iface.isInstance(this) || unwrap().isWrapperFor(iface);
    }

    @Override
    public String toString() {
        return this.getClass().getSimpleName() + " for target DataSource [" + unwrap() + "]";
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy