001package com.alamedatechlab.googtest;
002
003import java.io.FileReader;
004import java.io.IOException;
005import java.util.InputMismatchException;
006import java.util.Scanner;
007
008/**
009 * NeedlesHaystackTest is a driver for the Google writing test sample "findNeedles()" method.
010 *
011 * @author Kelli Wiseth 2019 Revised the original Google findNeedles() method to accept an array of
012 *     words and a locally stored textfile. Added methods to let users choose the size of the array
013 *     (up to 5) and validate entries.
014 * @param console Scanner object that accepts input from user, such as number of words to search for
015 *     and the words themselves.
016 */
017public class NeedlesHaystackTest {
018
019  /**
020   * Verifies that the string entered at console is an integer between 1 and 5.
021   *
022   * @param validEntries Hard-coded array of allowable entries.
023   * @param valueToCheck String entered at console.
024   */
025  static boolean checkEntry(int[] validEntries, int valueToCheck) {
026    boolean test = false;
027    for (int element : validEntries) {
028      if (element == valueToCheck) {
029        test = true;
030      }
031    }
032    return test;
033  } // public boolean checkEntry method
034
035  /**
036   * Finds and counts the number of each specified word (needle) (if found) that exist in the
037   * specified file (haystack). Haystack is a plaintext file stored locally. Needles are up to 5
038   * words entered at prompts on the command line.
039   *
040   * @param haystack String object comprising the plaintext from text file.
041   * @param needles An array containing five String objects.
042   * @see <a
043   *     href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html">
044   *     java.lang.String</a>
045   */
046  public static void findNeedles(String haystack, String[] needles) {
047    int[] counter = new int[needles.length];
048    String[] words = haystack.toLowerCase().split("[ \"\'\t\n\b\f\r]", 0);
049    for (int i = 0; i < needles.length; i++) {
050      //  String[] words = haystack.toLowerCase().split("[ \"\'\t\n\b\f\r]", 0);
051      for (int j = 0; j < words.length; j++) {
052        if (words[j].compareTo(needles[i].toLowerCase()) == 0) {
053          counter[i]++;
054        }
055      }
056    }
057    for (int j = 0; j < needles.length; j++) {
058      System.out.println(needles[j] + ": " + counter[j]);
059    }
060  } // findNeedles method
061
062  /**
063   * Launches program and prompts user for three pieces of variable input: the number of words
064   * (needles) in total that user wants to find; the specific words; and the name of the local text
065   * file (haystack) to search through.
066   */
067  public static void main(String[] args) throws IOException, InputMismatchException {
068
069    int[] validEntries = {1, 2, 3, 4, 5};
070    String[] textValues = {"first", "second", "third", "fourth", "fifth"};
071    System.out.println("*******************************************************");
072    System.out.println("This console program accepts up to 5 words ('needles') to ");
073    System.out.println("find in the file ('haystack') you specify.");
074    System.out.println("*******************************************************");
075    System.out.print("How many words do you want to search for? (5 max) : ");
076    System.out.flush();
077
078    Scanner console = new Scanner(System.in);
079    try {
080
081      // int needleCount = validateInput(rawInput);
082      int needleCount = console.nextInt();
083      boolean goodEntry = checkEntry(validEntries, needleCount);
084      while (!goodEntry) {
085        System.out.print("Please enter a number from 1 to 5 only: ");
086        needleCount = console.nextInt();
087        goodEntry = checkEntry(validEntries, needleCount);
088      }
089      String[] inputWords = new String[needleCount];
090
091      for (int i = 0; i < inputWords.length; i++) {
092        System.out.print("Type the " + textValues[i] + " word you want to find in the haystack: ");
093        inputWords[i] = console.next();
094      }
095      String[] needles = inputWords;
096      System.out.print("What is the name of the file (haystack)? : ");
097      String inputFileName = console.next().trim();
098      FileReader reader = new FileReader(inputFileName);
099      Scanner in = new Scanner(reader);
100      StringBuilder haystackBldr = new StringBuilder();
101
102      while (in.hasNextLine()) {
103        String line = in.nextLine();
104        haystackBldr.append(line);
105      }
106
107      String haystack = haystackBldr.toString();
108
109      findNeedles(haystack, needles);
110      in.close();
111      console.close();
112    } catch (IOException exception) {
113      System.out.println("Haystack file missing or other file error." + exception.toString());
114    } catch (InputMismatchException e) {
115      System.out.println("Numeric data required." + e.toString());
116    }
117  } // main method closing brace
118} // public class NeedlesHaystackTest closing brace