diff --git a/.classpath b/.classpath
index 3300db2..42620d7 100644
--- a/.classpath
+++ b/.classpath
@@ -1,9 +1,10 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/commons-dbutils-1.4.jar b/lib/commons-dbutils-1.4.jar
new file mode 100644
index 0000000..7b846ea
Binary files /dev/null and b/lib/commons-dbutils-1.4.jar differ
diff --git a/src/com/proquest/interview/phonebook/Person.java b/src/com/proquest/interview/phonebook/Person.java
index 96ccaa5..610fc30 100644
--- a/src/com/proquest/interview/phonebook/Person.java
+++ b/src/com/proquest/interview/phonebook/Person.java
@@ -1,7 +1,87 @@
package com.proquest.interview.phonebook;
+/**
+ * Person represents a person with a name, address, and phone number.
+ * Instances of this class are immutable.
+ *
+ */
public class Person {
- public String name;
- public String phoneNumber;
- public String address;
+ private final String name;
+ private final String phoneNumber;
+ private final String address;
+
+ /**
+ * Creates a person. The name, address, and phone number may not be null.
+ *
+ * @param name the full name of the person
+ * @param phoneNumber the person's phone number
+ * @param address the person's address
+ * @throws IllegalArgumentException if any of the parameters are null
+ */
+ public Person(String name, String phoneNumber, String address) {
+ if (name == null || phoneNumber == null || address == null) {
+ throw new IllegalArgumentException("null");
+ }
+ this.name = name;
+ this.phoneNumber = phoneNumber;
+ this.address = address;
+ }
+
+ /** Returns the person's name. */
+ public String getName() {
+ return name;
+ }
+
+ /** Returns the person's phone number. */
+ public String getPhoneNumber() {
+ return phoneNumber;
+ }
+
+ /** Returns the person's address. */
+ public String getAddress() {
+ return address;
+ }
+
+ /** Returns a string representation of the person. */
+ @Override public String toString() {
+ return name + ", " + phoneNumber + ", " + address;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((address == null) ? 0 : address.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result
+ + ((phoneNumber == null) ? 0 : phoneNumber.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof Person))
+ return false;
+ Person other = (Person) obj;
+ if (address == null) {
+ if (other.address != null)
+ return false;
+ } else if (!address.equals(other.address))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (phoneNumber == null) {
+ if (other.phoneNumber != null)
+ return false;
+ } else if (!phoneNumber.equals(other.phoneNumber))
+ return false;
+ return true;
+ }
}
diff --git a/src/com/proquest/interview/phonebook/PhoneBook.java b/src/com/proquest/interview/phonebook/PhoneBook.java
index 47627fd..d90c12c 100644
--- a/src/com/proquest/interview/phonebook/PhoneBook.java
+++ b/src/com/proquest/interview/phonebook/PhoneBook.java
@@ -1,6 +1,9 @@
package com.proquest.interview.phonebook;
+import java.util.Collection;
+
public interface PhoneBook {
- public Person findPerson(String firstName, String lastName);
- public void addPerson(Person newPerson);
+ Person findPerson(String firstName, String lastName);
+ void addPerson(Person newPerson);
+ Collection allPeople();
}
diff --git a/src/com/proquest/interview/phonebook/PhoneBookImpl.java b/src/com/proquest/interview/phonebook/PhoneBookImpl.java
index d7eb6fe..d2b0797 100644
--- a/src/com/proquest/interview/phonebook/PhoneBookImpl.java
+++ b/src/com/proquest/interview/phonebook/PhoneBookImpl.java
@@ -1,31 +1,162 @@
package com.proquest.interview.phonebook;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import org.apache.commons.dbutils.DbUtils;
+import org.apache.commons.dbutils.QueryRunner;
+import org.apache.commons.dbutils.ResultSetHandler;
+
import com.proquest.interview.util.DatabaseUtil;
public class PhoneBookImpl implements PhoneBook {
- public List people;
-
+ public List people = new ArrayList();
+
@Override
public void addPerson(Person newPerson) {
- //TODO: write this method
+ if (newPerson == null) throw new IllegalArgumentException("null");
+ people.add(newPerson);
}
-
+
@Override
- public Person findPerson() {
- //TODO: write this method
+ public Person findPerson(String firstName, String lastName) {
+ if (firstName == null || lastName == null) {
+ throw new IllegalArgumentException("null");
+ // the other option here is to return null, indicating not found
+ }
+ final String nameSought = firstName + " " + lastName;
+ for (Person person : people) {
+ if (nameSought.equals(person.getName())) return person;
+ }
+ return null;
+ }
+
+ public Collection allPeople() {
+ return Collections.unmodifiableList(people);
}
+ @Override public String toString() {
+ return people.toString();
+ }
+
public static void main(String[] args) {
- DatabaseUtil.initDB(); //You should not remove this line, it creates the in-memory database
-
- /* TODO: create person objects and put them in the PhoneBook and database
- * John Smith, (248) 123-4567, 1234 Sand Hill Dr, Royal Oak, MI
- * Cynthia Smith, (824) 128-8758, 875 Main St, Ann Arbor, MI
- */
- // TODO: print the phone book out to System.out
- // TODO: find Cynthia Smith and print out just her entry
- // TODO: insert the new person objects into the database
+ DatabaseUtil.initDB(); // You should not remove this line, it creates the in-memory database
+
+ PhoneBook phoneBook = new PhoneBookImpl();
+
+ // create person objects and put them in the PhoneBook and database
+
+ phoneBook.addPerson(new Person("John Smith", "(248) 123-4567",
+ "1234 Sand Hill Dr, Royal Oak, MI"));
+ phoneBook.addPerson(new Person("Cynthia Smith", "(824) 128-8758",
+ "875 Main St, Ann Arbor, MI"));
+
+ // print the phone book out to System.out
+
+ // It isn't clear to me which of these you want:
+
+ System.out.println(phoneBook);
+
+ for (Person person : phoneBook.allPeople()) {
+ System.out.println(person);
+ }
+
+ // find Cynthia Smith and print out just her entry
+
+ System.out.println("Cynthia:");
+ Person cynthiaSmith = phoneBook.findPerson("Cynthia", "Smith");
+ System.out.println(cynthiaSmith);
+
+ // It was a little unclear when you wanted me to add the objects
+ // to the database. At the top, you said to add people to the
+ // phone book and the database, but at the end, you said to add
+ // the new people to the database.
+
+ // insert the new person objects into the database
+
+ insertPeople(phoneBook.allPeople());
+ }
+
+ public static ResultSetHandler> rowsToPeople() {
+ return new ResultSetHandler>() {
+ public List handle(ResultSet rs) throws SQLException {
+ List people = new ArrayList();
+ while (rs.next()) {
+ people.add(new Person(rs.getString(1), rs.getString(2), rs.getString(3)));
+ }
+ return people;
+ }
+ };
+ }
+
+ public static List byCriteria(String sql, Object... criteria) {
+ Connection con = null;
+ try {
+ con = getConnection();
+ return new QueryRunner().query(con, sql, rowsToPeople(), criteria);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ // questionable; maybe we should throw some application-specific exception to indicate failure
+ return new ArrayList();
+ } finally {
+ DbUtils.closeQuietly(con);
+ }
+ }
+
+ public static List everyone() {
+ return byCriteria("SELECT * FROM PHONEBOOK", new Object[] {});
+ }
+
+ public static List byName(String name) {
+ return byCriteria("SELECT * FROM PHONEBOOK WHERE NAME = ?", name);
+ }
+
+ public static List byPhoneNumber(String phoneNumber) {
+ return byCriteria("SELECT * FROM PHONEBOOK WHERE PHONENUMBER = ?", phoneNumber);
+ }
+
+ public static List byAddress(String address) {
+ return byCriteria("SELECT * FROM PHONEBOOK WHERE ADDRESS = ?", address);
+ }
+
+ public static void insertPeople(Collection people) {
+ final String sql =
+ "INSERT INTO PHONEBOOK (NAME, PHONENUMBER, ADDRESS) VALUES(?, ?, ?)";
+
+ Connection con = null;
+ PreparedStatement ps = null;
+
+ try {
+ con = getConnection();
+ con.setAutoCommit(false);
+ ps = con.prepareStatement(sql);
+ QueryRunner q = new QueryRunner();
+ for (Person person : people) {
+ q.fillStatementWithBean(ps, person, "name", "phoneNumber", "address");
+ ps.addBatch();
+ }
+ ps.executeBatch();
+ con.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ } finally {
+ DbUtils.closeQuietly(ps);
+ DbUtils.closeQuietly(con);
+ }
+ }
+
+ public static Connection getConnection() throws SQLException {
+ try {
+ return DatabaseUtil.getConnection();
+ } catch (ClassNotFoundException e) {
+ // avoid dealing with CNFE; we aren't going to do anything different in that case anyway
+ throw new SQLException(e);
+ }
}
}
diff --git a/src/com/proquest/interview/util/DatabaseUtil.java b/src/com/proquest/interview/util/DatabaseUtil.java
index a23342d..8e690de 100644
--- a/src/com/proquest/interview/util/DatabaseUtil.java
+++ b/src/com/proquest/interview/util/DatabaseUtil.java
@@ -5,25 +5,30 @@
import java.sql.SQLException;
import java.sql.Statement;
+import org.apache.commons.dbutils.DbUtils;
+
/**
* This class is just a utility class, you should not have to change anything here
* @author rconklin
*/
public class DatabaseUtil {
public static void initDB() {
+ Connection cn = null;
try {
- Connection cn = getConnection();
+ cn = getConnection();
+ cn.setAutoCommit(false);
Statement stmt = cn.createStatement();
stmt.execute("CREATE TABLE PHONEBOOK (NAME varchar(255), PHONENUMBER varchar(255), ADDRESS varchar(255))");
stmt.execute("INSERT INTO PHONEBOOK (NAME, PHONENUMBER, ADDRESS) VALUES('Chris Johnson','(321) 231-7876', '452 Freeman Drive, Algonac, MI')");
stmt.execute("INSERT INTO PHONEBOOK (NAME, PHONENUMBER, ADDRESS) VALUES('Dave Williams','(231) 502-1236', '285 Huron St, Port Austin, MI')");
cn.commit();
- cn.close();
} catch (Exception ex) {
ex.printStackTrace();
+ } finally {
+ DbUtils.closeQuietly(cn);
}
-
}
+
public static Connection getConnection() throws SQLException, ClassNotFoundException {
Class.forName("org.hsqldb.jdbcDriver");
return DriverManager.getConnection("jdbc:hsqldb:mem", "sa", "");
diff --git a/test/com/proquest/interview/phonebook/PhoneBookImplTest.java b/test/com/proquest/interview/phonebook/PhoneBookImplTest.java
index 33c7c14..e39e1de 100644
--- a/test/com/proquest/interview/phonebook/PhoneBookImplTest.java
+++ b/test/com/proquest/interview/phonebook/PhoneBookImplTest.java
@@ -1,10 +1,62 @@
package com.proquest.interview.phonebook;
+import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
public class PhoneBookImplTest {
+ private PhoneBook phoneBook;
+
+ @Before
+ public void setUp() {
+ phoneBook = new PhoneBookImpl();
+ phoneBook.addPerson(new Person("David Conrad", "(313) 437-3173",
+ "17540 Mack Ave #4, Grosse Pointe, MI"));
+ }
+
+ @Test
+ public void emptyPhoneBookTest() {
+ phoneBook = new PhoneBookImpl();
+ assertEquals(phoneBook.allPeople().size(), 0);
+ }
+
+ @Test
+ public void addPersonTest() {
+ int formerSize = phoneBook.allPeople().size();
+ phoneBook.addPerson(new Person("Jane Doe", "(313) 555-1212",
+ "123 Elm Ct, Anytown, MI"));
+ assertEquals(phoneBook.allPeople().size(), formerSize + 1);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void addNullPersonTest() {
+ phoneBook.addPerson(null);
+ }
+
@Test
- public void shouldAddFindPerson() {
-
+ public void findPersonTest() {
+ assertNotNull(phoneBook.findPerson("David", "Conrad"));
+ }
+
+ @Test
+ public void noSuchPersonTest() {
+ assertNull(phoneBook.findPerson("Joe", "Schmoe"));
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void findNullPersonTest() {
+ phoneBook.findPerson(null, null);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void findNullFirstNameTest() {
+ phoneBook.findPerson(null, "Jones");
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void findNullLastNameTest() {
+ phoneBook.findPerson("Dev", null);
}
}