Refactoring

There are a few things we must take care of, before signing off this module! You may have notice some repeated code when we connect to the database or to create tables and populate it. There are also some dependencies in the tests; some tests make assumptions about certain course data being present (or absent) from the database. We need to refactor the codebase to address these issues. In the process, we will also organize the code into packages.

This section is mainly left to you as part of HW5. I provide descriptions of what needs to be done, and you should carry it out.

First, organize the code (the content of the src folder) in the following structure:

.
├── main
│   ├── java
│   │   ├── api
│   │   │   └── Server.java
│   │   ├── dao
│   │   │   ├── CourseDao.java
│   │   │   └── Sql2oCourseDao.java
│   │   ├── exceptions
│   │   │   ├── ApiError.java
│   │   │   └── DaoException.java
│   │   ├── model
│   │   │   └── Course.java
│   │   └── util
│   │       ├── DataStore.java
│   │       └── Database.java
│   └── resources
└── test
    ├── java
    │   ├── api
    │   │   └── ServerTest.java
    │   └── dao
    │       └── Sql2oCourseDaoTest.java
    └── resources
  • The Server.java is what you now have as ApiServer.java.

Here are the structure of DataStore.java and Database.java:

package util;

import model.Course;

import java.util.List;

/**
 * A utility class with methods to create sample data.
 */
public final class DataStore {

  private DataStore() {
    // This class should not be instantiated.
  }

  /**
   * Create a list of sample CS courses.
   *
   * @return a list of sample CS courses.
   */
  public static List<Course> sampleCourses() {
    return null; // TODO Implement Me!
  }
}
package util;

import model.Course;
import org.sql2o.Connection;
import org.sql2o.Sql2o;
import org.sql2o.Sql2oException;

import java.net.URISyntaxException;
import java.util.List;

/**
 * A utility class with methods to establish JDBC connection, set schemas, etc.
 */
public final class Database {
  public static boolean USE_TEST_DATABASE = false;

  private Database() {
    // This class should not be instantiated.
  }

  /**
   * Connect to the database and build the tables with sample data for this application.
   * <p>
   * Caution: Use this to cleanup the database.
   * </p>
   *
   * @param args command-line arguments; not used here.
   * @throws URISyntaxException Checked exception thrown to indicate the provided database URL cannot be parsed as a
   *     URI reference.
   */
  public static void main(String[] args) throws URISyntaxException {
    Sql2o sql2o = getSql2o();
    createCoursesTableWithSampleData(sql2o, DataStore.sampleCourses());
  }

  /**
   * Create and return a Sql2o object connected to the database pointed to by the DATABASE_URL.
   *
   * @return a Sql2o object connected to the database to be used in this application.
   * @throws URISyntaxException Checked exception thrown to indicate the provided database URL cannot be parsed as a
   *     URI reference.
   * @throws Sql2oException an generic exception thrown by Sql2o encapsulating anny issues with the Sql2o ORM.
   */
  public static Sql2o getSql2o() throws URISyntaxException, Sql2oException {
    return null; // TODO Implement Me!
  }

  /**
   * Create courses table schema and add sample CS courses to it.
   *
   * @param sql2o a Sql2o object connected to the database to be used in this application.
   * @param samples a list of sample CS courses.
   * @throws Sql2oException an generic exception thrown by Sql2o encapsulating anny issues with the Sql2o ORM.
   */
  public static void createCoursesTableWithSampleData(Sql2o sql2o, List<Course> samples) throws Sql2oException {
    // TODO Implement Me!
  }

  // Get either the test or the production Database URL
  private static String getDatabaseUrl() throws URISyntaxException {
    return null; // TODO Implement Me!
  }

  // Add course to the database connected to the conn object.
  private static void add(Connection conn, Course course) throws Sql2oException {
    // TODO Implement Me!
  }
}

You need to update the rest of the application (e.g. Server.java, test classes, etc) to use the methods in these utility classes.

Once you are done with refactoring, run the unit tests and make sure they all pass. Then, run Server.java and run HTTP requests in Postman to ensure the API behaves as expected.