/*
* Copyright (c) 1998-2010 Jitterbit, Inc.
*
*/
package org.jitterbit.integration.server.db.infoprovider;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.apache.commons.lang.StringUtils;
import org.jitterbit.integration.data.entity.id.SourceId;
import org.jitterbit.integration.data.entity.id.TargetId;
import org.jitterbit.integration.database.driver.ConnectionParams;
import org.jitterbit.integration.database.driver.JdbcDriverDescriptor;
import org.jitterbit.integration.database.info.InformixUtils;
import org.jitterbit.integration.server.accesscontrol.ServerAccessException;
import org.jitterbit.integration.server.conf.JdbcDriversConfig;
import org.jitterbit.integration.server.db.LocationPasswordLookup;
import org.jitterbit.integration.server.db.ServerDbException;
import org.jitterbit.integration.server.exception.ServerConfigurationException;
/**
* A factory for opening connections to source and target databases.
* <p>
* This class is not thread-safe.
*
* @author Torgil Zethson
*
* @since 3.0.0
*/
public final class DefaultConnectionFactory implements ConnectionFactory {
// TODO: Allow not passing a ConnectionParams, in which case the connection parameters
// will be looked up from the database.
private LocationPasswordLookup pwdLookup;
private final ConnectionParams connectionParams;
private final SourceId sourceGuid;
private final TargetId targetGuid;
private JdbcDriverDescriptor driver;
public DefaultConnectionFactory(ConnectionParams connectionParams, SourceId sourceGuid, TargetId targetGuid) {
this.connectionParams = connectionParams;
this.sourceGuid = sourceGuid;
this.targetGuid = targetGuid;
}
/**
* Provides this connection factory with a <code>LocationPasswordLookup</code> from which the
* source or target password can be looked up if it is not provided in the connection
* parameters. This can be the case e.g. when the client does a Test Connection to a DB source
* or target that has already been deployed; the password has been nulled out on the client so
* it is not included in the connection parameters, but it can be looked up from the deployed
* data here on the server side.
*
*/
public void setLocationPasswordLookup(LocationPasswordLookup lookup) {
pwdLookup = lookup;
}
/**
* Opens a connection to the source or target database. <strong>Note:</strong> It is the
* responsibility of the caller to close the connection when done.
*
* @return the opened <code>Connection</code>
*/
@Override
public Connection newConnection() throws ServerDbException, ServerAccessException, SQLException {
try {
JdbcDriverDescriptor driver = getDriver();
driver.loadDriverClass();
String url = driver.getConnectionString(connectionParams);
String user = connectionParams.getUser();
if (StringUtils.isEmpty(user)) {
// Assume that the user name and password is defined manually in the connection string.
return DriverManager.getConnection(url);
}
String password = getPassword();
return DriverManager.getConnection(url, user, password);
} catch (ServerConfigurationException ex) {
throw new ServerDbException("The Jitterbit server configuration is incorrect: " + ex.getMessage(), ex);
} catch (ClassNotFoundException ex) {
throw new ServerDbException("The driver could not be found. "
+ "Make sure the driver is on the classpath: " + ex.getMessage(), ex);
} catch (NoClassDefFoundError ex) {
throw new ServerDbException("The driver was found, but one of its required components could not be " +
"accessed correctly. Make sure all required driver libraries (JAR files) are installed " +
"correctly. The reported error message was: " + ex.toString(), ex);
} catch (ServerDbException ex) {
throw new ServerDbException("An error occurred while accessing the Jitterbit backend database: "
+ ex.getMessage(), ex);
}
}
private JdbcDriverDescriptor getDriver() throws ServerConfigurationException {
if (driver == null) {
driver = JdbcDriversConfig.getConfig().getDriverDescriptor(connectionParams.getDriverName());
}
return driver;
}
public boolean isInformixConnection() throws ServerConfigurationException {
return InformixUtils.isInformix(getDriver());
}
private String getPassword() throws ServerDbException, ServerAccessException {
String pwd = connectionParams.getPassword();
if (pwd == null && pwdLookup != null) {
pwd = pwdLookup.lookupPassword(sourceGuid, targetGuid);
}
return pwd;
}
}