uk.co.platosys.db.jdbc.DatabaseProperties.java Source code

Java tutorial

Introduction

Here is the source code for uk.co.platosys.db.jdbc.DatabaseProperties.java

Source

/*
 * DatabaseProperties.java
 *
 * Created on 03 October 2007, 11:27
 *
 *  Copyright (C) 2008  Edward Barrow
    
This class is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
    
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.
    
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * 
 * for more information contact edward.barrow@platosys.co.uk
 *
 */

package uk.co.platosys.db.jdbc;

import java.io.File;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.jdom2.*;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.XMLOutputter;
import org.jdom2.output.Format;

import uk.co.platosys.db.PlatosysDBException;
import uk.co.platosys.util.Logger;

/**
 * To make things work, you must have a working Postgresql installation with the matching jdbc driver in your classpath.
 * 
 * You need to create a master  database,  a corresponding  user/role and the initial databases.xml file, which must be in your 
 * /usr/local/platosys/conf directory and to which /etc/platosys is a symlink. 
 *   
 * 
 *
 *
 * @author edward
 */
public class DatabaseProperties {

    /*private static String DEFAULT_DB_URL=PlatosysProperties.readProperty("platosyx", "master_db");
    private static String DEFAULT_DB_USER=PlatosysProperties.readProperty("platosyx", "master_db_user");
    private static String DEFAULT_DB_PASSWORD=PlatosysProperties.readProperty("platosyx", "master_db_pwd");
    private static String DEFAULT_DB_DRIVER=PlatosysProperties.readProperty("platosyx", "master_db_driver");*/
    private static String UNIX_CONFIG_READ_DIR = "/etc/platosys/";//this should be a symlink to the write dir
    private static String UNIX_CONFIG_WRITE_DIR = "/usr/local/platosys/conf";
    private static String WIN_CONFIGDIR = "";
    private static String CONFIG_FILE = "databases.xml";
    protected static Logger DATABASE_LOGGER = new Logger("dbplat");
    private DatabaseCredentials masterCredentials = null;
    private static Logger logger = DATABASE_LOGGER;
    private List<DatabaseCredentials> credentials = new ArrayList<DatabaseCredentials>();
    private List<String> names = new ArrayList<String>();

    /** Creates a new instance of DatabaseProperties */
    public DatabaseProperties() {
        loadProperties();
    }

    private void loadProperties() {
        try {
            File configDir = new File(UNIX_CONFIG_READ_DIR);
            File configFile = new File(configDir, CONFIG_FILE);
            SAXBuilder builder = new org.jdom2.input.SAXBuilder();
            Document configDoc = builder.build(configFile);
            Element rootElement = configDoc.getRootElement();
            List<Element> databases = rootElement.getChildren("database");
            String status = "";
            for (Element database : databases) {
                String name = database.getAttributeValue("name");
                logger.log("DBProps reading elmt for db " + name);
                String databaseDriver = database.getChildText("databaseDriver");
                String databaseUrl = database.getChildText("databaseUrl");
                String databaseUser = database.getChildText("databaseUser");
                String databasePassword = database.getChildText("databasePassword");
                DatabaseCredentials databaseCredentials = new DatabaseCredentials(name, databaseDriver, databaseUrl,
                        databaseUser, databasePassword);
                if (database.getAttributeValue("status") != null) {
                    status = database.getAttributeValue("status");
                    if (status.equals("master")) {
                        masterCredentials = databaseCredentials;
                        logger.log(databaseCredentials.getName() + " is the master database");
                    } else {
                        logger.log(databaseCredentials.getName() + " has status " + status);
                    }
                }
                credentials.add(databaseCredentials);
                names.add(name);
                logger.log("DatabaseProperties has loaded details for " + status + " database " + name);
            }
        } catch (Exception e) {
            logger.log("Problem loading database properties", e);
        }

    }

    protected List<DatabaseCredentials> getDatabases() {
        loadProperties();
        return credentials;
    }

    public List<String> getDatabaseNames() {
        return names;
    }

    /**
     * creates a new database with the given name and the master database credentials
     * @param name
     * @return
     */
    public String createDatabase(String masterDatabase, String newDatabaseName) throws PlatosysDBException {
        logger.log("creating new database: " + newDatabaseName);
        DatabaseCredentials newCredentials = DatabaseCredentials.getNewCredentials(getMasterCredentials(),
                newDatabaseName);
        logger.log("creating new database/credentials: " + newDatabaseName);
        return createDatabase(masterDatabase, newCredentials);
    }

    /**
     * creates a new database and returns a String with its name
     * @param masterDatabase
     * @param newCredentials
     * @return
     * @throws PlatosysDBException 
     */
    public static String createDatabase(String masterDatabase, DatabaseCredentials newCredentials)
            throws PlatosysDBException {
        logger.log("checking database credentials etc");
        //some checks:
        String databaseName = newCredentials.getName();
        String databaseUser = newCredentials.getUsername();
        String databaseURL = newCredentials.getUrl();
        logger.log("into the next method");
        Document configDoc = null;
        Element rootElement = null;
        try {
            File configDir = new File(UNIX_CONFIG_READ_DIR);
            File configFile = new File(configDir, CONFIG_FILE);
            SAXBuilder builder = new org.jdom2.input.SAXBuilder();
            configDoc = builder.build(configFile);
            rootElement = configDoc.getRootElement();
            List<Element> databases = rootElement.getChildren("database");
            Iterator<Element> it = databases.iterator();
            while (it.hasNext()) {
                Element databaseElement = (Element) it.next();
                if (databaseElement.getAttributeValue("name").equals(masterDatabase)) {
                    //check the database drivers match
                    if (!(databaseElement.getChildText("databaseDriver").equals(newCredentials.getDriver()))) {
                        throw new PlatosysDBException("Database driver class names do not  match");
                    }
                    //TODO: fix location checking
                    /*
                     * not doing database location checks. Not working, too much time to fix
                     * for now.
                    //check the URL matches; strip off the name suffix of the URL
                    String masterURL = databaseElement.getChildText("databaseUrl");
                    logger.log("full masterURL is "+masterURL);
                    int b = masterDatabase.length();
                    int a = masterURL.length();
                    logger.log("masterDatabase is "+masterDatabase);
                    masterURL = masterURL.substring(0, a-b);
                    logger.log("stripped masterURL is "+masterURL);
                    logger.log("new dburl is "+databaseURL);
                    a = databaseURL.length();
                    b = databaseName.length();
                    String newURL = databaseURL.substring(0, a-b);
                    logger.log("newURL is"+newURL);
                    if (!masterURL.equals(newURL)){
                        throw new PlatosysDBException("New database must match the master database location");
                    }*/
                }
                if (databaseElement.getAttributeValue("name").equals(databaseName)) {
                    throw new PlatosysDBException("Database name " + databaseName + " already exists");
                }
                /*
                if (databaseElement.getChildText("databaseUser").equals(databaseUser)){
                    throw new PlatosysDBException("Database user "+databaseUser+" already exists");
                }*/
            }
        } catch (Exception x) {
            logger.log("problem doing createDB checks", x);
            throw new PlatosysDBException("Error doing create DB checks", x);
        }

        //connect to the master database and create new database and role
        Connection connection = ConnectionSource.getConnection(masterDatabase);
        try {
            Statement statement = connection.createStatement();
            //not creating new role because it is the same one (see how we get the credentials).
            //arguably we should create a new role. So just creating database.
            //statement.execute("CREATE ROLE "+databaseUser+" WITH LOGIN PASSWORD "+newCredentials.getPassword());
            statement.execute("CREATE DATABASE " + databaseName);
        } catch (Exception x) {
            logger.log("problem creating database", x);
            throw new PlatosysDBException("Failed to create new database: ", x);
        }
        try {
            connection.close();
        } catch (Exception x) {
        }
        try {
            //write this to a file:
            logger.log(2, "writing info to a file");
            File configDir = new File(UNIX_CONFIG_WRITE_DIR);
            File configFile = new File(configDir, CONFIG_FILE);
            Element databaseElement = new Element("database");
            databaseElement.setAttribute("name", databaseName);
            databaseElement.setAttribute("status", "slave");
            Element driverElement = new Element("databaseDriver");
            driverElement.setText(newCredentials.getDriver());
            databaseElement.addContent(driverElement);
            Element urlElement = new Element("databaseUrl");
            urlElement.setText(newCredentials.getUrl());
            databaseElement.addContent(urlElement);
            Element userElement = new Element("databaseUser");
            userElement.setText(newCredentials.getUsername());
            databaseElement.addContent(userElement);
            Element passwordElement = new Element("databasePassword");
            passwordElement.setText(newCredentials.getPassword());
            databaseElement.addContent(passwordElement);
            rootElement.addContent(databaseElement);

            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
            FileWriter writer = new FileWriter(configFile);
            outputter.output(configDoc, writer);
            writer.close();
        } catch (Exception x) {
            logger.log("problem writing database info to xml", x);
            throw new PlatosysDBException("problem writing new database configuration file ", x);
        }

        return newCredentials.getName();
    }

    private DatabaseCredentials getMasterCredentials() {
        return masterCredentials;
    }
}