Source code for Admin.java

package PhoneApp;

import PhoneApp.Data.*;
import PhoneApp.XML.*;

/**
 * Provides a simple admin interface for maintaining the
 * phonebook database.
 *
 * @version $Date: 2001/06/25 $
 * @author  Steve Franklin
 * @since   jdk 1.3.1
 */

class Admin {

  public Admin() {
    book = new Phonebook();
  }

 /**
  * Allows users to select a suite of administration options. After
  * execution of each task, the user can choose another administration
  * task.
  */
  public void run() {
    boolean continueRunning = true;
    while(continueRunning) {
      int option = getOption();
      // Depending on which option the user selects, choose
      // the appropriate data management activity.
      switch (option) {
        case 0: continueRunning = false; break;
        case 1: runAddEntry(); break;
        case 2: runAddBatch(); break;
        case 3: reportAllEntries(); break;
        case 4: runDelete(); break; // Added to include deletion from database
        case 5: runQuery(); break;  // Added to include query against database
        case 6: runUpdate(); break; // Added to allow update to existing records

        default: System.out.println("Unrecognized option. Try again.");
      }
    }
    // Added - must free up resources allocated through database connection
    book.close();
  }

 /**
  * Allow for entry of individual phone entries. The
  * system will add a new entry for valid entries. Validation
  * very minimal and incomplete.
  */
  public void runAddEntry() {
    ConsoleReader console = new ConsoleReader();

    console.sendPrompt("Enter new phone entry...");
    
    String firstName = console.getInput("First Name");
    String lastName = console.getInput("Last Name");
    String phoneNumber = console.getInput("Phone Number");
    int streetNumber = -1;
    try {
      streetNumber = Integer.parseInt(console.getInput("Street Number"));
    } catch (Exception e) {
      // parse of int failed
    }
    String street = console.getInput("Street");
    String apartmentNumber = console.getInput("Apartment");
    String postalCode = console.getInput("Postal Code");

    book.addEntry(firstName, lastName, phoneNumber,
                  street, streetNumber, apartmentNumber, postalCode);
  }


 /**
  * Accepts the name of an XML file containing the phone entries
  * to be added. Validation for the existance of the file does
  * not exist, and must be caught by the parser.
  */
  public void runAddBatch() {
    String defaultFile = "batchEntries.xml";
    ConsoleReader console = new ConsoleReader();

    console.sendPrompt("Enter new batch phone list...");
    String fileName = console.getInput("XML File Name [" + defaultFile + "]");
    if ( fileName.length() <= 0 ) {
      fileName = defaultFile;
    }

    // Retrieve the entries from the XML file
    XMLPhoneEntries entryList = new XMLPhoneEntries(fileName);

    // For each entry, extract the information and create a new phone entry
    // This should be improved to map XML to objects, but for simplicity we'll
    // go with the simpler approach.
    while (!entryList.empty() ) {
      String entryFields[] = (String[])entryList.pop();
      book.addEntry(entryFields[0], entryFields[1], entryFields[2], 
                    entryFields[3], Integer.parseInt(entryFields[4]), entryFields[5], entryFields[6]);
    }
  }
  
  // Added to allow deletion of records from the database.
  /**
   * Delete phonebook entries from the database
   */
  private void runDelete() {
    String selectedEntry = queryAndSelect("Entry to delete: ");

    if ( selectedEntry != null ) {
      boolean success = book.deleteEntry(selectedEntry);
      if ( success ) {
        System.out.println("Entry deleted.");
      }
    }
  }

  // Added to allow search for records in the database.
  /**
   * Query/report on phonebook entries in the database by
   * providing some filtering criteria
   */
  private void runQuery() {
    ConsoleReader console = new ConsoleReader();

    // Allow the user to pick the field that will be used for querying
    // the database (no multiple criteria supported in this code)
    String fieldName = getFieldName("Select field to query");

    if ( fieldName.length() > 0 ) {
      // For the specified field, allow the user to define the value to
      // look for (no wildcard matches supported)
      String fieldValue = console.getInput("Search for");
      String[] results = book.queryEntries(fieldName, fieldValue);

      // Print the results.
      System.out.println("");
      for (int i=0; i< results.length; i++) {
        System.out.println((i+1) + ") " + results[i]);
      }
    }

  }

  // Added to allow update of records from the database.
  /**
   * Update phonebook entries in the database
   */
  private void runUpdate() {
    ConsoleReader console = new ConsoleReader();
    String[] results = book.getEntryReport(Phonebook.DETAILED_REPORT);

    // Allow the user to pick the record which is to be updated.
    System.out.println("Available records:");
    String key = queryAndSelect("Record to Update [1-" + results.length + "]");

    if ( key.length() > 0 ) {
      // For the specified record, find the field to be updated and
      // accept user input for the new value.
      String fieldName = getFieldName("Select field to update");
      String fieldValue = console.getInput("New Value");
      book.updateEntry(key,fieldName, fieldValue);
    }

  }
  


  
  // Utility/helper functions below...

  // Added to allow for report of database contents.
  /**
   * Print a summary of all PhonebookEntry records in the database.
   * Allow for terse (keys only) or detailed (full entry summary) reports
   */
  private String queryAndSelect(String prompt) {

    // We really only care about the keys (the phone numbers), but
    // we will also get a report for the full version which is nicer
    // to print out to the user. The selected record is used to determine
    // the phonebook entry that is to be selected.
    String[] resultKeys = book.getEntryReport(Phonebook.KEY_REPORT);
    String[] results = book.getEntryReport(Phonebook.DETAILED_REPORT);
    ConsoleReader console = new ConsoleReader();

    if ( prompt.length() > 0 ) {
      System.out.println(prompt);
    }
    
    for (int i=0; i< results.length; i++) {
      console.sendPrompt((i+1) + ") " + results[i]);
    }

    int option = console.getUserNumber("","Entry");
    
    if (option > 0 && option <= results.length) {
      return resultKeys[option-1];
    } else {
      console.sendPrompt("Problem selecting entry " + option);
      return null;
    }
  }
  
  private void reportAllEntries() {
    String[] results = book.getEntryReport(Phonebook.DETAILED_REPORT);

    for (int i=0; i< results.length; i++) {
      System.out.println((i+1) + ") " + results[i]);
    }
  }
  
  // Added to allow user to specify which field to query/update
  /**
   * Allow user to specify which field to query/update.
   */
  private String getFieldName(String prompt) {

    ConsoleReader console = new ConsoleReader();
    console.sendPrompt(prompt);
    String[] queryFields = book.getQueryableFields();
    for (int i=0; i< queryFields.length; i++) {
      if ( i != 0 ) { System.out.print(",  "); }
      console.sendText((i+1) + ") " + queryFields[i]);
    }
    System.out.println("");
    
    int option = console.getUserNumber("","Choice");

    if (option > 0 && option <= queryFields.length) {
      return queryFields[option-1];
    } else {
      console.sendPrompt("Problem selecting entry " + option);
      return null;
    }
  }  

  /**
   * Read input from the console, and retrieve an integer value
   * based on user input.
   */
  private int getOption() {
    ConsoleReader console = new ConsoleReader();
    String prompt = "\n0: Quit,  1: Add,  2: Upload,  3: Report,  4: Delete,  5: Query,  6: Update";
    int optionNumber = console.getUserNumber(prompt, "Choice");
    return optionNumber;
  }

 /**
  * Runs the application. Accepts a single argument with the name
  * of an XML file containing the new phone entries.
  */
  public static void main (String[] args) {
    Admin app = new Admin();
    app.run();
  }

  // Added: Persistent data is accessed through the Phonebook
 /**
  * Provides the interface to the phone book, collecting
  * all phone entries in a persistent store.
  */
  Phonebook book = null;
}