create a method that accepts an IOException as an

profileTopsolutions
src_question.zip

DAOFactory.java

DAOFactory.java

public   class   DAOFactory
{
     // this method maps the ProductDAO interface
     // to the appropriate data storage mechanism
     public   static   ProductDAO  getProductDAO ()
     {
         ProductDAO  pDAO  =   new   ProductTextFile ();
         return  pDAO ;
     }
}

IOStringUtils.java

IOStringUtils.java

import  java . io . * ;

public   class   IOStringUtils
{
     public   static   void  writeFixedString ( DataOutput  out ,   int  length ,
     String  s )   throws   IOException
     {
         for   ( int  i  =   0 ;  i  <  length ;  i ++ )
         {
             if   ( <  s . length ())
                out . writeChar ( s . charAt ( i ));   // write char
             else
                out . writeChar ( 0 );             // write Unicode zero
         }
     }

     public   static   String  readFixedString ( DataInput  in ,   int  length )
     throws   IOException
     {
         StringBuilder  sb  =   new   StringBuilder ();
         for   ( int  i  =   0 ;  i  <  length ;  i ++ )
         {
             char  c  =  in . readChar ();
             // if char is not Unicode zero add to string
             if   ( !=   0 )
                sb . append ( c );
         }
         return  sb . toString ();
     }
}

Product.java

Product.java

import  java . text . NumberFormat ;

public   class   Product
{
     private   String  code ;
     private   String  description ;
     private   double  price ;

     public   Product ()
     {
         this ( "" ,   "" ,   0 );
     }

     public   Product ( String  code ,   String  description ,   double  price )
     {
         this . code  =  code ;
         this . description  =  description ;
         this . price  =  price ;
     }

     public   void  setCode ( String  code )
     {
         this . code  =  code ;
     }

     public   String  getCode (){
         return  code ;
     }

     public   void  setDescription ( String  description )
     {
         this . description  =  description ;
     }

     public   String  getDescription ()
     {
         return  description ;
     }

     public   void  setPrice ( double  price )
     {
         this . price  =  price ;
     }

     public   double  getPrice ()
     {
         return  price ;
     }

     public   String  getFormattedPrice ()
     {
         NumberFormat  currency  =   NumberFormat . getCurrencyInstance ();
         return  currency . format ( price );
     }

     public   boolean  equals ( Object  object )
     {
         if   ( object  instanceof   Product )
         {
             Product  product2  =   ( Product )  object ;
             if
             (
                code . equals ( product2 . getCode ())   &&
                description . equals ( product2 . getDescription ())   &&
                price  ==  product2 . getPrice ()
             )
                 return   true ;
         }
         return   false ;
     }

     public   String  toString ()
     {
         return   "Code:        "   +  code  +   "\n"   +
                "Description: "   +  description  +   "\n"   +
                "Price:       "   +   this . getFormattedPrice ()   +   "\n" ;
     }
}

ProductConstants.java

ProductConstants.java

public   interface   ProductConstants
{
     int  CODE_SIZE  =   4 ;
     int  DESCRIPTION_SIZE  =   40 ;
}

ProductDAO.java

ProductDAO.java

public   interface   ProductDAO   extends   ProductReader ,   ProductWriter ,   ProductConstants
{
     // all methods from the ProductReader and ProductWriter interfaces
     // all static constants from the ProductConstants interface
}

ProductMaintApp.java

ProductMaintApp.java

import  java . util . Scanner ;
import  java . util . ArrayList ;

public   class   ProductMaintApp   implements   ProductConstants
{
     // declare two class variables
     private   static   ProductDAO  productDAO  =   null ;
     private   static   Scanner  sc  =   null ;

     public   static   void  main ( String  args [])
     {
         // display a welcome message
         System . out . println ( "Welcome to the Product Maintenance application\n" );

         // set the class variables
        productDAO  =   DAOFactory . getProductDAO ();
        sc  =   new   Scanner ( System . in );
        
         // display the command menu
        displayMenu ();

         // perform 1 or more actions
         String  action  =   "" ;
         while   ( ! action . equalsIgnoreCase ( "exit" ))
         {
             // get the input from the user
            action  =   Validator . getString ( sc ,
                     "Enter a command: " );
             System . out . println ();

             if   ( action . equalsIgnoreCase ( "list" ))
                displayAllProducts ();
             else   if   ( action . equalsIgnoreCase ( "add" ))
                addProduct ();
             else   if   ( action . equalsIgnoreCase ( "del" )   ||  action . equalsIgnoreCase ( "delete" ))
                deleteProduct ();
             else   if   ( action . equalsIgnoreCase ( "help" )   ||  action . equalsIgnoreCase ( "menu" ))
                displayMenu ();
             else   if   ( action . equalsIgnoreCase ( "exit" )   ||  action . equalsIgnoreCase ( "quit" ))
                 System . out . println ( "Bye.\n" );
             else
                 System . out . println ( "Error! Not a valid command.\n" );
         }
     }

     public   static   void  displayMenu ()
     {
         System . out . println ( "COMMAND MENU" );
         System . out . println ( "list    - List all products" );
         System . out . println ( "add     - Add a product" );
         System . out . println ( "del     - Delete a product" );
         System . out . println ( "help    - Show this menu" );
         System . out . println ( "exit    - Exit this application\n" );
     }

     public   static   void  displayAllProducts ()
     {
         System . out . println ( "PRODUCT LIST" );

         ArrayList < Product >  products  =  productDAO . getProducts ();
         Product  p  =   null ;
         StringBuilder  sb  =   new   StringBuilder ();
         for   ( int  i  =   0 ;  i  <  products . size ();  i ++ )
         {
            p  =  products . get ( i );
            sb . append ( StringUtils . padWithSpaces (
                    p . getCode (),  CODE_SIZE  +   4 ));
            sb . append ( StringUtils . padWithSpaces (
                    p . getDescription (),  DESCRIPTION_SIZE  +   4 ));
            sb . append (
                    p . getFormattedPrice ());
            sb . append ( "\n" );
         }
         System . out . println ( sb . toString ());
     }

     public   static   void  addProduct ()
     {
         String  code  =   Validator . getString (
                sc ,   "Enter product code: " );
         String  description  =   Validator . getLine (
                sc ,   "Enter product description: " );
         double  price  =   Validator . getDouble (
                sc ,   "Enter price: " );

         Product  product  =   new   Product ();
        product . setCode ( code );
        product . setDescription ( description );
        product . setPrice ( price );
        productDAO . addProduct ( product );

         System . out . println ();
         System . out . println ( description
                 +   " has been added.\n" );
     }

     public   static   void  deleteProduct ()
     {
         String  code  =   Validator . getString ( sc ,
                 "Enter product code to delete: " );

         Product  p  =  productDAO . getProduct ( code );

         System . out . println ();
         if   ( !=   null )
         {
            productDAO . deleteProduct ( p );
             System . out . println ( p . getDescription ()
             +   " has been deleted.\n" );
         }
         else
         {
             System . out . println ( "No product matches that code.\n" );
         }
     }
}

ProductRandomFile.java

ProductRandomFile.java

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

public   class   ProductRandomFile   implements   ProductDAO
{
     private   RandomAccessFile  productsFile  =   null ;
     private   ArrayList < String >  productCodes  =   null ;

     private   final   int  PRICE_SIZE  =   8 ;    // doubles are 8 bytes
     private   final   int  RECORD_SIZE  =
        CODE_SIZE  *   2   +            // from the ProductConstants interface
        DESCRIPTION_SIZE  *   2   +     // from the ProductConstants interface
        PRICE_SIZE ;
     private   final   String  DELETION_CODE  =   "    " ;

     public   ProductRandomFile ()
     {
         try
         {
            productsFile  =   new   RandomAccessFile ( "products.ran" ,   "rw" );
            productCodes  =   this . getCodes ();
         }
         catch ( IOException  e )
         {
             System . out . println ( e );
         }
     }

     //*************************************************
     // Private methods for reading products
     //*************************************************

     private   int  getRecordCount ()   throws   IOException
     {
         int  recordCount  =   ( int )  productsFile . length ()   /  RECORD_SIZE ;
         return  recordCount ;
     }

     private   int  getRecordNumber ( String  productCode )
     {
         for   ( int  i  =   0 ;  i  <  productCodes . size ();  i ++ )
         {
             String  code  =  productCodes . get ( i );
             if   ( productCode . equals ( code ))
                 return  i ;
         }
         return   - 1 ;    // no record matches the product code
     }

     private   Product  getRecord ( int  recordNumber )   throws   IOException
     {
         if   ( recordNumber  >=   0   &&  recordNumber  <   this . getRecordCount ())
         {
            productsFile . seek ( recordNumber  *  RECORD_SIZE );

             String  code  =   IOStringUtils . readFixedString (
                productsFile ,  CODE_SIZE );
             String  description  =   IOStringUtils . readFixedString (
                productsFile ,  DESCRIPTION_SIZE );
             double  price  =  productsFile . readDouble ();

             Product  product  =   new   Product ( code ,  description ,  price );
             return  product ;
         }
         else
         {
             return   null ;
         }
     }

     private   ArrayList < String >  getCodes ()
     {
         try
         {
             ArrayList < String >  codes  =   new   ArrayList <> ();
             for   ( int  i  =   0 ;  i  <  getRecordCount ();  i ++ )
             {
                productsFile . seek ( *  RECORD_SIZE );
                codes . add ( IOStringUtils . readFixedString (
                    productsFile ,  CODE_SIZE ));
             }
             return  codes ;
         }
         catch ( IOException  e )
         {
             System . out . println ( e );
             return   null ;
         }
     }

     //*********************************************************
     // Public methods for reading products
     //*********************************************************

     public   ArrayList < Product >  getProducts ()
     {
         ArrayList < Product >  products  =   new   ArrayList <> ();
         try
         {
             for   ( int  i  =   0 ;  i  <  productCodes . size ();  i ++ )
             {
                 // if record has been marked for deletion,
                 // don't add to products array list
                 if   ( ! productCodes . get ( i ). equals ( DELETION_CODE ))
                 {
                     Product  product  =   this . getRecord ( i );
                    products . add ( product );
                 }
             }
         }
         catch ( IOException  e )
         {
             System . out . println ( e );
             return   null ;
         }
         return  products ;
     }

     public   Product  getProduct ( String  productCode )
     {
         try
         {
             int  recordNumber  =   this . getRecordNumber ( productCode );
             Product  product  =   this . getRecord ( recordNumber );
             return  product ;
         }
         catch ( IOException  e )
         {
             System . out . println ( e );
             return   null ;
         }
     }

     //*************************************************
     //* Private methods for writing products
     //*************************************************

     private   boolean  writeProduct ( Product  product ,   int  recordNumber )
     {
         try
         {
            productsFile . seek ( recordNumber  *  RECORD_SIZE );
             IOStringUtils . writeFixedString (
                productsFile ,  CODE_SIZE ,  product . getCode ());
             IOStringUtils . writeFixedString (
                productsFile ,  DESCRIPTION_SIZE ,  product . getDescription ());
            productsFile . writeDouble ( product . getPrice ());
             return   true ;
         }
         catch ( IOException  e )
         {
             System . out . println ( e );
             return   false ;
         }
     }

     //*************************************************
     //* Public methods for writing products
     //*************************************************

     public   boolean  addProduct ( Product  product )
     {
        productCodes . add ( product . getCode ());
         int  recordNumber  =  getRecordNumber ( product . getCode ());
         return  writeProduct ( product ,  recordNumber );
     }

     public   boolean  updateProduct ( Product  product )
     {
         int  recordNumber  =  getRecordNumber ( product . getCode ());
         if   ( recordNumber  !=   - 1 )
             return  writeProduct ( product ,  recordNumber );
         else
             return   false ;
     }

     public   boolean  deleteProduct ( Product  product )
     {
         int  recordNumber  =  getRecordNumber ( product . getCode ());
         if   ( recordNumber  !=   - 1 )
         {
            productCodes . set ( recordNumber ,  DELETION_CODE );
            product . setCode ( DELETION_CODE );    // mark record for deletion
             return  writeProduct ( product ,  recordNumber );
         }
         else
         {
             return   false ;
         }
     }
}

ProductReader.java

ProductReader.java

import  java . util . ArrayList ;

public   interface   ProductReader
{
     Product  getProduct ( String  code );
     ArrayList < Product >  getProducts ();
}

ProductTextFile.java

ProductTextFile.java

import  java . util . * ;
import  java . io . * ;
import  java . nio . file . * ;

public   final   class   ProductTextFile   implements   ProductDAO
{
     private   ArrayList < Product >  products  =   null ;
     private   Path  productsPath  =   null ;
     private   File  productsFile  =   null ;

     private   final   String  FIELD_SEP  =   "\t" ;

     public   ProductTextFile ()
     {
        productsPath  =   Paths . get ( "products.txt" );
        productsFile  =  productsPath . toFile ();
        products  =   this . getProducts ();
     }

     public   ArrayList < Product >  getProducts ()
     {
         // if the products file has already been read, don't read it again
         if   ( products  !=   null )
             return  products ;         

        products  =   new   ArrayList <> ();         
        
         if   ( Files . exists ( productsPath ))    // prevent the FileNotFoundException
         {
             try
             {
                
                 // open the input stream
                 BufferedReader  in  =  
                      new   BufferedReader (
                      new   FileReader ( productsFile ));
                
                 // read all products stored in the file
                 // into the array list
                 String  line  =  in . readLine ();
                 while ( line  !=   null )
                 {
                     String []  columns  =  line . split ( FIELD_SEP );
                     String  code  =  columns [ 0 ];
                     String  description  =  columns [ 1 ];
                     String  price  =  columns [ 2 ];

                     Product  p  =   new   Product (
                        code ,  description ,   Double . parseDouble ( price ));

                    products . add ( p );

                    line  =  in . readLine ();                     
                 }
                
                 // close the input stream
                in . close ();
             }
             catch ( IOException  e )
             {
                 System . out . println ( e );
                 return   null ;
             }
         }
         return  products ;             
     }

     public   Product  getProduct ( String  code )
     {
         for   ( Product  p  :  products )
         {
             if   ( p . getCode (). equals ( code ))
                 return  p ;
         }
         return   null ;
     }

     public   boolean  addProduct ( Product  p )
     {
        products . add ( p );
         return   this . saveProducts ();
     }

     public   boolean  deleteProduct ( Product  p )
     {
        products . remove ( p );
         return   this . saveProducts ();
     }

     public   boolean  updateProduct ( Product  newProduct )
     {
         // get the old product and remove it
         Product  oldProduct  =   this . getProduct ( newProduct . getCode ());
         int  i  =  products . indexOf ( oldProduct );
        products . remove ( i );

         // add the updated product
        products . add ( i ,  newProduct );

         return   this . saveProducts ();
     }

     private   boolean  saveProducts ()
     {         
     try
         {
             // open the output stream
             PrintWriter  out  =   new   PrintWriter (
                               new   BufferedWriter (
                               new   FileWriter ( productsFile )));

             // write all products in the array list
             // to the file
             for   ( Product  p  :  products )
             {
                out . print ( p . getCode ()   +  FIELD_SEP );
                out . print ( p . getDescription ()   +  FIELD_SEP );
                out . println ( p . getPrice ());
             }
            
             // close the output stream
            out . close ();
         }
         catch ( IOException  e )
         {
             System . out . println ( e );
             return   false ;
         }

         return   true ;
     }    
}

ProductWriter.java

ProductWriter.java

public   interface   ProductWriter
{
     boolean  addProduct ( Product  p );
     boolean  updateProduct ( Product  p );
     boolean  deleteProduct ( Product  p );
}

StringUtils.java

StringUtils.java

public   class   StringUtils
{
     public   static   String  padWithSpaces ( String  s ,   int  length )
     {
         if   ( s . length ()   <  length )
         {
             StringBuilder  sb  =   new   StringBuilder ( s );
             while ( sb . length ()   <  length )
             {
                sb . append ( " " );
             }
             return  sb . toString ();
         }
         else
         {
             return  s . substring ( 0 ,  length );
         }
     }
}

Validator.java

Validator.java

import  java . util . Scanner ;

public   class   Validator
{
     public   static   String  getLine ( Scanner  sc ,   String  prompt )
     {
         System . out . print ( prompt );
         String  s  =  sc . nextLine ();          // read the whole line
         return  s ;
     }

     public   static   String  getString ( Scanner  sc ,   String  prompt )
     {
         System . out . print ( prompt );
         String  s  =  sc . next ();          // read the first string on the line
        sc . nextLine ();                 // discard the rest of the line
         return  s ;
     }

     public   static   int  getInt ( Scanner  sc ,   String  prompt )
     {
         boolean  isValid  =   false ;
         int  i  =   0 ;
         while   ( isValid  ==   false )
         {
             System . out . print ( prompt );
             if   ( sc . hasNextInt ())
             {
                i  =  sc . nextInt ();
                isValid  =   true ;
             }
             else
             {
                 System . out . println ( "Error! Invalid integer value. Try again." );
             }
            sc . nextLine ();    // discard any other data entered on the line
         }
         return  i ;
     }

     public   static   int  getInt ( Scanner  sc ,   String  prompt ,
     int  min ,   int  max )
     {
         int  i  =   0 ;
         boolean  isValid  =   false ;
         while   ( isValid  ==   false )
         {
            i  =  getInt ( sc ,  prompt );
             if   ( <=  min )
                 System . out . println (
                     "Error! Number must be greater than "   +  min );
             else   if   ( >=  max )
                 System . out . println (
                     "Error! Number must be less than "   +  max );
             else
                isValid  =   true ;
         }
         return  i ;
     }

     public   static   double  getDouble ( Scanner  sc ,   String  prompt )
     {
         boolean  isValid  =   false ;
         double  d  =   0 ;
         while   ( isValid  ==   false )
         {
             System . out . print ( prompt );
             if   ( sc . hasNextDouble ())
             {
                d  =  sc . nextDouble ();
                isValid  =   true ;
             }
             else
             {
                 System . out . println ( "Error! Invalid decimal value. Try again." );
             }
            sc . nextLine ();    // discard any other data entered on the line
         }
         return  d ;
     }

     public   static   double  getDouble ( Scanner  sc ,   String  prompt ,
     double  min ,   double  max )
     {
         double  d  =   0 ;
         boolean  isValid  =   false ;
         while   ( isValid  ==   false )
         {
            d  =  getDouble ( sc ,  prompt );
             if   ( <=  min )
                 System . out . println (
                     "Error! Number must be greater than "   +  min );
             else   if   ( >=  max )
                 System . out . println (
                     "Error! Number must be less than "   +  max );
             else
                isValid  =   true ;
         }
         return  d ;
     }

}