Problems
- Use file processing to have your form letter and data read from the file system.
- Begin with the classes you developed last week (or adopt last week’s instructor sample solution).
- Create a class called
FormLetterFileReaderwhich has the following methods:- A no-parameter constructor, which simply creates a
FormLetterFileReader - A constructor which takes a file name
- A
setFilemethod which takes a file name, representing the file to read theFormLettercontents from - A
readLinemethod which returns one line read from the opened (and buffered) file - A
getTokensmethod which returns an array of tokens found on the line. A token is either a buffer of text, or a replacement data item. These data items are recognized by starting with a { and ending with a } .- Note that the
FormLetterFileReadermay store the array differently, internally; but it needs to return the result as an array of Strings. TheStringswill be tokenized and constructed into aFormLetterby theFormLetterFile.
- Note that the
- A way to test the class to ensure it works properly (e.g., read a file, and output the resulting tokens). This can be a
mainmethod, or can be JUnit tests.
- A no-parameter constructor, which simply creates a
- Create a class called
FormLetterFilewhich encapsulates a simple main method (not very different thanFormLetterHelloin many ways):- Gets two filenames from the command line or by prompting the user (implement one of the choices)
- One filename is for the
FormLetter, and one for theProperties.
- One filename is for the
- Creates a new
FormLetterFileReaderusing this filename as a parameter. - Creates a
FormLetterinstance with the filename as the title- While it can read a line from the FormLetterFileReader:
- Break the line into tokens
- For each token, if it is a simple string (i.e., doesn’t begin with a { ), add it as a text entry to the FormLetter.
- Otherwise, add it as a data item entry to the FormLetter.
- Note that various text methods, such as trimming and substrings will be needed to make this go smoothly.
- Load a
Propertieswith the contents of the associated file name. - Invoke the
doFormLettermethod on the FormLetter.
- Gets two filenames from the command line or by prompting the user (implement one of the choices)
- Run the
FormLetterFilemainmethod and capture the result for your submission. - Create your own
FormLettertemplate file and associatedPropertiesfile, and test your program by runningFormLetterFilewith them.
Notes
- The client method is expected to either call the one-parameter constructor or call the no-parameter constructor followed by calling
setFile. CallingreadLinewithout opening the file first should throw an appropriate exceptiongetTokensshould simply return a zero-length array of Strings if called with an empty String - The
setFilemethod needs to arrange for the file to be read one line at a time. This will make it convenient for the input to be setup as aBufferedReaderobject. A BufferedReader requires aFileReaderto construct it. AFileReaderis constructed from a File Also, note that it is possible the file does not exist, or perhaps cannot be read. Thus, yoursetFilemay want to call asetInputfunction like so:private void setInput(String filename) throws FileNotFoundException { try { FileReader f = new FileReader(filename); input = new BufferedReader(f); // Assumes input is the field name for the BufferedReader } catch (FileNotFoundException fnfe) { System.err.println("File "+file+" not found"); throw fnfe; // rethrow the exception }} - The
readLinemethod can use delegation returninput.readLine(), just like any otherBufferedReader. However, you may also need to catch a possibleIOExceptionit may raise. - The String split method provides an efficient way to parse input strings.
- The class
StringTokenizerprovides another very flexible way to parse input strings.- Note that, each time you find a “{” token, you next need look for a “}” token, to find the end of the
DataItemEntryname. - The basic StringTokenizer methods are
hasMoreTokens(), which returns true when there is another token to read, andnextToken(delimiter), which returns the next String bounded by that delimiter. - When constructing a
StringTokenizer, you may provide the default token delimiter, and a boolean indicating whether you’d like to get the delimiters themselves back as tokens.
- Note that, each time you find a “{” token, you next need look for a “}” token, to find the end of the
- Also, you can just find the tokens using the
StringindexOfandsubstringmethods. - It is also possible to use the
Scannerclass
- The class
- When accumulating your array of results, you may find it useful to temporarily store them in a
List<String>, since it is easy to add Strings to it. ALinkedListofStringis a good implementation class. To turn aListinto an array, remember to use thetoArraymethod of the collection object, and pass anew String[0]as a parameter to coerce the return type. Propertiescan be loaded directly, given a file name.- While you will create your own form letter, a sample form letter file might have content like so (or even be a web page):
{date}Dear {name},BREAKING: {newsHeadline}This is an ALL HANDS ON DECK SITUATION:If we don't fight back, the {otherParty} will get their way.Donate to {thisParty} TODAY so we can finally put an end to the {otherParty} shenanigans!Give {amount}£ nowOr, donate another amountPaid for by the {thisParty} PAC, not authorized by any candidate or candidate's committee. - While you will create your own properties file, a sample file, useful for the letter above, might have content like so:
name=Loyal Party Supporter newsHeadline=Rt. Hon. Lord North calls for OUTRAGEOUS INCREASE IN TAXES on TEA! thisParty=Sons Of Liberty otherParty=British date=May 8, 1773 amount=1
