Lab: Gaining Experience with Serialization
         
            
         
         
            Instructions:
  Answer the following questions one at a time. After answering each question,
  check your answer (by clicking on the check-mark icon if it is available)
  before proceeding to the next question.
  
            
            
                
         
         
            Getting Ready:
   Before going any further, you should:
   
               - 
    Setup your development environment.
    
 
               - 
    Depending on your development environment, create either a
    directory or a project for this lab.
    
 
               - 
    Download the following files:
                  
    to an appropriate directory/folder.  (In most browsers/OSs, the
    easiest way to do this is by right-clicking/control-clicking on
    each of the links above and then selecting Save as...
    or Save link as....)
     
            
         
         
            1. In Case You Haven't Learned About Serialization: 
  If you haven't learned about serialization in Java, you should read the
   
      , 
      
lecture notes on the topic.  
  
 
         
            2. Getting Caught Up: 
  This lab is a simulation of a part of the process that is being used
  to create a product named 
TaxEze
  for the (hypothetical) company
  
FreeMarket. 
  The team is using an incremental process known as Scrum, which divides the
  work up into sprints. Since you weren't involved in the
  earlier sprints, you have some catching up to do.
  
               - 
    Read the  sprintable
    stories from the previous sprint.  (Note that not all of the
    acceptance criteria were satisfied in the previous sprint. The
    tasks required to complete those product backlog items are someone
    else's responsibility. You should be able to complete your tasks
    independently.)
    
 
               - 
    Review the UML class diagram that
    was created during the previous sprint. (Note that the UML class
    diagram is fairly abstract.)
    
 
               - 
    Create a project in your IDE.
    
 
               - 
    Copy the existing code into the 
src directory/folder
    in your IDE. (Note that the code is in several packages, one of
    which contains JUnit tests. If you copy the directories/folders
    from a file explorer and paste them into your IDE, it will create the
    appropriate packages for you.)
     
               - 
    Un-zip the 
.tax files from
    US2019.zip and put them in a convenient location
    (outside of the project).
     
               - 
    Un-zip the icons from
    
icons.zip and put them in a convenient location
    (outside of the project).
     
               - 
    Copy the icons into the project directory/folder inside of the IDE.
    
 
               - 
    Run the JUnit tests to ensure that
    the 
TaxTable class is working. (Note: You will first need
    to change the PATH in the test of the read()
    method.
     
               - 
    Run the Taxeze application to ensure that it is working.
    
 
               - 
    Read the  sprintable
    stories for this sprint.
    
 
            
            
  Note that this lab is part of a sequence, so you should save
  your work -- you may need it later.
  
          
         
            3. A Brief Review of Serialization in Java: 
  This part of the lab will help you remember some of what you've
  learned about serialization in Java.
  
               - 
    What interface must a class implement in order for its objects to
    be serializable?
 
    
    
                  
                     
                  
                  
               
 
               - 
    Which class or classes in Taxeze must implement this interface?
 
    
    
                  
                     
                        
                           
                              
    Obviously the TaxSchedule class must. But, since it extends
    HashMap it already does. However, to make it explicit, its
    useful to add it to the declaration of the class.
    In addition, since TaxSchedule 
    contains
    references to TaxTable, TaxTable must
    also implement Serializable.
    
                              
                           
                        
                      
                  
                  
                
               - 
    What is the point of the static 
serialVersionUID attribute?
 
    
    
                  
                     
                        
                           
                              
    It allows the de-serializer to compare the version of the
    serialized object with the version of the class to ensure that
    they are the same.
    
                              
                           
                        
                      
                  
                  
                
               - 
    What method in what class can be used to serialize 
Serializable
    objects?
    
    
                  
                     
                        
                           
                              
    The writeObject() method in the ObjectOutputStream
    class.
    
                              
                           
                        
                      
                  
                  
                
               - 
    What method in what class can be used to deserialize 
    
Serializable objects?
    
    
                  
                     
                        
                           
                              
    The readObject() method in the ObjectInputStream
    class.
    
                              
                           
                        
                      
                  
                  
                
               - 
    What kinds of objects are returned by the de-serializing method?
    
    
                  
                     
                        
                           
                              
                                 Object objects.
    
                              
                           
                        
                      
                  
                  
                
               - 
    As a result, what must be done to the objects it returns?
    
    
                  
                     
                        
                           
                              
    They must be typecast.
    
                              
                           
                        
                      
                  
                  
                
            
          
         
            4. Tasks: 
  The sprintable stories have been decomposed into the following tasks
  that you must complete for this lab.
  
               - 
    Declare all of the appropriate classes to be 
Serializable.
    
                  
                     
                  
                  
                
               - 
    Add a method with the signature:
    
                     
    public void write(String filename) throws IOException
    
                  
                  
    to the TaxSchedule class that serializes the owning object.
    
                  
                  
                     
                        
                           
                              
                                 
                                    
  public void write(String filename) throws IOException
  {
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename + ".txs"));
    
    out.writeObject(this);
    out.flush();
    out.close();
  }
                                 
                               
                              
                           
                        
                      
                  
                  
                
               - 
    Add a method with the signature:
    
                     
    public static TaxSchedule open(String filename) throws IOException
    
                  
                  
    to the TaxSchedule class that reads a serialized
    TaxSchedule object.
    
                  
                  
                     
                        
                           
                              
                                 
                                    
  public static TaxSchedule open(String filename) throws IOException
  {
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename + ".txs"));
    TaxSchedule schedule;
    try
    {
      schedule = (TaxSchedule)in.readObject();
    }
    catch (ClassNotFoundException cnfe)
    {
      schedule = new TaxSchedule("Unknown");
    }
    in.close();
    
    return schedule;
  }
                                 
                               
                              
                           
                        
                      
                  
                  
                
               - 
    Add a 
SerializationTests class to the testing
    package that tests these new methods.
 
    
    
                  
                     
                        
                           
                              
    It should look something like the following.
                                    
package testing;
import static org.junit.jupiter.api.Assertions.*;
import java.io.*;
import tax.*;
import org.junit.jupiter.api.Test;
class SerializationTests
{
  private static final String PATH = "CHANGE ME";
  @Test
  public void roundTrip() throws IOException
  {
    TaxSchedule   schedule = new TaxSchedule("US");
    TaxTable table;
    String name;
    
    name = "Single_2019";
    table = new TaxTable();
    table.read(PATH + name);
    schedule.put(name, table);
    
    name = "Married-Filing-Jointly_2019";
    table = new TaxTable();
    table.read(PATH + name);
    schedule.put(name, table);
    
    schedule.write(PATH + "test");
    
    schedule = TaxSchedule.open(PATH + "test");
    
    table = schedule.get("Single_2019");
    assertEquals(12.56467, table.getInterpolatedRate(42000.50), 0.001);
  }
}
                                 
                               
                              
                           
                        
                      
                  
                  
                
               - 
    Perform regression testing using the pre-existing unit tests to
    ensure you didn't introduce any defects into the code that was
    working.
    
                  
                     
                  
                  
               
 
               - 
    Have you satisfied all of the acceptance criteria?
    
    
                  
                     
                        
                           
                              
    No, I haven't added the GUI components and I haven't conducted
    the system tests. I'll do that as part of another lab.