Project 2
For the Analyzer
- Use the command
$ ant build_analyzer
to compile and build the class. - Use the command
$ ant run_tests_analyzer
to test the class. - Use the script
$ ./runAnalyzer.sh YourFilePath
to run the class.
For the Web Application
- Use the command
$ ant tcup
to start tomcat. - Web address: http://localhost:8080/java112/
Project Overview
There are two parts to Project 2.
Part 1: Analyzer: Extends the Project 1 Analyzer with more file analyzers and a project properties file.
Part 2: Web Application: Start to create a web application by creating Servlets with server-side java web programming.
Special note on project code
Projects must rely on coded solutions that have been covered in the class material, unless otherwise specified.
If the coded solution uses concepts not covered in class, you are required to do a code review. This review must include a detailed explanation of your coding choices and rationale for employing a solution beyond the scope of the class material.
Project Directory Structure
projects/
|-- config/
|-- dist/
|-- docs/
|-- lib/
|-- output/
|-- public_html/
| |-- images/
|-- src/
|-- java112/
|-- analyzer/
|-- labs1/
|-- labs2/
|-- project2/
|-- utilities/
This structure will hold all projects for the course. Description of each directory:
- The projects directory can be anywhere that you would like. It might be easier if you put it at the top level of your C:\ drive. This document will assume that it is placed there.
- The classes directory will hold all of your .class files in their correct package layout.
- The config directory will hold all of your project's .properties files.
- The data directory will be used in future projects.
- The docs directory will contain the documentation for the application in javadoc format.
- The output directory will contain the output generated by your application. Your application will need to get the location of the output directory from the application properties file.
- The public_html directory will contain all the static files for your web application like .html files and all your JSP files.
- The images directory will contain all your web applications images.
- The src directory will contain all of your .java source code files in their correct package layout.
- The analyzer directory will contain the source code that is only part of analyzer project.
- The labsx directories will hold the labs for their respective modules.
- The project2 directory will contain the source code that is only part of project 2. Reminder: only servlet code will be placed in the project2 directory. Classes for the Analyzer application should still be placed in the analyzer directory.
- The utilities directory will contain utility classes and interfaces that will be used in more than one application.
Part 1: Analyzer – Continued!
File Size
You must be prepared to test your application with a file that is bigger than 20MB with more than 4 million tokens (bigFile.txt). Your application must process this file properly.
Run Script
We need to load a properties file when we run the Analyzer application with the runanalyzer.sh
script. To do this, we need to modify the run script to take another parameter.
- Modify your
runanalyzer.sh
script to match below:
#! /bin/sh
java -classpath lib/analyzer.jar:config java112.analyzer.Driver $1 /analyzer.properties
TokenAnalyzer Interface
We also need to modify the TokenAnalyzer
interface by deleting the second parameter in the generateOutputFile
method declaration.
- Modify your
generateOutputFile
method to match below:
void generateOutputFile(String inputFilePath);
PropertiesLoader Interface
Your project will have a new interface, located in the new package java112.utilities
. This package will be contain things that will be used more than once in part of your projects.
Once you completed the "Default Interface Methods Practice" lab, you will have the PropertiesLoader.java in your java112.utilities
package. Open it; notice the new default
keyword?
package java112.utilities;
import java.io.*;
import java.util.*;
/**
* @author Eric Knapp
*
*/
public interface PropertiesLoader{
default Properties loadProperties(String propertiesFilePath) throws Exception {
Properties properties = new Properties();
try {
properties.load(this.getClass().getResourceAsStream(propertiesFilePath));
} catch (IOException ioException) {
ioException.printStackTrace();
throw ioException;
} catch (Exception exception) {
exception.printStackTrace();
throw exception;
}
return properties;
}
}
Analyzer Properties
Your project has too many hard-coded strings embedded in its code. We are now going to get rid of all of them! We will use the Properties class that comes with the collections framework. Here are the steps:
- Create a file named analyzer.properties and place it in the config directory.
- Add properties entries for at least the following, you can add more when you need them. You must use the following properties exactly as they are shown. You can’t change the names of the properties, the value can be different.
application.name=
author=
author.email.address=
output.directory=output/
output.file.summary=summary.txt
output.file.distinct=distinct_tokens.txt
output.file.largest.words=largest_words.txt
output.file.distinct.counts=distinct_counts.txt
largest.words.minimum.length=14
Constructors
Each of our analyzer classes needs a new constructor to take in a Properties object.
-
First, make sure each Analyzer class has an empty Constructor. By empty, we mean they have no parameters.
/** * Empty constructor example */ public FileSummaryAnalyzer() { // There may be code here for some Analyzers. // For example, to instantiate a collection instance variable. }
-
Add a Constructor with one parameter that is a Properties reference. Assign the parameter reference to the Properties instance variable.
/** * Constructor with one Properties parameter */ public FileSummaryAnalyzer(Properties properties) { this();// call the empty/no-arg constructor this.properties = properties; }
FileAnalysis
Modifications for the new Properties
We need to change the FileAnalysis class so we can load the Properties and send them to our analyzer classes. Here are the overall list of the changes.
-
We have two arguments coming into our program now. The file to be analyzed and our new Properties file.
- Change your constant for the valid number of arguments from 1 to 2.
-
The FileAnalysis class needs access to the PropertiesLoader interface.
- Implement the PropertiesLoader interface in the FileAnalysis class. The interface should have been added in the Default Interfaces Lab.
-
We have to load our new Properties file. We'll do this in the
analyze()
method.- Modify the
analyze()
method to call theloadProperties()
method. - Send the new second argument from the command line to the method.
- The returned Properties object should be passed to the method where the analyzers are created.
- Modify the
Modifications to Make Our Program more Flexible and Manageable
We don't want to have a separate instance variable for every analyzer class. We want the program to be flexible. What if someday I need 100 different analyzer classes, imagine how having 100 instance variables for each could become very hard to manage!
Here's our solution.
-
We'll use a List to store all our analyzer classes in!
- Create an instance variable for a List of TokenAnalyzer instances. Think carefully about where the instance variable should be declared verses where to instantiate it.
-
We no longer need the individual instance variables for FileSummaryAnalyzer and the DistinctTokensAnalyzer.
- Delete the two instance variables for the FileSummaryAnalyzer and the DistinctTokensAnalyzer.
-
When we create our analyzers, we need to add them to this list. They also need the properties object.
- Add each TokenAnalyzer class to the new list.
-
Call the new constructor and pass the Properties parameter.
Example:
analyzers.add(new FileSummaryAnalyzer(properties));
-
Now that our analyzers are stored in a List, we can loop through them. Very handy!
- Modify your code to use enhanced for loops to call the
processToken()
andgenerateOutputFile()
methods.
- Modify your code to use enhanced for loops to call the
Project 1 Analyzers
We need to make a few updates to the FileSummaryAnalyzer and the DistinctTokensAnalyzer.
-
Since we are using Properties instead of hard-coded values, we need an instance variable to store the new Properties object.
- Add an instance variable for a Properties object
private Properties properties;
-
We changed the method signature of
generateOutputFile()
method in the TokenAnalyzer, we need our classes to match this signature.- Change the
generateOutputFile()
method signature to match the interface.
- Change the
-
Instead of hard-coding values in the
generateOutputFile()
method, use the Properties object.- Update the
generateOutputFile()
method to use the Properties object for its needed information.
- Update the
LargestTokensAnalyzer
LargestTokensAnalyzer Class Purpose
-
The purpose of the LargestTokensAnalyzer class is to find unique tokens that have a length greater than or equal to a specified number.
-
What does it know? The Properties object, the largest tokens, the minimum token length.
-
What does it do? Gets the minimum token length from the Properties object. Finds and stores all tokens that are greater or equal to that length. It outputs each token on it's own line.
LargestTokensAnalyzer Class Details
- The name of the class must be LargestTokensAnalyzer.
-
Create the following instance variables and get method. No other instance variables are allowed.
private Properties properties; private Set<String> largestTokens; private int minimumTokenLength; public Set<String> getLargestTokens() { return largestTokens; }
-
No setter methods are allowed.
- Only access the property for the minimum length just once. Do this in the constructor, not the processToken method.
DistinctTokenCountsAnalyzer
DistinctTokenCountsAnalyzer Class Purpose
-
The purpose of the DistinctTokenCountsAnalyzer class is to count the number of unique tokens.
-
What does it know? The Properties object and the distinct tokens count.
-
What does it do? Gets the Properties object. Finds and stores all unique tokens while counting how many time they occur. It outputs a row for each unique token followed by the number of times that token occurred in the file.
DistinctTokenCountsAnalyzer Class Details
- The format of the output is as follows: [unique token] [tab] [count]
- To create a tab, use the
\t
escape character. -
For example, the java code will look like the following:
and\t160 friendly\t7 what\t8
-
Which, will output this:
and 160 friendly 7 what 8
-
The class will have the following instance variables and get method. No other instance variables are allowed.
private Properties properties; private Map<String, Integer> distinctTokenCounts; public Map<String, Integer> getDistinctTokenCounts() { return distinctTokenCounts; }
- Don’t create any set methods.
Part 2: Your Web Application
For this part of the project you will be creating a website, that run serer-side Java code! Your website will contain a home page, a First Servlet page, and a Properties Servlet page. You'll be add more pages in Project 3 and 4.
Ant commands for building and deploying the web application
- To compile and build your application’s .war file:
$ ant build_web
- To compile, build, and deploy your web app to tomcat just use this. It will be one you want to use most of the time.
$ ant deploy
- Finally, since we will be deploying so often, the deploy target is set up as the default. That means you can do everything with just this:
$ ant
Site Design
The first step is to pick a design! In this course, you're going to practice a necessary skill; using someone else’s design.
- You must use a design in the form of a web design template.
- You may not use your own design!
- For project 2, only your home page will need to use the design.
- Below are some templates that you could use that would work well for the course. You can also choose something from W3Schools Templates if you'd like more options.
Home Page
Your project will need a home page that will contain links to all the other pages in your website.
- It must be named index.jsp.
- It must be located in the
projects/public_html
directory. - It must be clearly identified as your home page for this course.
- It must have links to all the other parts of the project.
- It will be used for the remaining projects of the course so you should identify the project 2 links as part of project 2.
First Servlet
The purpose of this page is to practice creating a Servlet. It will simply output HTML information.
- Create a Servlet named First112Servlet and place it in the java112.project2 package.
- This Servlet will have these elements:
- It will generate HTML output that contains your name and the course you are taking.
- The generated output will contain an image tag. Find an appropriate image somewhere and put it into the
projects/public_html/images
directory. The correct way to create the tag will be discussed in class. - The generated output will contain a link back to the home page.
Project Properties File
The web application will have it's own set of properties separate from the analyzer application.
- Create a file named project2.properties and place it into the projects/config directory. This file will contain entries for the following:
- The name of the author of the project
- The email address of the author
- The course title
- The course meeting days and times
- The name of your instructor
- A multi-line description of the project (meaning the description continues over multiple lines in your properties file)
Properties Servlet
The purpose of this page is to practice creating a Servlet that uses the Properties class to output a list of properties.
- Create a Servlet named PropertiesServlet and place it in the java112.project2 package.
-
This Servlet will have these elements:
- The servlet will implement the PropertiesLoader.
- The servlet will have an instance variable of type Properties from the java.util package.
- The servlet will implement the
init()
method and load the project properties file into the Properties instance variable using theloadProperties()
method. - The servlet will output some static HTML that identifies this servlet.
- The servlet will output an HTML table (use a loop) with the contents of the properties file. The contents of the table must come from the project properties file.
- The generated output will contain a link back to the home page.
Rubric
All of the following must be satisfied to achieve a "Met" status
Criteria | Met Status |
---|---|
Screenshots |
|
Debugging & Problem-Solving | Code is free from errors, and all provided tests pass without any issues. |
Code Quality | Code is exceptionally clean, efficient, and maintainable. Follows best practices, coding standards, and programming principles. |
Properties | The properties have been used in the application in place of hard-coded values. |
Constructors | Each class has an empty constructor. |
Git and GitHub | You have consistently uses Git and GitHub for version control. Commits are meaningful and atomic. At least 25 commits messages have been made during Unit 2. |
Java IO | Correct Java IO classes are used to read and write data to files. |
Exception Handling | Exception handling is used correctly throughout the application, including providing user-friendly error messages. Try-with-resources is implemented correctly. |
Collections | The appropriate concrete implementation of the Collections interface is used, such as Sets and Lists. |
Functionality | The FileSummaryAnalyzer and DistinctTokensAnalyzer still produce the correct output.
The LargestTokensAnalyzer and DistinctTokensAnalyzer produce the correct output with the BigFile.
|
Code Documentation | All classes, methods, instance variables, and constructors are thoroughly documented with accurate descriptions and proper JavaDoc comments. |
Web App |
|
External Sources | External sources (websites, classmates, AI tools, etc), if utilized, are referenced and documented within the code as comments. |
Reflection | Issue created correctly with thoughtful answers to the reflection questions. |