Project: Glossary (In JAVA) Objectives Familiarity with designing and coding a r
ID: 3704505 • Letter: P
Question
Project: Glossary (In JAVA)
Objectives
Familiarity with designing and coding a realistic component-based application program without being provided a skeleton solution.
Note that in your solution you can only use components from the components package and components from the standard Java libraries that have been used before in lectures/labs/projects (e.g., String). You should not use other components from any other libraries that have not been used in CSE 2221.
The Problem
Your customer, Cy Burnett, heads a major publisher of textbooks who is migrating toward on-line access. Cy wants a relatively easy-to-maintain glossary facility. (A glossary is a list of difficult or specialized words, or terms, with their definitions, that is usually near the end of a book.) His initial requirements are as follows:
The output shall be a group of HTML files. There shall be a top-level index which merely lists each term in the glossary, and separate pages for each of the terms with their definitions. Clicking on a term in the index shall take you to the page for that term and its associated definition. Moreover, clicking on any term in the glossary that happens to appear in a definition shall take you to the page for that term and its associated definition.
Every term shall consist of a single "word" (i.e., a term contains no whitespace characters).
The terms shall appear in the glossary index in alphabetical order. In each term's page, that term shall appear in red boldface italics just before its definition.
The entire glossary shall be generated in batch fashion by your program from an input file. This input shall consist of a single term on the first line, its definition on the next one or more lines (terminated by an empty line), another term on the next line, its definition on the next one or more lines (terminated by an empty line), etc. The input shall continue in this fashion through the definition of the last term, which shall end with its terminating empty line. The program shall not check for invalid input; the customer shall be responsible for providing input that meets the stated conditions.
The program shall ask the user for the name of the input file and for the name of a folder where all the output files will be saved. The output folder must already exist and will not be created by the program. The top-level index shall be named index.html and the page for each term shall be named term.htmlwhere term is the actual term.
In the preceding item, "name of the input file" and "name of a folder" are to be understood as follows. Each includes the notion of a path to the terminal name. The path may either be relative to a current folder or be absolute from the top of the file system. It would be bad form for the program to insert an implied sub-path or folder prior to or after what the user supplies as input. Similarly, it would be bad form for the program to supply an implied filename extension such as ".txt" after what the user supplies as input. Therefore, the program shall respect the user input as being the complete relative or absolute path as the name of the input file, or the name of a folder, and will not augment the given path in any way, e.g., it will not supply its own filename extension. For example, a reasonable user response for the name of the input file could directly result in the String value "data/terms.txt"; similarly, a reasonable user response for the name of a folder could directly result in the String value "data".
These are the stated requirements for your program. If you have questions of clarification or need additional details, Cy is willing to answer them if you ask your instructor to contact him.
Setup
You're on your own! There are no other setup instructions; this is the "blank sheet of paper" project that you've all been waiting for!
Method
When you are satisfied that your program works, select your Eclipse project (not just some of the files, but the whole project), create a zip archive of it, and submit the zip archive to the Carmen dropbox for this project, as described in Submitting a Project.
Your grade will depend not merely on whether the final program meets the customer's initial requirements, of course, but also on the general software quality factors we've been discussing for the past three months: understandability, precision, appropriate use of existing software components, maintainability, adherence to coding standards, and so forth.
A sample input file is available at:
A sample of the corresponding program output is available at:
You should not assume that your glossary must look like this one, which is merely a sample of what the output might be. This sample is just something your requirements analyst and the customer cobbled together by hand for a small glossary, to serve as a possible prototype for the final program output. You should feel free to improve on it.
Explanation / Answer
Glossary.java
import components.map.Map;
import components.map.Map1L;
import components.queue.Queue;
import components.queue.Queue1L;
import components.set.Set;
import components.set.Set1L;
import components.simplereader.SimpleReader;
import components.simplereader.SimpleReader1L;
import components.simplewriter.SimpleWriter;
import components.simplewriter.SimpleWriter1L;
public final class Glossary {
/**
* Private constructor so this utility class cannot be instantiated.
*/
private Glossary() {
}
public static Queue<String> getTermsAndDef(SimpleReader input,
Map<String, String> termAndDef) {
Queue<String> terms = new Queue1L<>();
/* While loop to go through entire input. */
while (!input.atEOS()) {
/* Gets the next "term". */
String term = input.nextLine();
StringBuilder definition = new StringBuilder();
boolean nextTerm = false;
/* While loop to get entire definition of corresponding term. */
while (!nextTerm) {
String line = input.nextLine();
if (!line.equals("")) {
definition.append(line + " ");
} else {
/* Removes trailing space at end of definition. */
definition.deleteCharAt(definition.length() - 1);
nextTerm = true;
}
}
/*
* Adds the term and its corresponding definition to {@code
* termAndDef}, as well as to {@code terms}.
*/
termAndDef.add(term, definition.toString());
terms.enqueue(term);
}
/* Sorts {@code terms}. */
terms.sort(String.CASE_INSENSITIVE_ORDER);
return terms;
}
public static void generateTitlePage(SimpleWriter feedFile,
Queue<String> terms) {
feedFile.println("<html>");
feedFile.println(" <head>");
feedFile.println(" <title>Glossary</title>");
feedFile.println(" </head>");
feedFile.println(" <body>");
feedFile.println(" <h2>Glossary</h2>");
feedFile.println(" <hr>");
feedFile.println(" <h3>Index</h3>");
feedFile.println(" <ul>");
/* For loop to add a hyperlink for each term's page. */
for (int i = 0; i < terms.length(); i++) {
feedFile.println(" <li>");
feedFile.println(" <a href="" + terms.front()
+ ".html">" + terms.front() + "</a>");
feedFile.println(" </li>");
terms.rotate(1);
}
feedFile.println(" </ul>");
feedFile.println(" </body>");
feedFile.println("</html>");
}
public static void generateTermPage(SimpleWriter feedFile, String term,
Map<String, String> termsAndDef) {
feedFile.println("<html>");
feedFile.println(" <head>");
feedFile.println(" <title>" + term + "</title>");
feedFile.println(" </head>");
feedFile.println(" <body>");
feedFile.println("<h2><b><i><font color="red">" + term
+ "</font></i></b></h2>");
/*
* Prints to {@code feedFile} the term and its corresponding definition,
* formatted in html style.
*/
feedFile.println(
"<blockquote>" + termsAndDef.value(term) + "</blockquote>");
feedFile.println(" <hr>");
feedFile.println("<p>Return to <a href="index.html">index</a>.</p>");
feedFile.println(" </body>");
feedFile.println("</html>");
}
public static void updateDefinition(Queue<String> terms,
Map<String, String> termsAndDef) {
/* Set of separators. */
Set<Character> separators = new Set1L<>();
separators.add(',');
separators.add(' ');
separators.add(' ');
separators.add(';');
separators.add('.');
/* Nested for loops to check for any definitions that contain a term. */
for (int i = 0; i < terms.length(); i++) {
String term = terms.front();
for (int q = 0; q < terms.length(); q++) {
String curTerm = terms.front();
String definition = termsAndDef.value(term);
int position = 0;
while (position < definition.length()) {
String curWord = nextWordOrSeparator(definition, position,
separators);
/*
* If a term is found, update definition to contain the html
* hyperlinked equivalent, linking to its respective page.
*/
if (curWord.equals(curTerm)) {
definition = definition.substring(0, position)
+ "<a href="" + curWord + ".html">" + curWord
+ "</a>"
+ definition.substring(
position + curWord.length(),
definition.length());
}
position += curWord.length();
}
termsAndDef.replaceValue(term, definition);
terms.rotate(1);
}
terms.rotate(1);
}
}
public static String nextWordOrSeparator(String text, int position,
Set<Character> separators) {
assert text != null : "Violation of: text is not null";
assert separators != null : "Violation of: separators is not null";
assert 0 <= position : "Violation of: 0 <= position";
assert position < text.length() : "Violation of: position < |text|";
StringBuilder returnText = new StringBuilder();
if (separators.contains(text.charAt(position))) {
for (int i = position; i < text.length()
&& separators.contains(text.charAt(i)); i++) {
returnText.append(text.charAt(i));
}
} else {
for (int i = position; i < text.length()
&& !separators.contains(text.charAt(i)); i++) {
returnText.append(text.charAt(i));
}
}
return returnText.toString();
}
/**
* Main method.
*
* @param args
* the command line arguments
*/
public static void main(String[] args) {
SimpleReader in = new SimpleReader1L();
SimpleWriter out = new SimpleWriter1L();
/*
* Gets the location of the input file and the desired location for the
* output.
*/
out.println("Enter input file location: ");
String inputFile = in.nextLine();
out.println("Enter folding to save output files: ");
String outputLoc = in.nextLine();
SimpleReader input = new SimpleReader1L(inputFile);
Map<String, String> termsAndDef = new Map1L<>();
Queue<String> terms = getTermsAndDef(input, termsAndDef);
updateDefinition(terms, termsAndDef);
/* Generates title page. */
SimpleWriter output = new SimpleWriter1L(outputLoc + "\index.html");
generateTitlePage(output, terms);
/* Generates term page for each term. */
int length = terms.length();
for (int i = 0; i < length; i++) {
String term = terms.dequeue();
output = new SimpleWriter1L(outputLoc + "\" + term + ".html");
generateTermPage(output, term, termsAndDef);
}
in.close();
out.close();
input.close();
output.close();
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.