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

xpertss.ds.jdbc.JdbcOriginDataSource Maven / Gradle / Ivy

Go to download

A modern high speed connection pool that supports multiple connection types.

There is a newer version: 2.6
Show newest version
package xpertss.ds.jdbc;

import xpertss.ds.DataSourceException;
import xpertss.ds.JdbcDataSource;
import xpertss.ds.base.BaseOriginDataSource;
import xpertss.ds.jdbc.spi.JdbcDriverService;
import xpertss.ds.jdbc.spi.JdbcDriverSupport;
import xpertss.ds.utils.NumberUtils;
import xpertss.ds.utils.ServiceLoader;
import xpertss.ds.utils.TimeProvider;

import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;
import java.util.Set;


/**
 * Implements an origin data source which provides raw JDBC connections.
 * 

* The major downfall of the property approach is that we won't know we * have an invalid property until we use the connections and even then * we might miss it. * * @author cfloersch */ public class JdbcOriginDataSource extends BaseOriginDataSource implements JdbcDataSource, JdbcOriginDataSourceMBean, Referenceable { private static ServiceLoader loader = ServiceLoader.load(JdbcDriverService.class); private volatile boolean closed = false; private volatile long lastFail = 0; // not persisted across jndi context storage private String name; private Driver driver; private JdbcDriverSupport support; private long blackout = 30000; JdbcOriginDataSource() { super(Type.Origin); } public synchronized String getName() { if(name == null) { String uri = getProperty(URL); if(uri != null && support != null) { name = support.parseName(uri); } if(name == null) { if(support != null) { return "Unknown " + support.vendorName() + " Database"; } else { return "Unknown JDBC Database"; } } } return name; } public boolean isAvailable() { return (TimeProvider.get().milliTime() - lastFail > blackout); } public Connection getConnection() throws DataSourceException { if(closed) throw new DataSourceException("datasource.closed"); if(!isAvailable()) throw new DataSourceException("datasource.unavailable"); try { return create(getProperty(USERNAME), getProperty(PASSWORD)); } catch (DataSourceException dse) { lastFail = TimeProvider.get().milliTime(); throw dse; } catch (SQLException e) { lastFail = TimeProvider.get().milliTime(); throw new DataSourceException("connect.failed", e); } catch (RuntimeException e) { lastFail = TimeProvider.get().milliTime(); throw new DataSourceException("connect.failed", e); } } public String setProperty(String key, String value) { String result = super.setProperty(key, value); if(DRIVER.equals(key)) { driver = null; support = null; name = null; for(JdbcDriverService service : loader) { support = service.createSupport(value); if(support != null) break; } } else if(URL.equals(key)) { name = null; } else if(BLACKOUT.equals(key)) { blackout = NumberUtils.getLong(getProperty(BLACKOUT), 30) * 1000; } return result; } public String clearProperty(String key) { String result = super.clearProperty(key); if(DRIVER.equals(key)) { driver = null; support = null; name = null; } else if(URL.equals(key)) { name = null; } else if(BLACKOUT.equals(key)) { blackout = 30000; } return result; } public void close() { closed = true; } // javax.naming.Referenceable Impl public Reference getReference() throws NamingException { Reference ref = createReference(JdbcDataSource.class, JdbcDataSourceFactory.class); for(Map.Entry e : getPropertySet()) { ref.add(new StringRefAddr(e.getKey(), e.getValue())); } return ref; } public String[] getProperties() { int index = 0; Set> props = getPropertySet(); String[] results = new String[props.size()]; for(Map.Entry e : props) { results[index++] = e.getKey() + ": " + e.getValue(); } return results; } private Connection create(String username, String password) throws SQLException, DataSourceException { Properties props = new Properties(); int connect_timeout = getPositiveInt(CONNECT_TIMEOUT, 0); int read_timeout = getPositiveInt(READ_TIMEOUT, 0); // Decided to let support runtime errors propagate if(support != null) support.configureTimeouts(props, connect_timeout, read_timeout); // Set username/password after making call to service provider if(username != null) props.put("user", username); if(password != null) props.put("password", password); if(driver == null) driver = createDriver(); Connection conn = driver.connect(getProperty(URL), props); if(conn == null) throw new DataSourceException("url.invalid"); conn.setAutoCommit(getBoolean(AUTO_COMMIT, true)); // specification default (true) conn.setReadOnly(getBoolean(READ_ONLY, false)); // specification default (false) conn.setTransactionIsolation(getIsolation().getValue()); conn.setHoldability(getHoldability().getValue()); return conn; } private Isolation getIsolation() { try { return Isolation.valueOf(getProperty(ISOLATION)); } catch(Exception e) { return Isolation.Serializable; // specification default } } private Holdability getHoldability() { try { return Holdability.valueOf(getProperty(HOLDABILITY)); } catch(Exception e) { return Holdability.Hold; // specification default } } private Driver createDriver() throws DataSourceException { try { return (Driver) Class.forName(getProperty(DRIVER)).newInstance(); } catch(ClassCastException cce) { throw new DataSourceException("driver.invalid"); } catch(ClassNotFoundException cnfe) { throw new DataSourceException("driver.missing"); } catch(Exception e) { throw new DataSourceException("driver.failed", e); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy