package edu.hawaii.ics.yucheng; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; /** * An immutable class that contains the configuration information of a node. * * @author Cheng Jade * @assignment ICS 421 Assignment 1 * @date Feb 10, 2010 * @bugs None */ public final class ConfigurationNode { /** The driver name used for the database connection. */ public final String driver; /** The host name URI for the database server. */ public final String hostname; /** A name used for identifying the thread responsible for this instance. */ public final String name; /** The password for the database connection. */ public final String password; /** The user name for the database connection. */ public final String username; /** * Initializes a new instance of the ConfigurationNode class. * * @param properties * A properties object that the configuration node will be loaded * from. * @param name * The name used for identifying the thread responsible for this * instance. * * @throws NullPointerException * @throws ProgramException * Thrown if the reading properties goes wrong. */ public ConfigurationNode( final Properties properties, final String name) throws ProgramException { // Read the corresponding lines from the properties object, and use the // values as the parameters to call the other constructor, which assigns // the class fields to those values. this( name, read(properties, name, "driver"), read(properties, name, "hostname"), read(properties, name, "username"), read(properties, name, "passwd")); } /** * Initializes a new instance of the ConfigurationNode class. * * @param name * The name used for identifying the thread responsible for this * instance. * @param driver * The driver name used for the database connection. * @param hostname * The host name URI for the database server. * @param username * The user name for the database connection. * @param password * The password for the database connection. * * @throws NullPointerException * @throws ProgramException * Thrown if any parameter is null. */ public ConfigurationNode( final String name, final String driver, final String hostname, final String username, final String password) throws ProgramException { // Check if any parameter is null, and throw exception in that case. if (null == name) throw new ProgramException("name is null"); if (null == driver) throw new ProgramException("driver is null"); if (null == hostname) throw new ProgramException("hostname is null"); if (null == username) throw new ProgramException("username is null"); if (null == password) throw new ProgramException("password is null"); // Assign the parameter values to the class fields. this.name = name; this.driver = driver; this.hostname = hostname; this.username = username; this.password = password; } /** * Checks the DBMS driver is available. * * @throws ProgramException * Thrown if the DBMS driver is not available. */ public void checkDriver() throws ProgramException { try { Class.forName(this.driver).newInstance(); return; } catch (final InstantiationException e) { } catch (final IllegalAccessException e) { } catch (final ClassNotFoundException e) { } throw new ProgramException("Cannot load driver '" + this.driver + "'."); } /** * Gets a connection to the DBMS database. * * @throws ProgramException * Thrown if the connection cannot be made. */ public Connection getConnection() throws ProgramException { this.checkDriver(); try { return DriverManager.getConnection( this.hostname, this.username, this.password); } catch (final SQLException e) { throw new ProgramException( "Cannot open connection to '" + this.hostname + "'.", e); } } /** * Returns a readable version of the contents of the Configuration Node. * * @return A readable version of the contents of the Configuration Node. */ @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append(" Driver: "); builder.append(this.driver); builder.append("\n Hostname: "); builder.append(this.hostname); builder.append("\n Username: "); builder.append(this.username); builder.append("\n Password: "); builder.append(this.password); return builder.toString(); } /** * Creates a key and looks up a value in the properties object. The value is * returned if it is found; otherwise, an exception is thrown. * * @return The key word to search for in the properties file. * * @throws NullPointerException * @throws ProgramException * Thrown if the key is not found in the properties object. */ private static String read( final Properties properties, final String prefix, final String name) throws ProgramException { assert null != name; // Check if the properties and prefix are not nulls. if (null == properties) throw new NullPointerException("properties"); if (null == prefix) throw new NullPointerException("prefix"); // Create the key to search for according to the prefix and name. final String key = prefix + "." + name; // Search for the key and return the corresponding value. final String value = properties.getProperty(key); if (null == value) throw new ProgramException( "Property '" + key + "' not found in configuration file."); return value; } /** * The entry point for a test for this class. * * @param args * The command line arguments (not used). */ public static void main(final String[] args) { // Declare, initialize, and print a ConfigurationNode object. try { System.out.println(new ConfigurationNode("n", "d", "h", "u", "p")); } catch (final ProgramException e) { System.err.println(e.getMessage()); System.exit(1); return; } // Exit cleanly while debugging from Eclipse. System.exit(0); } }