JdbcPoolService.java 8.74 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.commons.datasource.poolservice.DataSourcePoolProvider
 *  org.osgi.framework.BundleContext
 *  org.osgi.framework.ServiceRegistration
 *  org.osgi.service.component.ComponentContext
 *  org.osgi.service.log.LogService
 */
package com.day.commons.datasource.jdbcpool;

import com.day.commons.datasource.poolservice.DataSourcePoolProvider;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.sql.DataSource;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.KeyedObjectPoolFactory;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.log.LogService;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
public class JdbcPoolService
implements DataSourcePoolProvider {
    private LogService log;
    public static final int DEFAULT_POOL_SIZE = 10;
    public static final int DEFAULT_MAX_WAIT_MSEC = 1000;
    public static final int MAX_WAIT_DONT_WAIT = 0;
    public static final int MAX_WAIT_BLOCK = -1;
    public static final String OSGI_PROPERTY_JDBC_DRIVER_CLASS = "jdbc.driver.class";
    public static final String OSGI_PROPERTY_JDBC_CONNECTION_URI = "jdbc.connection.uri";
    public static final String OSGI_PROPERTY_JDBC_USERNAME = "jdbc.username";
    public static final String OSGI_PROPERTY_JDBC_PASSWORD = "jdbc.password";
    public static final String OSGI_PROPERTY_JDBC_VALIDATION_QUERY = "jdbc.validation.query";
    public static final String OSGI_PROPERTY_DEFAULT_READ_ONLY = "default.readonly";
    public static final String OSGI_PROPERTY_DEFAULT_AUTO_COMMIT = "default.autocommit";
    public static final String OSGI_PROPERTY_POOL_SIZE = "pool.size";
    public static final String OSGI_PROPERTY_MAX_WAIT_MSEC = "pool.max.wait.msec";
    public static final String OSGI_PROPERTY_DATASOURCE_NAME = "datasource.name";
    public static final String OSGI_PROPERTY_DATASOURCE_SVC_PROPS = "datasource.svc.properties";
    private String name;
    private PoolingDataSource dataSource;
    private GenericObjectPool connectionPool;
    private ServiceRegistration dsRegistration;

    public Object getDataSource(String name) {
        if (name.equals(this.name)) {
            return this.dataSource;
        }
        return null;
    }

    public String[] getNames() {
        if (this.name == null) {
            return new String[0];
        }
        return new String[]{this.name};
    }

    protected void activate(ComponentContext componentContext) throws Exception {
        if (this.name != null) {
            throw new IllegalStateException("Already activated with name=" + this.name);
        }
        Dictionary properties = componentContext.getProperties();
        String newName = (String)properties.get("datasource.name");
        if (newName == null || newName.trim().length() == 0) {
            throw new Exception("Missing configuration property datasource.name");
        }
        if (this.log != null) {
            this.log.log(3, "Configuring and activating data source with name=" + newName);
        }
        this.setupDataSource(newName, JdbcPoolService.createConfig(properties));
        Hashtable<String, String> dsProps = new Hashtable<String, String>();
        dsProps.put("datasource.name", newName);
        String[] dsCfgProps = (String[])componentContext.getProperties().get("datasource.svc.properties");
        if (dsCfgProps != null) {
            for (String nv : dsCfgProps) {
                int idx = nv.indexOf(61);
                if (idx <= 0) continue;
                dsProps.put(nv.substring(0, idx).trim(), nv.substring(idx + 1).trim());
            }
        }
        if (this.dataSource != null) {
            this.dsRegistration = componentContext.getBundleContext().registerService(DataSource.class.getName(), (Object)this.dataSource, dsProps);
        }
    }

    protected void deactivate(ComponentContext componentContext) {
        if (this.log != null) {
            this.log.log(3, "deactivating data source with name=" + this.name);
        }
        this.name = null;
        if (this.dsRegistration != null) {
            this.dsRegistration.unregister();
            this.dsRegistration = null;
        }
        if (this.connectionPool != null) {
            block5 : {
                try {
                    this.connectionPool.close();
                }
                catch (Exception e) {
                    if (this.log == null) break block5;
                    this.log.log(1, "Error while closing connection pool", (Throwable)e);
                }
            }
            this.connectionPool = null;
        }
        this.dataSource = null;
    }

    void setupDataSource(String newName, DataSourceConfig cfg) {
        if (this.name != null) {
            throw new IllegalStateException("Already configured with name '" + this.name + "'");
        }
        this.initalizeDriver(cfg.driverClassToLoad);
        this.connectionPool = new GenericObjectPool(null);
        this.connectionPool.setMaxActive((int)cfg.poolSize);
        if (cfg.maxWaitMsec <= 0) {
            throw new IllegalArgumentException("For now, DataSourceConfig.maxWaitMsec must be >= 0");
        }
        this.connectionPool.setWhenExhaustedAction(1);
        this.connectionPool.setMaxWait(cfg.maxWaitMsec);
        DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(cfg.connectionURI, cfg.username, cfg.password);
        KeyedObjectPoolFactory kopf = null;
        new PoolableConnectionFactory(connectionFactory, this.connectionPool, kopf, cfg.validationQuery, cfg.defaultReadOnly, cfg.defaultAutoCommit);
        this.dataSource = new PoolingDataSource(this.connectionPool);
        if (this.log != null) {
            this.log.log(3, "Datasource configured, name=" + newName + ", connectionURI=" + cfg.connectionURI + ", default readonly=" + cfg.defaultReadOnly + ", default autocommit=" + cfg.defaultAutoCommit + ", validation query=" + cfg.validationQuery);
        }
        this.name = newName;
    }

    protected static String nullIfEmpty(String str) {
        if (str == null || str.trim().length() == 0) {
            return null;
        }
        return str;
    }

    static DataSourceConfig createConfig(Dictionary<String, Object> params) {
        DataSourceConfig result = new DataSourceConfig();
        result.driverClassToLoad = PropertiesUtil.toString(params.get("jdbc.driver.class"), null);
        result.connectionURI = PropertiesUtil.toString(params.get("jdbc.connection.uri"), null);
        result.username = JdbcPoolService.nullIfEmpty(PropertiesUtil.toString(params.get("jdbc.username"), null));
        result.password = JdbcPoolService.nullIfEmpty(PropertiesUtil.toString(params.get("jdbc.password"), null));
        result.validationQuery = JdbcPoolService.nullIfEmpty(PropertiesUtil.toString(params.get("jdbc.validation.query"), null));
        result.defaultReadOnly = PropertiesUtil.toBoolean(params.get("default.readonly"), false);
        result.defaultAutoCommit = PropertiesUtil.toBoolean(params.get("default.autocommit"), true);
        result.poolSize = PropertiesUtil.toLong(params.get("pool.size"), 10);
        result.maxWaitMsec = PropertiesUtil.toLong(params.get("pool.max.wait.msec"), 1000);
        return result;
    }

    private void initalizeDriver(String driverClassName) {
        if (driverClassName != null) {
            try {
                ClassLoader loader = this.getClass().getClassLoader();
                Class driverClass = loader.loadClass(driverClassName);
                driverClass.newInstance();
            }
            catch (Throwable t) {
                throw new IllegalArgumentException("Cannot initialize driver '" + driverClassName + "'", t);
            }
        }
    }

    protected void bindLog(LogService logService) {
        this.log = logService;
    }

    protected void unbindLog(LogService logService) {
        if (this.log == logService) {
            this.log = null;
        }
    }

    static class DataSourceConfig {
        String driverClassToLoad;
        String connectionURI;
        String username;
        String password;
        String validationQuery;
        boolean defaultReadOnly;
        boolean defaultAutoCommit;
        long poolSize = 10;
        long maxWaitMsec = 1000;

        DataSourceConfig() {
        }
    }

}