Make a BadFileException , an unchecked exception, and InvalidNameFormatException and InvalidAttendanceInformationException , two checked exceptions, each in
Question:
Make a BadFileException, an unchecked exception, and InvalidNameFormatException and InvalidAttendanceInformationException, two checked exceptions, each in their respective file. All of these are concrete classes and will extend directly from Exception or RuntimeException (use the information on checked/unchecked to determine which exceptions extend from which class).
Part 2: AttendanceTaker
Variables
Variables must be not allowed to be directly modified outside the class in which they are declared, unless otherwise stated in the description of the variable.
The AttendanceTaker class must have these variables.
- File inputFile
- File outputFile
Constructors
- A constructor that accepts two File objects (inputFile and outputFile, in that order)
- A constructor that accepts two Strings to represent the filenames (again, input before output)
o Chains to the other constructor
o Hint: This should be a single-statement constructor NOTE: These constructors should not attempt to perform any operations in the files, that is, the
instantiation should always be successful (for example, it should success even if the input file doesn't exist).
Methods
- Please follow the instructions exactly. Do not make additional methods or instance variables
- public void takeAttendance()
o The first part will be processing the input file, where we will extract
an array of Strings representing the names we want to use to take attendance. If this operation is not successful, no further steps should be executed.
- The input file has a specific format, storing all its information in a single line.
- You should open the input file with a Scanner. If the Scanner throws a FileNotFoundException, it should let it propagate. Because it's a checked exception, you will have to change the method header.
- If the file is completely empty, you should throw a BadFileException with the following message: "The input file was empty" and end here.
- You should use nextLine in the scanner to get all the information in one go.
- When that doesn't work, it will throw a NoSuchElementException. You can catch that exception and throw a BadFileException inside the catch.
- Otherwise, continue: A valid file has to start with |-- and has to end with with --| (both have 3 characters and no spaces). If any of these isn't present, or if the file has less than 6 characters (main reason: to avoid considering |--| or |---| as valid), you should throw a BadFileException with the message: "The file doesn't have correct beginning or end"
- If none of the previous checks trigger, the file is considered valid. Remove the beginning and end (the 6 characters) and split the remaining characters with the separator --- (3 hyphenes, no spaces, use the split method). The resulting array of Strings will be the array having the names. With the names obtained, you should close the input file.
- If a BadFileException or FileNotFoundException occurs, you shouldn't catch it, let it propagate. You must make sure that the input file is closed regardless of whether an exception is thrown or not.
Hint: There's a keyword that can be used in combination with a try/catch to achieve this behavior.
o Make sure to store the array of String outside of the previous block of code so it can be accessed later. If it's a local variable inside a try block, it won't be able to be accessed after it ends. Declare the array outside the try and set it to null initially.
o For the second part, we will use a helper method to take the attendance. o Make Scanner from System.in and a PrintWriter for the output file.
You won't use them on this function, instead, you will pass them to a
helper function that will be described after this one. o For each name, call the helper method described below (takes the name,
the Scanner for the console input, and the PrintWriter). You should
catch each of the two possible exceptions it can throw and print to console a message if that happens (do nothing if the method call executes successfully) and then continue to the next name.
- If the call results in an InvalidNameFormatException, print to console the following: "Skipping [name] because of an invalid name format: [exception message]" (no brackets)
- If the call results in an InvalidAttendanceInformationException, print to console the following: "Skipping [name] because of an invalid attendance information: [exception message]" (no brackets)
For each of them, the exception message is the Exception's getMessage() value. The name is the current name being processed.
o Because you will catch all the exceptions we will test (there could be unchecked exceptions that we won't test), your try/catch (with double catch!) should be inside your loop.
o After your loop completes, close the scanner for the console input and close the PrintWriter. That's the end of this function.
Example output is provided for different scenarios
private static void processStudentAttendance(String name, Scanner consoleScanner, PrintWriter printWriter)
o NOTE: For all exceptions, before throwing it, put a - (hyphen) in the output file in its own line with the PrintWriter's newline - NOT THE System.out!!! - before throwing the exception (this will happen in 4 scenarios, so this note is to avoid the 4x repetition)
o The first thing we will do is a bunch of checks in the name. If any of these fails, an exception will be thrown and propagated.
- If the name isn't "uppercase only" (String must match with its toUpperCase()), throw an InvalidNameFormatException with the message "The name isn't uppercase only"
- Otherwise, we character by character, and perform these checks in the following order:
- If the character is a digit, throw an InvalidNameFormatException with the message "The name has a digit"
- If the character is a pipe character (the |), throw an InvalidNameFormatException with the message "The name has a pipe character"
o If those checks pass, print "[name]: " to console and await for user input. Use nextLine.
If the returned string is empty (the user just hit "enter" immediately), throw an InvalidAttendanceInformationException with the message "Attendance information missing"
- If the returned string is not an A (for absent) or P (for present), throw an InvalidAttendanceInformationException with the message "Attendance information is not P or A"
- Otherwise, pass the obtained string directly to the PrintWriter. Use it's println method to print a line with just the letter to the file.
public static void main(String[] args) o Make AttendanceTaker using the first two console arguments
(guaranteed to exist, no need for checks) and call its takeAttendance method.
Example 1: File myInput.txt: (an empty file) <- NOT text: a file with no bytes.
> java AttendanceTaker myInput.txt myOutput.txt
Result: Your program should terminate abruptly will a BadFileException thrown from the Scanner's nextLine in takeAttendance (and not caught in either takeAttendance or main). The exception's message should be "The input file was empty" as the file is empty. myOutput.txt should NEVER be created, a Scanner for System.in should NEVER be created, and a PrintWriter for myOutput.txt should NEVER be created. The Scanner for myInput.txt should be closed.
Example 4: File myInput.txt: |--NAME---NAME2---name---MYNAME---NA|ME---MYNAMEAGAIN--|
> java AttendanceTaker myInput.txt myOutput.txt Console I/O. User input in bold NAME: P Skipping NAME2 because of an invalid name format: The name has a digit Skipping name because of an invalid name format: The name isn't uppercase only MYNAME: A
Skipping NA|ME because of an invalid name format: The name has a pipe character MYNAMEAGAIN: [USER HITS ENTER WITHOUT A CHARACTER]
Skipping MYNAMEAGAIN because of an invalid attendance information: Attendance information missing
Expected output file: myOutput.txt
P - - A - -
Result: Your program should terminate successfully with the shown console I/O and correct output in myOutput.txt. The file myOutput.txt will be created or overwriten (it will have 6 lines or 7 with the last line being an empty line). Both Scanners and the PrintWriter should be closed.
To prevent trivialization of the assignment, you are only allowed to import the following classes. You are not allowed to import any other classes or packages.
- java.io.File
- java.io.FileNotFoundException
- java.io.PrintWriter
- java.util.NoSuchElementException
- java.util.Scanner