/** This class (and specifically its test() method) is for the purpose of ** testing the BucketOfRecords class by creating an instance of that class ** and by exercising its various methods. ** ** @author R. McCloskey ** @version November 2007 */ import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class BucketOfRecordsTester { BufferedReader keyBoard; // source of input data boolean echo; // true if input should be echoed BucketOfRecords buck; private BucketOfRecordsTester(BufferedReader br, boolean echoInput) { keyBoard = br; echo = echoInput; } /** Carries out an interactive session with a user, first asking ** the user to specify a bucket size and then repeatedly ** inviting her/him to choose an operation to be applied to a ** BucketOfRecords object (initially containing no records) of ** that size. */ private void test() throws IOException { System.out.print("Enter size of bucket to create:"); int buckSize = Integer.parseInt(readAndEcho(echo)); buck = new BucketOfRecords(buckSize); System.out.println("Bucket of size " + buckSize + " has been created."); String menu = "\n" + "(0) exit program " + "(4) delete record\n" + "(1) display entire bucket " + "(5) replace record\n" + "(2) retrieve/display one record " + "(6) display duplicate bucket\n" + "(3) insert record\n" + ">"; int menuChoice; boolean finished = false; while (!finished) { menuChoice = getNumericResponse(menu); if (menuChoice == 0) { finished = true; } else if (menuChoice == 1) { displayRecordsInBucket(buck); } else if (menuChoice == 2) { retrieveOneRecord(buck); } else if (menuChoice == 3) { insertOneRecord(buck); } else if (menuChoice == 4) { deleteOneRecord(buck); } else if (menuChoice == 5) { replaceOneRecord(buck); } else if (menuChoice == 6) { BucketOfRecords duplicateBucket = new BucketOfRecords(buck.imageOf()); displayRecordsInBucket(duplicateBucket); } else { // menuChoice out of bounds System.out.print("ERROR: Your choice must be in the range 0..6"); } } System.out.println("Goodbye..."); } /** Displays the prompt provided (via the argument) and returns the ** user's numeric (integer) response. (If the user enters a string ** that does not correspond to an int, the prompt is displayed ** again. This is repeated until the user enters a valid string.) */ private int getNumericResponse(String prompt) throws IOException { int result = -1; boolean done = false; while (!done) { done = true; System.out.print(prompt); try { result = Integer.parseInt(readAndEcho(echo)); } catch (NumberFormatException e) { System.out.print("Illegal non-numeric response; try again."); done = false; } } return result; } /** Prompts user to enter the position of a record within the bucket ** provided (via the argument) and displays that record. */ private void retrieveOneRecord(BucketOfRecords b) throws IOException { int recLoc; recLoc = getNumericResponse(" Enter position of record to retrieve: "); if (inRange(recLoc, 0, b.numRecords()-1)) { System.out.println(new String(b.getRecord(recLoc))); } } private void insertOneRecord(BucketOfRecords b) throws IOException { int recLoc = getNumericResponse(" Enter position at which to insert: "); if (inRange(recLoc, 0, b.numRecords())) { System.out.print(" Enter record to insert: "); String recStr = readAndEcho(echo); byte[] recStrAsByteAry = recStr.getBytes(); if (b.enoughRoomToInsert(recStrAsByteAry)) { b.insertRecord(recLoc, recStrAsByteAry); } else { System.out.print("Cannot insert; insufficient room"); } } } private void deleteOneRecord(BucketOfRecords b) throws IOException { int recLoc; recLoc = getNumericResponse(" Enter position of record to delete: "); if (inRange(recLoc, 0, b.numRecords()-1)) { b.deleteRecord(recLoc); } } private void replaceOneRecord(BucketOfRecords b) throws IOException { int recLoc = getNumericResponse(" Enter position of record to replace:"); if (inRange(recLoc, 0, b.numRecords()-1)) { System.out.print(" Enter replacement record: "); String recStr = readAndEcho(echo); byte[] recStrAsByteAry = recStr.getBytes(); if (b.enoughRoomToReplace(recLoc, recStrAsByteAry)) { b.replaceRecord(recLoc, recStrAsByteAry); } else { System.out.print("Cannot replace; insufficient room"); } } } /**** u t i l i t i e s ****/ /** Displays, one per line, all the records in the given bucket */ private void displayRecordsInBucket(BucketOfRecords b) { for (int i=0; i != b.numRecords(); i++) { System.out.println("record " + i + ":" + new String(b.getRecord(i))); } } /** Reports whether or not the value of the first argument is ** within the range defined by the second and third arguments. ** If not, a warning message is written to System.out. */ private static boolean inRange(int val, int lowBound, int highBound) { boolean result; if (lowBound <= val && val <= highBound) { result = true; } else { System.out.println("ERROR: response must be in range " + lowBound + ".." + highBound); result = false; } return result; } /** Reads a line of text from keyBoard and returns it. ** If the value of the argument is true, the line of text is ** also written to System.out (for the purpose of having the ** input data be displayed in case it originates from a source ** other than the actual keyboard). */ private String readAndEcho(boolean echo) throws IOException { String result = keyBoard.readLine(); if (echo) { System.out.println(result); } return result; } public static void main(String[] args) throws IOException { BufferedReader input; boolean echo; /* If there is a command line argument, interpret it to be the ** name of a file containing user input */ if (args.length > 0) { input = new BufferedReader(new FileReader(args[0])); echo = true; } else { input = new BufferedReader(new InputStreamReader(System.in)); echo = false; } new BucketOfRecordsTester(input, echo).test(); } }