/* * ==================== * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common Development * and Distribution License("CDDL") (the "License"). You may not use this file * except in compliance with the License. * * You can obtain a copy of the License at * http://opensource.org/licenses/cddl1.php * See the License for the specific language governing permissions and limitations * under the License. * * When distributing the Covered Code, include this CDDL Header Notice in each file * and include the License file at http://opensource.org/licenses/cddl1.php. * If applicable, add the following below this CDDL Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * ==================== */ package org.identityconnectors.mysqluser; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Hashtable; import org.identityconnectors.common.StringUtil; import org.identityconnectors.common.logging.Log; import org.identityconnectors.common.security.GuardedString; import org.identityconnectors.dbcommon.DatabaseConnection; import org.identityconnectors.dbcommon.JNDIUtil; import org.identityconnectors.dbcommon.SQLUtil; import org.identityconnectors.framework.common.exceptions.ConnectorException; import org.identityconnectors.framework.common.objects.ConnectorMessages; import org.identityconnectors.framework.spi.Configuration; /** * The MySQLUserConnection extends the DatabaseConnection overriding the test * method. * * @since 1.0 */ public final class MySQLUserConnection extends DatabaseConnection { /** * Setup logging for the {@link MySQLUserConnector}. */ private static final Log LOG = Log.getLog(MySQLUserConnection.class); private static final String VALIDATE_CONNECTION = "FLUSH STATUS"; /** * The configuration. */ private MySQLUserConfiguration config; /** * Use the {@link Configuration} passed in to immediately connect to a * database. * * If the {@link Connection} fails a {@link RuntimeException} will * be thrown. * * @param conn * Real connection. * @throws RuntimeException * if there is a problem creating a {@link java.sql.Connection}. */ private MySQLUserConnection(MySQLUserConfiguration config, Connection conn) { super(conn); this.config = config; } /** * Determines if the underlying JDBC {@link java.sql.Connection} is valid. * * @throws RuntimeException * if the underlying JDBC {@link java.sql.Connection} is not * valid otherwise do nothing. */ @Override public void test() { // make sure to clear any buffers in database // attempt through auto commit.. PreparedStatement stmt = null; try { LOG.info("Test connection using {0}", VALIDATE_CONNECTION); stmt = getConnection().prepareStatement(VALIDATE_CONNECTION); // valid queries will return a result set... stmt.execute(); } catch (Exception ex) { // anything, not just SQLException // nothing to do, just invalidate the connection LOG.error("Test connection fail with {0}", ex.getMessage()); SQLUtil.rollbackQuietly(getConnection()); throw ConnectorException.wrap(ex); } finally { SQLUtil.closeQuietly(stmt); } } /** * Get the instance method. * * @param config * a {@link MySQLUserConfiguration} configuration object * @return The connection instance */ static MySQLUserConnection getConnection(MySQLUserConfiguration config) { final Connection connection = getNativeConnection(config); return new MySQLUserConnection(config, connection); } /** * @param config * @return */ private static java.sql.Connection getNativeConnection(MySQLUserConfiguration config) { Connection connection; final String user = config.getUser(); final GuardedString password = config.getPassword(); final String datasource = config.getDatasource(); if (StringUtil.isNotBlank(datasource)) { final String[] jndiProperties = config.getJndiProperties(); final ConnectorMessages connectorMessages = config.getConnectorMessages(); final Hashtable<String, String> prop = JNDIUtil.arrayToHashtable(jndiProperties, connectorMessages); if (StringUtil.isNotBlank(user) && password != null) { connection = SQLUtil.getDatasourceConnection(datasource, user, password, prop); } else { connection = SQLUtil.getDatasourceConnection(datasource, prop); } } else { connection = SQLUtil.getDriverMangerConnection(config.getDriver(), MySQLUserConfiguration .getUrlString(config.getHost(), config.getPort()), config.getUser(), config.getPassword()); } // Disable auto-commit mode try { if (connection.getAutoCommit()) { connection.setAutoCommit(false); } } catch (SQLException expected) { LOG.error(expected, "Could not disable auto-commit mode"); } return connection; } /** * Close connection if pooled. */ void closeConnection() { if (getConnection() != null && StringUtil.isNotBlank(config.getDatasource())) { LOG.info("Close the connection"); dispose(); } } /** * Create new connection if pooled and taken from the datasource. * * @throws SQLException */ void openConnection() throws SQLException { if (getConnection() == null || getConnection().isClosed()) { LOG.info("Get new connection, it is closed"); setConnection(getNativeConnection(config)); } } }