
com.googlecode.mycontainer.datasource.DataSourceDeployer Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2008 Whohoo Licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
* law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.googlecode.mycontainer.datasource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.sql.DataSource;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import com.googlecode.mycontainer.jta.TxEntry;
import com.googlecode.mycontainer.kernel.KernelRuntimeException;
import com.googlecode.mycontainer.kernel.ShutdownHook;
import com.googlecode.mycontainer.kernel.deploy.DeployException;
import com.googlecode.mycontainer.kernel.deploy.Deployer;
public class DataSourceDeployer extends Deployer implements ShutdownHook, DataSource {
private static final long serialVersionUID = -2510091316151254781L;
private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(DataSourceDeployer.class);
private String transcationManagerName = "TransactionManager";
private String driver;
private String url;
private String user;
private String pass;
private String name;
private String newConnectionSql;
private PrintWriter logWriter;
private int loginTimeout;
public void setTranscationManagerName(String transcationManagerName) {
this.transcationManagerName = transcationManagerName;
}
public void setName(String name) {
this.name = name;
}
public void setDriver(String driver) {
this.driver = driver;
}
public void setUrl(String url) {
this.url = url;
}
public void setUser(String user) {
this.user = user;
}
public void setPass(String pass) {
this.pass = pass;
}
public void setNewConnectionSql(String newConnectionSql) {
this.newConnectionSql = newConnectionSql;
}
public void deploy() {
try {
Context ctx = getContext();
LOG.info("Deploying: " + name);
ctx.bind(name, this);
getKernel().addShutdownHook(this);
} catch (NamingException e) {
throw new DeployException(e);
}
}
public void shutdown() {
try {
Context ctx = getContext();
LOG.info("Undeploying: " + name);
ctx.unbind(name);
} catch (NamingException e) {
throw new DeployException(e);
}
}
public Connection getConnection() throws SQLException {
return getConnection(user, pass);
}
public Connection getConnection(String username, String password) {
Connection ret = null;
try {
Context ctx = getContext();
TransactionManager tm = (TransactionManager) ctx.lookup(transcationManagerName);
if (tm.getStatus() == Status.STATUS_NO_TRANSACTION) {
ret = createConnection();
return ret;
}
Transaction tx = tm.getTransaction();
TxEntry entry = new TxEntry(tx, name);
Map connections = lookupConnections();
ret = connections.get(entry);
if (ret != null) {
return ret;
}
ret = createConnection();
ret = enlist(ret, tx);
connections.put(entry, ret);
ConnectionResourceSynchronization sync = new ConnectionResourceSynchronization(connections, entry);
tx.registerSynchronization(sync);
return ret;
} catch (ClassNotFoundException e) {
rollbackAndClose(ret);
throw new DeployException(e);
} catch (SQLException e) {
rollbackAndClose(ret);
throw new DeployException(e);
} catch (NamingException e) {
rollbackAndClose(ret);
throw new DeployException(e);
} catch (SystemException e) {
rollbackAndClose(ret);
throw new DeployException(e);
} catch (RollbackException e) {
rollbackAndClose(ret);
throw new DeployException(e);
} catch (RuntimeException e) {
rollbackAndClose(ret);
throw e;
}
}
private Connection createConnection() throws ClassNotFoundException, SQLException {
Connection ret;
Class.forName(driver);
ret = DriverManager.getConnection(url, user, pass);
ret.setAutoCommit(false);
handleNewConnection(ret);
return ret;
}
private void handleNewConnection(Connection con) throws SQLException {
if (newConnectionSql != null && newConnectionSql.trim().length() > 0) {
Statement st = con.createStatement();
try {
st.execute(newConnectionSql);
} finally {
try {
st.close();
} catch (SQLException ex) {
LOG.error("Error closing st.", ex);
}
}
try {
con.commit();
} catch (Exception e) {
throw new RuntimeException("error commiting newConnectionSql", e);
}
}
}
@SuppressWarnings("unchecked")
private Map lookupConnections() {
Context ctx = getContext();
try {
try {
Map ret = (Map) ctx.lookup("tl/ds/connections");
return ret;
} catch (NameNotFoundException e) {
Map ret = new HashMap();
ctx.bind("tl/ds/connections", ret);
return ret;
}
} catch (NamingException e) {
throw new KernelRuntimeException(e);
}
}
private void rollbackAndClose(Connection ret) {
if (ret != null) {
try {
ret.rollback();
ret.close();
} catch (Exception e) {
LOG.error("Error closing", e);
}
}
}
private Connection enlist(Connection ret, Transaction tx) {
try {
ConnectionResource resource = new ConnectionResource(name, ret);
tx.enlistResource(resource);
return resource.getProxy();
} catch (SystemException e) {
throw new KernelRuntimeException(e);
} catch (IllegalStateException e) {
throw new KernelRuntimeException(e);
} catch (RollbackException e) {
throw new KernelRuntimeException(e);
}
}
public PrintWriter getLogWriter() throws SQLException {
return this.logWriter;
}
public int getLoginTimeout() throws SQLException {
return this.loginTimeout;
}
public void setLogWriter(PrintWriter out) throws SQLException {
this.logWriter = out;
}
public void setLoginTimeout(int seconds) throws SQLException {
this.loginTimeout = seconds;
}
public boolean isWrapperFor(Class> iface) throws SQLException {
throw new KernelRuntimeException("unsupported opration");
}
public T unwrap(Class iface) throws SQLException {
throw new KernelRuntimeException("unsupported opration");
}
public Logger getParentLogger() {
throw new KernelRuntimeException("unsupported opration");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy