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

ch.vorburger.mariadb4j.DBConfigurationBuilder Maven / Gradle / Ivy

There is a newer version: 3.1.0
Show newest version
/*
 * #%L
 * MariaDB4j
 * %%
 * Copyright (C) 2012 - 2014 Michael Vorburger
 * %%
 * 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.
 * #L%
 */
package ch.vorburger.mariadb4j;

import ch.vorburger.exec.ManagedProcessListener;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.SystemUtils;

/**
 * Builder for DBConfiguration. Has lot's of sensible default conventions etc.
 */
public class DBConfigurationBuilder {

    protected static final String WIN32 = "win32";
    protected static final String LINUX = "linux";
    protected static final String OSX = "osx";

    private static final String DEFAULT_DATA_DIR = SystemUtils.JAVA_IO_TMPDIR + "/MariaDB4j/data";

    private String databaseVersion = null;

    // all these are just some defaults
    protected String osDirectoryName = SystemUtils.IS_OS_WINDOWS ? WIN32
            : SystemUtils.IS_OS_MAC ? OSX : LINUX;
    protected String baseDir = SystemUtils.JAVA_IO_TMPDIR + "/MariaDB4j/base";
    protected String libDir = null;

    protected String dataDir = DEFAULT_DATA_DIR;
    protected String socket = null; // see _getSocket()
    protected int port = 0;
    protected boolean isDeletingTemporaryBaseAndDataDirsOnShutdown = true;
    protected boolean isUnpackingFromClasspath = true;
    protected List args = new ArrayList();
    private boolean isSecurityDisabled = true;

    private boolean frozen = false;
    private ManagedProcessListener listener;

    public static DBConfigurationBuilder newBuilder() {
        return new DBConfigurationBuilder();
    }

    protected DBConfigurationBuilder() {}

    protected void checkIfFrozen(String setterName) {
        if (frozen)
            throw new IllegalStateException("cannot " + setterName + "() anymore after build()");
    }

    public String getBaseDir() {
        return baseDir;
    }

    public DBConfigurationBuilder setBaseDir(String baseDir) {
        checkIfFrozen("setBaseDir");
        this.baseDir = baseDir;
        return this;
    }

    public String getLibDir() {
        if (libDir == null)
            return baseDir + "/libs";
        else
            return libDir;
    }

    public DBConfigurationBuilder setLibDir(String libDir) {
        checkIfFrozen("setLibDir");
        this.libDir = libDir;
        return this;
    }

    public String getDataDir() {
        return dataDir;
    }

    public DBConfigurationBuilder setDataDir(String dataDir) {
        checkIfFrozen("setDataDir");
        this.dataDir = dataDir;
        return this;
    }

    public int getPort() {
        return port;
    }

    /**
     * Sets the port number.
     *
     * @param port port number, or 0 to use detectFreePort()
     * @return this
     */
    public DBConfigurationBuilder setPort(int port) {
        checkIfFrozen("setPort");
        this.port = port;
        return this;
    }

    /**
     * Set a custom process listener to listen to DB start/shutdown events
     * @param listener custom listener
     * @return this
     */
    public DBConfigurationBuilder setProcessListener(ManagedProcessListener listener) {
        this.listener = listener;
        return this;
    }

    public ManagedProcessListener getProcessListener() {
        return listener;
    }

    public boolean isDeletingTemporaryBaseAndDataDirsOnShutdown() {
        return isDeletingTemporaryBaseAndDataDirsOnShutdown;
    }

    /**
     * Defines if the configured data and base directories should be deleted on shutdown.
     * If you've set the base and data directories to non temporary directories
     * using {@link #setBaseDir(String)} or {@link #setDataDir(String)},
     * then they'll also never get deleted anyway.
     */
    public DBConfigurationBuilder setDeletingTemporaryBaseAndDataDirsOnShutdown(boolean doDelete) {
        checkIfFrozen("keepsDataAndBaseDir");
        this.isDeletingTemporaryBaseAndDataDirsOnShutdown = doDelete;
        return this;
    }

    protected int detectFreePort() {
        try {
            ServerSocket ss = new ServerSocket(0);
            port = ss.getLocalPort();
            ss.setReuseAddress(true);
            ss.close();
            return port;
        } catch (IOException e) {
            // This should never happen
            throw new RuntimeException(e);
        }
    }

    public String getSocket() {
        return socket;
    }

    public DBConfigurationBuilder setSocket(String socket) {
        checkIfFrozen("setSocket");
        this.socket = socket;
        return this;
    }

    public DBConfiguration build() {
        frozen = true;
        return new DBConfiguration.Impl(_getPort(), _getSocket(), _getBinariesClassPathLocation(), getBaseDir(), getLibDir(), _getDataDir(),
                WIN32.equals(getOS()), _getArgs(), _getOSLibraryEnvironmentVarName(), isSecurityDisabled(),
                isDeletingTemporaryBaseAndDataDirsOnShutdown(), this::getURL, getProcessListener());
    }

    /**
     * Whether to to "--skip-grant-tables" (defaults to true).
     */
    public DBConfigurationBuilder setSecurityDisabled(boolean isSecurityDisabled) {
        checkIfFrozen("setSecurityDisabled");
        this.isSecurityDisabled = isSecurityDisabled;
        return this;
    }

    public boolean isSecurityDisabled() {
        return isSecurityDisabled;
    }

    public DBConfigurationBuilder addArg(String arg) {
        checkIfFrozen("addArg");
        args.add(arg);
        return this;
    }

    protected String _getDataDir() {
        if (isNull(getDataDir()) || getDataDir().equals(DEFAULT_DATA_DIR))
            return DEFAULT_DATA_DIR + SystemUtils.FILE_SEPARATOR + getPort();
        else
            return getDataDir();
    }

    protected boolean isNull(String string) {
        if (string == null)
            return true;
        String trim = string.trim();
        if (trim.length() == 0)
            return true;
        if (trim.equalsIgnoreCase("null"))
            return true;
        return false;
    }

    protected int _getPort() {
        int port = getPort();
        if (port == 0) {
            port = detectFreePort();
        }
        return port;
    }

    protected String _getSocket() {
        String socket = getSocket();
        if (socket == null) {
            String portStr = String.valueOf(getPort());
            // Use /tmp instead getBaseDir() here, else we too easily hit
            // the "mysqld ERROR The socket file path is too long (> 107)" issue
            socket = SystemUtils.JAVA_IO_TMPDIR + "/MariaDB4j." + portStr + ".sock";
        }
        return socket;
    }

    public String getDatabaseVersion() {
        return databaseVersion;
    }

    public DBConfigurationBuilder setDatabaseVersion(String databaseVersion) {
        checkIfFrozen("setDatabaseVersion");
        this.databaseVersion = databaseVersion;
        return this;
    }

    protected String _getDatabaseVersion() {
        String databaseVersion = getDatabaseVersion();
        if (databaseVersion == null) {
            if (OSX.equals(getOS()))
                databaseVersion = "mariadb-10.2.11";
            else if (LINUX.equals(getOS()))
                databaseVersion = "mariadb-10.2.11";
            else if (WIN32.equals(getOS()))
                databaseVersion = "mariadb-10.2.11";
            else
                throw new IllegalStateException(
                        "OS not directly supported, please use setDatabaseVersion() to set the name "
                                + "of the package that the binaries are in, for: "
                                + SystemUtils.OS_VERSION);
        }
        return databaseVersion;
    }

    protected String getBinariesClassPathLocation() {
        StringBuilder binariesClassPathLocation = new StringBuilder();
        binariesClassPathLocation.append(getClass().getPackage().getName().replace(".", "/"));
        binariesClassPathLocation.append("/").append(_getDatabaseVersion()).append("/");
        binariesClassPathLocation.append(getOS());
        return binariesClassPathLocation.toString();
    }

    public DBConfigurationBuilder setOS(String osDirectoryName) {
        checkIfFrozen("setOS");
        this.osDirectoryName = osDirectoryName;
        return this;
    }

    public String getOS() {
        return osDirectoryName;
    }

    protected String _getOSLibraryEnvironmentVarName() {
        return SystemUtils.IS_OS_WINDOWS ? "PATH"
                : SystemUtils.IS_OS_MAC ? "DYLD_FALLBACK_LIBRARY_PATH "
                        : "LD_LIBRARY_PATH";
    }

    protected String _getBinariesClassPathLocation() {
        if (isUnpackingFromClasspath)
            return getBinariesClassPathLocation();
        else
            return null; // see ch.vorburger.mariadb4j.DB.unpackEmbeddedDb()
    }

    public boolean isUnpackingFromClasspath() {
        return isUnpackingFromClasspath;
    }

    public DBConfigurationBuilder setUnpackingFromClasspath(boolean isUnpackingFromClasspath) {
        checkIfFrozen("setUnpackingFromClasspath");
        this.isUnpackingFromClasspath = isUnpackingFromClasspath;
        return this;
    }

    public String getURL(String databaseName) {
        return "jdbc:mysql://localhost:" + this.getPort() + "/" + databaseName;
    }

    public List _getArgs() {
        return args;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy