<file_sep>package com.twu.biblioteca;

import org.junit.Test;
import static org.junit.Assert.*;

public class MovieTest {

    @Test
    public void testToString() {
        Movie movie = new Movie("The Mooovie", "<NAME>", "2014", "10");
        assertEquals("The Mooovie\tCow, Arthur\t2014\t10", movie.toString());
    }

    @Test
    public void testEquals() {
        Movie movie = new Movie("The Mooovie", "<NAME>", "2014", "10");
        assertTrue(movie.equals(new Movie("The Mooovie", "<NAME>", "2014", "10")));
    }
}
<file_sep>package com.twu.biblioteca;

import java.util.*;

/*
This is the CONSOLE class.  Here, we read in any message typed in by the user,
perform appropriate operations, and then return a message indicating the result.
 */

class Console {

    private Library library;
    private ArrayList<User> userList;
    private boolean isLoggedIn;
    private User activeUser;

    Console() {
        library = new Library();
        isLoggedIn = false;
        userList = new ArrayList<User>();


        userList.add(new User("101-3345", "letmein", "<NAME>",
                "<EMAIL>","(979) 606-5684"));
        userList.add(new User("777-0987", "sevens",
                "<NAME>", "<EMAIL>", "(978) 960-2396"));
        userList.add(new User("123-4567", "password",
                "<NAME>", "<EMAIL>", "(661) 574-7566"));
    }

    String getWelcomeMessage() {
        return "Hello!\nWelcome to Biblioteca.\nPlease type your commands below.";
    }

    String getMainMenu() {
        if (isLoggedIn)
            return "\nMAIN MENU:\n" +
                "List Books\n" +
                "List Movies\n" +
                "Checkout <Title>\n" +
                "Return <Title>\n" +
                "View User Info\n" +
                "Quit";
        else
            return "\nMAIN MENU:\n" +
                    "List Books\n" +
                    "List Movies\n" +
                    "Login\n" +
                    "Quit";
    }

    String readMessage(String in) {

        if (in.equals("List Books")) {
            return listResources("book");
        } else if(in.equals("List Movies")) {
            return listResources("movie");
        } else if (isACheckoutMessage(in) && isLoggedIn) {
            return performCheckOutSequence(in);

        } else if (isAReturnMessage(in) && isLoggedIn) {
            return performReturnSequence(in);

        } else if (in.equals("View User Info") && isLoggedIn) {
            return activeUser.getUserInfo();

        } else if (in.equals("Quit")) {
            return quit();
        }
        else {
            return "Select a valid option!";
        }
    }

    public String login(String userId, String password) {
        User u = getUserWithThisLogin(userId, password);
        if (u != null) {
            isLoggedIn = true;
            activeUser = u;
            return "Successfully logged in!" + getMainMenu();
        } else {
            return "Failed login";
        }
    }

    private User getUserWithThisLogin(String userId, String password) {
        for (User user : userList) {
            if (user.isThisLogin(userId, password)) {
                return user;
            }
        }
        return null;
    }

    private boolean isAReturnMessage(String message) {
        String[] splitIntoWords = message.split(" ");
        return (splitIntoWords[0].equals("Return"));
    }

    private String performReturnSequence(String in) {
        String title = getAllWordsExceptFirstWord(in);
        if (isAValidReturn(title)) {
            Resource toReturn = library.getResourceByTitle(title);
            toReturn.checkIn();
            return toReturn.getTitle() + " has been successfully returned.\nThank you for returning the book.";
        }
        else {
            return "This is not a valid book to return.";
        }
    }

    private boolean resourceWithThisTitleIsCheckedOut(String title) {
        Resource r = library.getResourceByTitle(title);
        return !r.isCheckedIn();
    }

    private String performCheckOutSequence(String in) {
        String title = getAllWordsExceptFirstWord(in);
        if (isAValidCheckout(title)) {
            Resource toCheckout = library.getResourceByTitle(title);
            toCheckout.checkOut();
            return toCheckout.getTitle() + " has been successfully checked out.\nThank you! Enjoy the book.";
        }
        else {
            return "That book is not available.";
        }
    }

    private boolean isAValidReturn(String title) {
        return library.containsTitle(title) && resourceWithThisTitleIsCheckedOut(title);
    }

    private boolean isAValidCheckout(String title) {
        return library.containsTitle(title) && !resourceWithThisTitleIsCheckedOut(title);
    }

    private boolean isACheckoutMessage(String message) {
        String[] splitIntoWords = message.split(" ");
        return (splitIntoWords[0].equals("Checkout"));
    }

    private String getAllWordsExceptFirstWord(String message) {
        int indexOfSpace = message.indexOf(' ');
        return message.substring(indexOfSpace + 1); // the book title
    }

    private String listResources(String mode) {
        return library.getResourceListInColumns(mode);
    }

    String quit() {
       return "Goodbye!";
    }

}
<file_sep>package com.twu.biblioteca;

import org.junit.Test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertNotEquals;

public class BookTest {

    @Test
    public void testToString() {
        Book book = new Book("Emma", "<NAME>", "1815");
        assertEquals(book.toString(), "Emma\tAusten, Jane\t1815");
    }

    @Test
    public void testToColumnWithCheckedOutBooks() {
        Book book = new Book("Emma", "<NAME>", "1815");
        assertEquals("Emma   <NAME>   1815", book.toColumn(4, 12));
        book.checkOut();
        assertEquals("", book.toColumn(4, 12));
    }

    @Test
    public void testEquals() {
        Book book = new Book("Emma", "<NAME>", "1815");
        assertTrue(book.equals(new Book("Emma", "<NAME>", "1815")));
    }
}
<file_sep>package com.twu.biblioteca;

public class Movie extends Resource {

    private String rating;

    public Movie(String titleArg, String yearArg, String directorArg, String ratingArg) {
        super(titleArg, directorArg, yearArg); // CAUTION: argument order
        rating = ratingArg;
    }

    public String getDirector() {
        return creator;
    }

    public String getRating() {
        return rating;
    }

    public String getTitle() {
        return title;
    }

    public String getYear() {
        return year;
    }

    public String getCreator() {
        return getDirector();
    }

    public String toColumn(int titleLength, int directorLength) {

        StringBuilder row = new StringBuilder(title);
        while (row.length() < titleLength + 3) { // need spaces to be even with longest title
            row.append(" ");
        }

        row.append(year);
        row.append("   ");

        row.append(creator);
        while (row.length() < titleLength + directorLength + 9 + 4) { // 4 chars for the year
            row.append(" ");
        }

        row.append(rating);

        return row.toString();

    }

    public String toString() {
        return title + "\t" + year + "\t" + creator + "\t" + rating;
    }


}
<file_sep>package com.twu.biblioteca;

public abstract class Resource {

    protected String title;
    protected String year;
    protected String creator;
    protected boolean isCheckedIn;

    public Resource(String titleArg, String creatorArg, String yearArg) {
        title = titleArg;
        year = yearArg;
        creator = creatorArg;
        isCheckedIn = true;
    }

    public String getTitle() {
        return title;
    }

    public String getCreator() {
        return creator;
    }

    public String getYear() {
        return year;
    }

    public abstract String toColumn(int titleLength, int creatorLength);
    public abstract String toString();

    public boolean equals(Resource other) {
        return toString().equals(other.toString());
    }

    public boolean isCheckedIn() {
        return isCheckedIn;
    }

    public void checkOut() {
        isCheckedIn = false;
    }

    public void checkIn() {
        isCheckedIn = true;
    }

    public Book toBook() {
        if (this instanceof Book) {
            return (Book) this;
        } else {
            throw new IllegalArgumentException("toBook called on a non-book object");
        }
    }

    public Movie toMovie() {
        if (this instanceof Movie) {
            return (Movie) this;
        } else {
            throw new IllegalArgumentException("toMovie called on a non-Movie object");
        }
    }


}
<file_sep>package com.twu.biblioteca;

import java.util.*;
import java.io.InputStream;

public class BibliotecaApp {

    public static void main(String[] args) {
        Console console = new Console();
        welcome(console);
        InputStream stdin = System.in;

        listen(stdin, console);
    }

    // this accepts a general InputStream for testing purposes
    public static void listen(InputStream in, Console console) {
        Scanner sc = new Scanner(in);
        while (sc.hasNext()) {
            String command = sc.nextLine();

            if (command.equals("Login")) { // special case

                System.out.println("User ID:");
                String userId = sc.nextLine();
                System.out.println("Password:");
                String password = sc.nextLine();
                System.out.println(console.login(userId, password));
                continue;
            }

            String response = console.readMessage(command);
            System.out.println(response);

            if (command.equals("Quit")) { // special case
                break;
            }
        }
    }

    public static void welcome(Console console) {
        System.out.println(console.getWelcomeMessage());
        System.out.println(console.getMainMenu());
    }
}
