Part 6 Guidance

Problem

You’re going to work on a strategy to output your data to both the screen (which the software already does) and to the file system.

Activity 1 (~ 20 mins)

Sketch out a modified class model showing how the business objects can be written to both the screen and file system.  Consider reusing the classes Writer and ScreenWriter.

Activity 2 (~ 60 mins)

Now code your solution. Examine the solution FileTextCopy.java for help. 

You will need to create a new interface as follows

Sample code
public interface OutputChannel
{
    public  void    write( String dataStream );
    public  void    close();
}

You will need to create a new writer similar to ScreenWriter but capable of writing to files, make it an implementation of OutputChannel.

The close() is very important.  Classes that implement this interface must ensure that an output file is closed after use, otherwise data written to the file will be lost.

Here is TextFileWriter

TextFileWriter
public class TextFileWriter   implements  OutputChannel
{
    private String  itsFileName;
    private PrintWriter itsPrintWriter;
    
    public  TextFileWriter()
    {
    }
    
    public  void    openForWriting( String fname )
    {
        itsFileName = fname;
        
        try
        {
            itsPrintWriter = new PrintWriter(new BufferedWriter(new FileWriter(fname)));
        } catch (IOException ex)
        {
            Logger.getLogger(TextFileWriter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }    
    @Override
    public  void    write( String dataStream )
    {
        itsPrintWriter.printf("%s", dataStream );
    }   
    
    @Override
    public  void    close()
    {
        itsPrintWriter.close();
    }
    
}


Modify ScreenWriter so that it implements OutputChannel.

ScreenWriter
public class ScreenWriter   implements  OutputChannel
{
    @Override
    public  void    write( String dataStream )
    {
        System.out.printf("%s", dataStream );
    } 
    
    @Override
    public  void    close()
    {
    }
}


Modify Writer so it has a new method with the following signature

Writer
public class Writer
{
    private static  final   ScreenWriter    screenWriter = new ScreenWriter();
    private static  final   TextFileWriter  textFileWriter = new TextFileWriter();
    
    public  static  OutputChannel    getScreenWriter()
    {
        return screenWriter;  
    }
    
    public  static  OutputChannel    getTextFileWriter( String fname )
    {
        textFileWriter.openForWriting(fname);
        
        return textFileWriter;  
    }
    
    public  static  Writer  getWriter( WriterMode mode )
    {
        Writer result = null;
        
        if( mode == WriterMode.XML_WRITER )
            result = null;
        
        return result;
    }
}


If your implementation is successful, you should be able to read the file (using a simple text editor) that your code has generated.  You can test it in main with the following code

MainUnit - writing out to a file
Customer cc = new Customer("Selvyn", "Wright", LocalDate.of(1965, 5, 8), "Birmingham, UK");
Account acc = new Account(cc, 1);
cc.setAccount( acc );
sw = Writer.getTextFileWriter("c:\\tmp\\account.json");
sw.write(FormatFactory.getFormatter(WriterMode.JSON_WRITER).format(acc));
sw.close();
sw = Writer.getTextFileWriter("c:\\tmp\\account.xml");
sw.write(FormatFactory.getFormatter(WriterMode.XML_WRITER).format(acc));
sw.close();
sw = Writer.getTextFileWriter("c:\\tmp\\customer.json");
sw.write(FormatFactory.getFormatter(WriterMode.JSON_WRITER).format(cc));
sw.close();


Activity 3 (~ 30 mins )

Implement code to read the data from the file back into your program. Once loaded, display it on the screen using System.out.println().  Make use of the following interface

InputChannel
public interface InputChannel
{
    public  String  read();
    public  void    close();    
}


Here is the implementation of the interface

TextFileReader
public class TextFileReader implements  InputChannel
{
    private String  itsFileName;
    private BufferedReader itsFileReader;
    
    public  TextFileReader()
    {
    }
    
    public  void    openForWriting( String fname )
    {
        itsFileName = fname;
        
        try
        {
            itsFileReader = new BufferedReader(new FileReader(fname));
        } catch (IOException ex)
        {
            Logger.getLogger(TextFileWriter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }    
    @Override
    public  String    read()
    {
        StringBuilder sb = new StringBuilder();
        String line;
        try
        {
            while( (line = itsFileReader.readLine()) != null )
                sb.append(line );
        } catch (IOException ex)
        {
            Logger.getLogger(TextFileReader.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally
        {
            close();
        }
        return sb.toString();
    }   
    
    @Override
    public  void    close()
    {
        try
        {
            itsFileReader.close();
        } catch (IOException ex)
        {
            Logger.getLogger(TextFileReader.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
}


Now add the following lines of code to MainUnit to test your code

MainUnit - reading from a file
// Read the files back in
System.out.println( "===========================================" );
TextFileReader tfr = new TextFileReader();
tfr.openForWriting("c:\\tmp\\account.json");
String jsonStream = tfr.read();
System.out.println( jsonStream );

tfr.openForWriting("c:\\tmp\\account.xml");
String xmlStream = tfr.read();
System.out.println( xmlStream );

tfr.openForWriting("c:\\tmp\\customer.json");
jsonStream = tfr.read();
System.out.println( jsonStream );