com.adaptris.jdbc.connection.FailoverConfig.java Source code

Java tutorial

Introduction

Here is the source code for com.adaptris.jdbc.connection.FailoverConfig.java

Source

/*
 * Copyright 2015 Adaptris Ltd.
 * 
 * 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.adaptris.jdbc.connection;

import static org.apache.commons.lang.StringUtils.isEmpty;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.adaptris.core.util.Args;

/**
 * Class that is used to configure a failover database connection.
 *
 * @see FailoverConnection
 * @author lchan
 * @author $Author: lchan $
 */
public final class FailoverConfig implements Cloneable {

    private boolean verbose;
    private List<String> connectionUrls;
    private String databaseDriver;
    private String testStatement;
    private boolean autoCommit;
    private boolean alwaysValidateConnection;
    private String username;
    private String password;
    private Properties connectionProperties;

    private static final String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
    private static final String MYSQL_TEST_STMT = "SELECT DATABASE(), VERSION(), NOW(), USER();";

    /**
     * resource key for driver classname
     */
    public static final String JDBC_DRIVER = "jdbc.driver.classname";

    /**
     * Resource key for testing a connection.
     *
     */
    public static final String JDBC_TEST_STATEMENT = "jdbc.driver.test";

    /**
     * resource key for driver url
     */
    public static final String JDBC_URL_ROOT = "jdbc.driver.url";

    /**
     * resource key for driver autocommit setting
     */
    public static final String JDBC_AUTO_COMMIT = "jdbc.driver.autocommit";

    /**
     * resource key for connection verify setting
     */
    public static final String JDBC_ALWAYS_VERIFY = "jdbc.driver.alwaysverify";

    /**
     * resource key specifying extra debug.
     *
     */
    public static final String JDBC_DEBUG = "jdbc.driver.debug";

    /**
     * resource key for specifying the username
     */
    public static final String JDBC_USERNAME = "jdbc.username";

    /**
     * resource key for specifying the password
     */
    public static final String JDBC_PASSWORD = "jdbc.password";

    /**
     * @see Object#Object()
     *
     *
     */
    public FailoverConfig() {
        setConnectionUrls(new ArrayList<String>());
        setDatabaseDriver(MYSQL_DRIVER);
        setTestStatement(MYSQL_TEST_STMT);
        setAutoCommit(true);
        setAlwaysValidateConnection(true);
        setConnectionProperties(new Properties());
        setUsername(null);
        setPassword(null);
    }

    /**
     * Constructor using a pre-existing map.
     * <p>
     * This allows us to easily configure the repository from a set of properties.
     * </p>
     * <p>
     * The properties object is expected to contain the following keys with associated values
     * <ul>
     * <li>jdbc.driver.classname - this represents the jdbc driver classname</li>
     * <li>jdbc.driver.url.n - where n is some unique identifier. Each of these entries will specify a database connection string in
     * the general form <code>jdbc:mysql://localhost:3306/portal</code>. There must be at least one of these entries. Each entry is
     * used to as a parameter to FailoverConfig.addConnectionUrl(String s)
     * <li>jdbc.driver.autocommit - either true or false, the default is true
     * <li>jdbc.username - the username for the connection - this is optional, if all connection urls have a username/password inline.
     * <li>jdbc.password - password for the connection - this is optional, if all connection urls have a username/password inline.
     * </ul>
     * </p>
     * <p>
     * If there is more than one <code>jdbc.driver.url</code> key then the natural ordering of the keys is used to specify the order
     * in which urls are added to the <code>FailoverConfig</code> object.
     * <p>
     * An Example property file would be:-
     * 
     * <pre>
     * {@code 
     * jdbc.driver.classname=com.mysql.jdbc.Driver
     * jdbc.driver.url.1=jdbc:mysql://master:3306/portal?user=user
     * jdbc.driver.url.2=jdbc:mysql://slave1:3306/portal?user=user
     * jdbc.driver.url.3=jdbc:mysql://slave2:3306/portal?user=user
     * }
     * </pre>
     * 
     * @param map the <code>Map</code> from which we will initialise from.
     * @see #JDBC_DRIVER
     * @see #JDBC_URL_ROOT
     * @see FailoverConfig#addConnectionUrl(String)
     */
    public FailoverConfig(Properties map) {
        this();
        initialise(map);
    }

    /**
     * Set a Connection URL to the configured list.
     *
     * @param list a list of connection urls
     * @throws IllegalArgumentException if the string is null.
     */
    public void setConnectionUrls(List<String> list) {
        connectionUrls = Args.notNull(list, "connectionURLs");
    }

    /**
     * Add a Connection URL to the configured list.
     *
     * @param string a connection url
     * @throws IllegalArgumentException if the string is null.
     */
    public void addConnectionUrl(String string) {
        connectionUrls.add(Args.notBlank(string, "connectionURL"));
    }

    /**
     * Get the configured list of URLs.
     *
     * @return The configured collection of urls
     */
    public List<String> getConnectionUrls() {
        return connectionUrls;
    }

    /**
     * Get the configured database Driver for this config
     *
     * @return the database driver
     */
    public String getDatabaseDriver() {
        return databaseDriver;
    }

    /**
     * Set the database driver.
     *
     * @param string the database driver
     * @throws IllegalArgumentException if the driver is null.
     */
    public void setDatabaseDriver(String string) {
        databaseDriver = Args.notBlank(string, "databaseDriver");
    }

    /**
     * Get the statement that will test the connection.
     *
     * @return the statement
     */
    public String getTestStatement() {
        return testStatement;
    }

    /**
     * Set the statement that will test the connection.
     *
     * @param string the statement
     * @throws IllegalArgumentException if the statement is null.
     */
    public void setTestStatement(String string) throws IllegalArgumentException {
        testStatement = Args.notNull(string, "testStatement");
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        if (o == this) {
            return true;
        }
        if (o instanceof FailoverConfig) {
            FailoverConfig rhs = (FailoverConfig) o;
            return new EqualsBuilder().append(getTestStatement(), rhs.getTestStatement())
                    .append(getDebugMode(), rhs.getDebugMode()).append(getDatabaseDriver(), rhs.getDatabaseDriver())
                    .append(getAutoCommit(), rhs.getAutoCommit())
                    .append(getAlwaysValidateConnection(), rhs.getAlwaysValidateConnection())
                    .append(getConnectionUrls(), rhs.getConnectionUrls()).isEquals();
        }
        return false;
    }

    /**
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        return new HashCodeBuilder(31, 17).append(getTestStatement()).append(getDatabaseDriver())
                .append(getAutoCommit()).append(getAlwaysValidateConnection()).append(getConnectionUrls())
                .append(getDebugMode()).toHashCode();
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("driver", getDatabaseDriver())
                .append("connectionUrls", getConnectionUrls()).append("testStatement", getTestStatement())
                .append("debugMode", getDebugMode()).append("autoCommit", getAutoCommit())
                .append("alwaysValidate", getAlwaysValidateConnection()).toString();
    }

    /**
     * Get autoCommit flag for this configuration
     *
     * @return the autoCommit flag
     */
    public boolean getAutoCommit() {
        return autoCommit;
    }

    /**
     * Set the autocommit flag for this configuration
     *
     * @param b the new flag
     */
    public void setAutoCommit(boolean b) {
        autoCommit = b;
    }

    /**
     * Return whether the database connection should have further verbose logging.
     *
     * @return true or false.
     */
    public boolean getDebugMode() {
        return verbose;
    }

    /**
     * Specify verbose logging.
     *
     * @param b true or false.
     */
    public void setDebugMode(boolean b) {
        verbose = b;
    }

    /**
     * Perform initialisation from some map.
     *
     * @param p the map containing the properties.
     */
    private void initialise(Properties p) {
        setDatabaseDriver(p.getProperty(JDBC_DRIVER, MYSQL_DRIVER));
        setAutoCommit(Boolean.valueOf(p.getProperty(JDBC_AUTO_COMMIT, "true")));
        setDebugMode(Boolean.valueOf(p.getProperty(JDBC_DEBUG, "false")));
        setAlwaysValidateConnection(Boolean.valueOf(p.getProperty(JDBC_ALWAYS_VERIFY, "true")));
        if (!isEmpty(p.getProperty(JDBC_USERNAME))) {
            setUsername(p.getProperty(JDBC_USERNAME));
        }
        if (!isEmpty(p.getProperty(JDBC_PASSWORD))) {
            setPassword(p.getProperty(JDBC_PASSWORD));
        }
        List<String> connectionUrls = new ArrayList<String>();
        for (Iterator i = p.keySet().iterator(); i.hasNext();) {
            String key = (String) i.next();
            if (key.startsWith(JDBC_URL_ROOT)) {
                connectionUrls.add(p.getProperty(key));
            }
        }
        // Bug#2555
        // for (String key : p.stringPropertyNames()) {
        // if (key.startsWith(JDBC_URL_ROOT)) {
        // connectionUrls.add(p.getProperty(key));
        // }
        // }
        setConnectionUrls(connectionUrls);
        setTestStatement(p.getProperty(JDBC_TEST_STATEMENT, MYSQL_TEST_STMT));
    }

    /**
     * @see java.lang.Object#clone()
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        FailoverConfig result = (FailoverConfig) super.clone();
        result.setConnectionUrls(new ArrayList<String>(getConnectionUrls()));
        return result;
    }

    public boolean getAlwaysValidateConnection() {
        return alwaysValidateConnection;
    }

    public void setAlwaysValidateConnection(boolean b) {
        alwaysValidateConnection = b;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Properties getConnectionProperties() {
        return connectionProperties;
    }

    public void setConnectionProperties(Properties p) {
        this.connectionProperties = p;
    }
}