CPE 102

Winter 2008

Program 4

 

Due Date

 

You must turn in a functionally correct program to receive any credit.  The grade you receive will be based on when you turn it in minus any deductions for the quality of your implementation and/or multiple submissions.  There is no deduction for the first submission and a 5% deduction for each additional submission, if any.  Programs will be checked for correctness once a day and you will be notified by email if your submission is not functionally correct.  Programs will be graded after the last due date and the results will be emailed to you within a few days of that date.

 

100% (minus any deductions) by 9:00pm Monday, 2/4/08

90% (minus any deductions) by 9:00pm Tuesday, 2/5/08

80% (minus any deductions) by 9:00pm Wednesday, 2/6/08

70% (minus any deductions) by 9:00pm Thursday, 2/7/08

 

You must also turn in a UML Diagram for the program in lecture on Monday 2/4no late diagrams accepted.  The diagram is worth 10% of your program grade and may be hand-drawn.

  

Errata:

 

None

 

Objectives

 

  1. To demonstrate basic object-oriented design and development skills.
    1. I will be giving you quite a bit of the structure of the solution – use good judgment “filling in the blanks”.
  1. To become more familiar with:
    1. Java interfaces and inheritance.
    2. The concept of polymorphism.
    3. The javadoc style of documenting code.
    4. Using UML for designing and describing programs.

 

Resources

 

  1. Java Standard API
  2. P4TestDriver.java (Will be published Monday 2/4)  
  3. UML Overview
  4. P4UnitTests.zip

 

Problem Description

 

  1. You will be creating an inventory of various products for a fictitious online retailer.  You will develop the foundation classes and three specific products for use now and to support any new products that may be added in the future.  These products will make use of a utility class to support complex (relatively!) name searches.  In addition, you will be implementing several methods to find products by various criteria.  You will assign each product a unique product identification number.  Since the products will have a quantity variable you will insure that no duplicates are entered into you inventory.  Instead, you can manage the number of each product in the inventory by modifying the quantity instance field.
  2. JUnit tests will be provided in P4UnitTests.zip.  As in previous assignments, some JUnit test cases are left stubbed out for you to fill in.  In Program 4, you will need to write JUnit tests for the Inventory, BookOnTape, and CD classes.

 

Specification

 

  1. You must implement the classes and methods exactly as described or the provided test driver will not work!

 

  1. Document all public methods in Inventory and Product classes using the javadoc style of documentation.  Don’t forget the required comment block that belongs at the top of each and every file too.

 

  1. Implement a class called Inventory.

 

    1. With one (and only one) private instance field of type ArrayList<Product> to contain products.

 

    1. With one constructor (the default constructor).

 

    1. With the following public methods:

 

      1. boolean addNew(Product product) - Adds the product to the inventory.  This method prevents duplicate products from being added to the inventory.  Duplicates are considered to be products with the same product ID or products that are equal (based on the equals() method described below).  This method should return true if the product was successfully added or false the product is a duplicate.

 

      1. boolean addInventory(int productID, int quantity) - Adds the specified quantity to an existing product in the inventory.  Note that the quantity passed in may be positive or negative.  If it is negative and adding it to the current quantity of the product would result in a value less that zero the quantity is not changed and false is returned, otherwise the method returns true.

 

      1. ArrayList<Book> findBooksByAuthor(String last, String first, String middle) – Searches the Inventory for books by the specified author and returns all matches in an ArrayList or an empty ArrayList if no matches found.  Any of the parameters, last, first, or middle may be null.   If a parameter is null then that part of the name is ignored for matching purposes.  For example, passing in (Smith, null, null) would return all books by any author with the last name “Smith” regardless of first or middle name; passing in (null, null, null) would return all books by any author.  Hint: you will probably want to put this matching logic in the Name class so you can use it for other methods which do similar matching.

 

      1. ArrayList<Book> findBooksByTitle(String title) – Returns an ArrayList of all books matching the specified title, otherwise an empty ArrayList.

 

      1. ArrayList<BookOnTape> findBookOnTapeByReader(String last, String first, String middle) – Similar to findBooksByAuthor() above but returns an ArrayList of BookOnTape objects that match the specified Reader.  Ask me if you need further clarification.

 

      1. ArrayList<CD> findCDsByArtist(String last, String first, String middle) – Similar to findBooksByAuthor() above but returns an ArrayList of CD objects matching the specified Artist.  Ask me if you need further clarification.

 

      1. ArrayList<CD> findCDsByTitle(String title) – Similar to findBooksByTitle() above but returns an ArrayList of CD objects matching the specified title.  Ask me if you need further clarification.

 

  1. Implement an abstract class called Product.

 

    1. With a private static int to use as a source of unique IDs when you are constructing new products.  The first product should added to the inventory should have a value of 100000 and each subsequent product should get an ID one larger.

 

    1. With the following private instance fields:

 

      1. An int to contain the unique ID of a product.

 

      1. An int to contain the number of units in stock.

 

      1. A String to contain a description of the product.

 

      1. A double representing the wholesale price of the product.

 

      1. A double representing the retail price of the product.

 

    1. With the following two constructors:

 

      1. Product() – Using the private static in defined above, this constructor should assign a unique value to the private instance variable representing the product ID and initialize the other instance fields as necessary and appropriate.

 

      1. Product(int productID) – Assign the productID passed in to the private instance variable representing the product ID and initialize the other instance fields as necessary and appropriate.

 

      1. Notice the lack of specific direction regarding initialization of most of the instance variables – the choices you make in your constructors will impact how you implement rest of the class methods, especially the equals method.

 

    1. The following public accessor and mutator methods – ask if you need clarification about what these methods should do:

 

      1. int getProductID()

 

      1. int getQuantity()

 

      1. void setQuantity(int quantity)

 

      1. String getDescription()

 

      1. void setDescription(String description)

 

      1. double getWholesalePrice()

 

      1. void setWholesalePrice(double)

 

      1. double getRetailPrice()

 

      1. void setRetailPrice(double)

 

    1. Override the equals(Object) method of Object.  This should be a well-formed equals method as described in class and in your text.  DO NOT include the unique productID or quantity instance fields as part of the equality test.  We want the equals() method to consider logically identical products as equal regardless of their unique product ID or quantity on hand.  All other instance variables of this class should be compared as part of the equality test for this class.

 

  1. Implement an abstract class called AbstractBook that extends Product.

 

    1. With the following public int constants:

 

      1. FICTION                  (Constant used by the getType/setType methods - value of constant to be determined by you)
      2. NONFICTION            (Constant used by the getType/setType methods - value of constant to be determined by you)

 

    1. With the following private instance fields:

 

      1. A String to represent the title of the book.

 

      1. A String to represent the publisher of the book.

 

      1. A Name (class described below) reference to represent the author of the book.

 

      1. An int to represent the type, FICTION or NONFICTION, of the book.  Initial value should be FICTION.

 

    1. With the following constructors:

 

      1. AbstractBook() – See matching super-class constructor description for behavior.

 

      1. AbstractBook(int productID) – See matching super-class constructor description for behavior.

 

      1. Notice the lack of specific direction regarding initialization of most of the instance variables – the choices you make in your constructors will impact how you implement rest of the class methods, especially the equals method.

 

      1. Remember that the super-class needs to be initialized without using any of the mutator methods.

 

    1. With the following public accessor and mutator methods – ask if you need clarification about what these methods should do:

 

      1. String getTitle()

 

      1. void setTitle(String)

 

      1. String getPublisher()

 

      1. void setPublisher(String)

 

      1. Name getAuthor()

 

      1. void setAuthor(Name)

 

      1. int getType()

 

      1. void setType(int)

 

    1. Override the equals(Object) method of the Product class.  This should be a well-formed equals method as described in class and in your text.  Make sure you include all instance fields of this class and consider its super-class without using explicit accessor methods.

 

  1. Implement a class called Book that extends AbstractBook.

 

    1. With the following public int constants:

 

      1. HARD_COVER           (Constant used by getBinding/setBinding – value of constant to be determined by you)

 

      1. PAPERBACK              (Constant used by getBinding/setBinding – value of constant to be determined by you)

 

    1. With the following private instance fields:

 

      1. An int to represent the number of pages in the book.

 

      1. An int to represent the binding type, HARD_COVER or PAPERBACK.  Initial value should be HARD_COVER.

 

    1. With the following constructors:

 

      1. Book() – See matching super-class constructor description for behavior.

 

      1. Book(int productID) – See matching super-class constructor description for behavior.

 

      1. Notice the lack of specific direction regarding initialization of most of the instance variables – the choices you make in your constructors will impact how you implement rest of the class methods, especially the equals method.

 

      1. Remember that the super-class needs to be initialized without using any of the mutator methods.

 

    1. With the following public accessor and mutator methods – ask if you need clarification about what these methods should do:

 

      1. int getPages()

 

      1. void setPages(int)

 

      1. int getBinding()

 

      1. void setBinding(int)

 

    1. Override the equals(Object) method of AbstractBook.  This should be a well-formed equals method as described in class and in your text.  Make sure you include all instance fields of this class and consider its super-class without using explicit accessor methods.

 

  1. Implement a class called BookOnTape that extends AbstractBook.

 

    1. With the following public static int constants:

 

      1. TAPE   (Constance used by getFormat/setFormat – value of constant to be determined by you)

 

      1. CD      (Constance used by getFormat/setFormat – value of constant to be determined by you)

 

      1. DVD    (Constance used by getFormat/setFormat – value of constant to be determined by you)

 

    1. With the following private instance fields:

 

      1. A Name (class described below) reference to represent the reader of the book.

 

      1. An int to represent the length of the BookOnTape in minutes.

 

      1. An int to represent the format, TAPE, CD, or DVD.  Initial value should be TAPE.

 

    1. With the following constructors:

 

      1. BookOnTape() – See matching super-class constructor description for behavior.

 

      1. BookOnTape(int productID) – See matching super-class constructor description for behavior.

 

      1. Notice the lack of specific direction regarding initialization of most of the instance variables – the choices you make in your constructors will impact how you implement rest of the class methods, especially the equals method.

 

      1. Remember that the super-class needs to be initialized without using any of the mutator methods.

 

    1. With the following public accessor and mutator methods – ask if you need clarification about what these methods should do:

 

      1. Name getReader()

 

      1. void setReader(Name)

 

      1. int getLength()

 

      1. void setLength(int)

 

      1. int getFormat()

 

      1. void setFormat(int)

 

    1. Override the equals(Object) method of AbstractBook.  This should be a well-formed equals method as described in class and in your text.  Make sure you include all instance fields of this class and consider its super-class without using explicit accessor methods.

 

  1. Implement a class called CD that extends Product.

 

    1. With the following private instance fields:

 

      1. A String to represent the title of the CD

 

      1. A Name (class described below) to represent the name of the artist

 

    1. With the following constructors:

 

      1. CD() – See matching super-class constructor description for behavior.

 

      1. CD(int productID) – See matching super-class constructor description for behavior.

 

      1. Notice the lack of specific direction regarding initialization of most of the instance variables – the choices you make in your constructors will impact how you implement rest of the class methods, especially the equals method.

 

      1. Remember that the super-class needs to be initialized without using any of the mutator methods.

 

    1. With the following public accessor and mutator methods – ask if you need clarification about what these methods should do:

 

      1. String getTitle()

 

      1. void setTitle()

 

      1. Name getArtist()

 

      1. void setArtist(Name)

 

    1. Override the equals(Object) method of Product.  This should be a well-formed equals method as described in class and in your text.  Make sure you include all instance fields of this class and consider its super-class without using explicit accessor methods.

 

  1. Implement a class called Name.

 

    1. With the following private instance fields:

 

      1. A String to represent the first name of a person.

 

      1. A String to represent the middle name of a person.

 

      1. A String to represent the last name of a person.

 

    1. With the following constructors:

 

      1. Name() – Initializes all instance variables as necessary.

 

      1. Name(String last, String first, String middle) – Initializes all instance variables to the values passed in.

 

      1. Notice the lack of specific direction regarding initialization of most of the instance variables – the choices you make in your constructors will impact how you implement rest of the class methods, especially the equals method.

 

    1. With the following public accessor methods (ask if you need clarification about what these methods should do):

 

      1. String getFirst()

 

      1. String getMiddle()

 

      1. String getLast()

 

    1. With the following public “utility” method:

 

      1. match(String last, String first, String middle) – This method should determine if the last, first, and middle names passed in match this Name object’s instance fields with this special caveat:  If a null is passed in for one (or more) of the names it should be ignored for matching purposes.  For example, if the object’s last name is “Smith”, its first name is “Bob”, and it middle name is “” (empty string) and someone calls match( “Smith”, null, null) then match returns true.  If someone called match(“Smith”, “Jane”, “”) on the same object the method would return false.  Another example, calling match(null, null, null) would return true for any Name object.

 

    1. Override the equals(Object) method of Object.  This should be a well-formed equals method as described in class and in your text.  Make sure you include all instance fields of this class when determining equality.

 

Suggestions

  1. Remember to use the tests and given documentation to understand the conditions in which your implementation should work.
  2. Follow the test-driven development style by first reading the given JUnit test for the method you want to implement, then implement that method's functionality and watch the test pass.  If the test is not given, then write the test for how the method should work, see that it fails (since you have not written the code yet), then write the code to pass the test.
  3. Keep track of your hours worked as you go, so you don’t have to guess when you hand in your assignment (see handin section below for information on time.txt).

Testing With the Provided Tests

 

  1. Your code must be 100% correct to recieve credit.  Correctness will be determined by running the acceptance test P4TestDriver.java to be published Monday 2/4.  
  2. In addition to the acceptance test, sections 7 and 9 will be graded on the quality of JUnit tests they create for this program, section 3 will not.
  3. Use the JUnit tests while developing in a test-driven approach to ensure your code's correctness before the acceptance test is released.  Run them by opening the AllTests.java file and executing it.
  4. Ask your instructor for assistance if you are not able to run these tests on your own.

Handing in Your Source Electronically…

 

  1. Create a plain text file called time.txt to log the amount of time spent on the assignment.  The file will contain only three lines with the following information on each line: name, project number, hours spent.
                 Example time.txt file:   
                              Sally Student
                              Program 4
                              7.5 hours
              
  2. Move the necessary file(s) to your vogon account using your favorite FTP client program.
  3. Log on to vogon using your favorite Shell client program.
  4. Change directory (cd-command) to the directory containing the file(s) to hand in.  Be sure you code compiles and runs correctly on vogon before turning it in!
  5. Use the following handin command being sure to:

 

    1. Replace the x with the correct maximum score you can earn based on the due date, i.e., replace y with 100 if you are handing in by Monday’s deadline, 90 for Tuesday, 80 for Wednesday, or 70 for Thursday, for example Program4-100, Program4-90, et cetera.

 

12:01pm vogon ~$ handin graderkm Program4-y Inventory.java Product.java AbstractBook.java Book.java BookOnTape.java CD.java Name.java InventoryTest.java BookOnTapeTest.java CDTest.java time.txt