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);
}
}