CIS 211 - Computer Science II
Winter, 2003 - A. Hornof
This Project is due on Monday, February 17, at 5 PM.
This project will give you practice the following programming techniques:
In this project, you will write a program that reads the input file as in Project 2 and creates a MaritimeModel as in Project 3. In this project, you will reuse and extend both of those sets of code (or the Project 2 and 3 solutions provided on the course web page). You will write a program that reads in the input file and puts the specified Ships and Islands into the MaritimeModel. Your program will read the model from a slightly-enhanced version of the data file used in Project 2. It will create a MaritimeModel of the dimensions specified in the input data file. It will create a Ship or Island object for each Ship or Island described in the data file. As in Project 3, the constructors will announce each object's creation. Once all objects are created, the program will list the contents of the MaritimeModel and then save the objects back to the data file.
Project 4 builds on Projects 2 and 3. You may build on your previous code or you may build on the solutions provided for previous projects. You may not, however, start with any code written by other students in the class.
The Project 4 Addendum posted on the course web site is officially part of these project specifications. You should check it at least at the beginning of each work session. Be sure to start the project early enough to have an opportunity to ask for clarification in case it is necessary.
The first step in Project 4 is for you to create a general purpose file-reading method and file-writing method and to put these methods into a class called FileUtils.java in a package called "util". These utilities will be useful in this project as well as in any future projects in which you want to read/write files to/from ArrayLists while providing a minimum set of user interaction if problems are encountered.
This will be a class that contains only two public methods: fileToStringList() and stringListToFile(). The first opens and reads an input file into an ArrayList of Strings, and the second puts an ArrayList of Strings into a file. It should recreate the same user interaction specified in the first part of Project 2. The fileToStringList() method should not verify the contents of the file. For example, it shouldn't check that the first line is "Maritime Simulation World State". You can re-use any of the methods that you wrote for Project 2, or any of the methods provided in the Project 2 Solution on the web page. (But keeping with the academic honest policy of the course--see the Syllabus--you may not reuse code written by other students. See me if you have any questions or concerns on this matter.)
All methods besides the two specified here should be private. All variables should be private. All methods should be class methods. No instance of FileUtils should ever be created, and you should in fact insure that no code written outside of the FileUtils class could possibly create a FileUtils object.
To make the methods slightly more generic and useful, remove the word "simulation" from all of the error messages. When you are done, you will have a generic and useful FileUtils.java class that you can use any time you want to load a file into an ArrayList or save the ArrayList into a file.
There is one additional mechanism for you to add: a QuittingException class which is derived from the Exception class. Follow the Java convention of one class per ".java" file. Put the QuittingException class in the "util" package. As in Project 2, if the user types a 'Q' or 'q' at the specified places, the program quits. This will be accomplished by fileToStringList() and stringListToFile() throwing a QuittingException that is caught by main(). The following functionality provided in Project 2 must be also preserved: If a user types a 'Q' during the file-reading phase, the program quits with no message, but if the user types the 'q' during the file-writing phase, the program should display the message "The data file was not saved." No other junk such as "util.QuittingException" should be displayed. No blank lines should be printed either.
Write a program P4_1.java that uses the FileUtils methods from the "util" package to read in a file, save it to an ArrayList, and writes the ArrayList to the same file. The functionality is identical to simModel_2_1.java except that the word "simulation" is removed from all user messages. As before, use the first command line argument as the input filename or "world.txt" if no argument is provided. Ignore any other command line arguments.
P4_1.java should be a very small file primarily containing just the following code. You will need to add a little additional code before and after, but the "try" block should be cut and pasted from here.
...
try
{
// Read the file into the stringList.
fileName = FileUtils.fileToStringList (fileName, stringList);
// Save the stringList into the file.
FileUtils.stringListToFile(stringList, fileName);
}
...
The Products of Step 1 include P4_1.java, FileUtils.java, and QuittingException.java. Submit them via e-turnin.
In Project 2, the checkFileFormat() method was used to confirm that the contents of the stringList ArrayList conformed to a maritime simulation file format specification. Since the specification relates closely to the design of the maritime classes, the format-checking functionality is being moved into the MaritimeModel class as a public "class method" called stringListToModel(). It will take one argument, an ArrayList that is the contents of a maritime simulation data file. The contents of the ArrayList will not have been verified to conform to maritime data file format specifications. The method stringListToModel() will both (1) verify that the ArrayList conforms to specifications and (2) load the ArrayList into the MaritimeModel.
There are two subtasks in this step of the project: (1) Upgrade the file-checking to accommodate the new file specification and (2) get the checked file into MaritimeModel by calling the appropriate constructors in the maritime package. It is probably best to start by extending the code to accommodate the new file format specification without creating any maritime objects. However, as you make these modifications, bear in mind that you will need to call constructors with the data in each ArrayList entry, so at least jot down some notes or comments as you go as to what kinds of modifications will be needed, and where they will be needed. But it is probably best to save the implementation until later. Solve one problem at a time.
These are the modifications you will make to checkFileFormat(), regardless of whether you start with your own solution or the solution provided on the course web page.
1. The world size must be at least 1 1. If not, output the error message shown below and quit.
2. When reading the input data file, verify that the Ships and Island X and Y coordinates are less than or equal to the corresponding coordinates provided for the size of the world. If they are not, output the error message shown below and quit. Consider implementing this one after you have added the code that fills the MaritimeModel, so that you can you retrieve the world size from the MaritimeModel.
3. Expand the data file's description of Islands to include two additional integers. The first is the amount of fuel oil currently available at the island. The second is the production rate of oil on that island. Verify that both can be parsed as Integers. If not, output the error message shown below and quit.
4. Since we will not be simulating wind patterns in our simulation, there will be no means for a Sailboat to move. Hence, a Sailboat is no longer an acceptable Ship type, and should generate an error message if specified in the data file.
5. This is the new error message for any improperly formatted line in the data file.
Error: Line <line number> in maritime simulation data
file <data filename> is improperly formatted: "<The line appears here>"
As in Project 2, when the first file format error is encountered, the error message should be displayed and then the program should quit. In this Project, this will be accomplished in part by having stringListToModel() throw a QuittingException that is caught in main().
After the file format-checking is complete, further modify stringListToModel() so that it creates a Ship and an Island object for every Ship and Island specified in the data file and adds all the Ships and Islands to the appropriate ArrayLists in MaritimeModel. Each should be added in the order that it is encountered in the data file.
Confirm everything is working by studying the constructor output statements for a variety of input files that you create.
Finally, write the code that will output the objects to an ArrayList. This will be done in the public method modelToStringList() in the MaritimeModel class. The method will take an ArrayList as a parameter, clear the the ArrayList, and fill it with Strings that correspond to the correctly-formatted lines in a maritime simulation data file. Don't forget to include the first two Strings in the file. Traverse the MaritimeModel list of SimObjects in order from start to end.
To make this method easier to implement, create a public getFileLine() method in every class in which you created a toString() method in Project 3. The method getFileLine() will be identical in every way to the toString() methods except that getFileLine() will return a String that is formatted appropriately for the maritime simulation data file. The Location getFileLine() will return simply "<X> <Y>" (an String consisting of an integer, a space, and an integer) which you should find useful inside of all of the other getFileLine() methods.
The getFileLine() for the Island class, for example, would return the following (assuming these data values):
Island Hawaii 87 2
The P4.java that you turn in should include the following try block, exactly as it appears here. This code block should also help you to understand how the four methods work together.
try
{
// Read the file into the stringList.
fileName = FileUtils.fileToStringList (fileName, stringList);
// Load the stringList into the model.
(MaritimeModel.getInstance()).stringListToModel(stringList);
stringList.clear(); // Just to make sure it is cleared.
// Save the model to the stringList.
(MaritimeModel.getInstance()).modelToStringList(stringList);
// Save the stringList into the file.
FileUtils.stringListToFile(stringList, fileName);
}
As before, P4 should use the first command line argument as the input filename or "world.txt" if no argument is provided.
The Products of Steps 2 and 3 include P4.java and a new MaritimeModel.java. Submit them via e-turnin.
If you didn't get full credit on Project 2, consider using the solution provided on the web. We may "regression test" to make sure that all of the Project 2 file-reading and file-checking is still there.
Start early. If you do not have a good solution to Project 2 and decide to use the solution provided on the course web page, you will need to spend some time understanding how it works and how to modify it so that it throws the correct QuittingException. Regardless of which Project 2 you use, there will be a lot of code surgery and fine-tuning to be done.
Compile regularly. Bring your code to working stopping points regularly. Back up these intermediary working versions, such as in a folder called "Backup" and in a further subfolder with the current date and time, as in "2-2-03-1130PM". In case you accidentally ruin working code later on or your disk crashes, you can easily revert back to a previous working version and continue.
Test your code and your package specifications by deleting all class files in your current directory and in the CLASSPATH directories, by removing all .java files except P4.java from your current working directory, and by then compiling and running P4.java from the command line.
You will receive credit for programs that compile using the correct package declarations and that solve the problems as specified. You will not receive any credit for code that does not compile from the command line using Java 1.4.1. Any problems with your Project 2 and Project 3 solutions must be fixed for this project. For example, if your program still has a bug of always requiring a command line argument, then your project could fail all of the tests in Project 4.