PROGRAM 2



Clarifications

  • The command options are updated to reflect the required delimiter.
  • In TreeNode class there is a private instance field called worker, which is a List. Please do not rename this to workers or make any other modification to the TreeNode class. This update is provided here after this Piazza post.
  • The extra space in na me which was part of the CompanyHierarchyException exception message in getCoWorkers and getSupervisorChain methods have been updated. This is based on the following Piazza post
  • In getCoWorkers method do not include the employee you searched in your return list. Only include all other employees who are co workers.
  • addEmployee and replaceEmployee function specification have been updated to take into account the case where some other existing employee has the same id as the new employee that you are trying to add or replace. This is with reference to this Piazza post.
  • getEmployeeInJoiningDateRange function specification has been updated to take into account the case where parsing fails. This is with reference to this Piazza post.
  • j command in CompanyHierarchyMain is supposed to work on the range inclusively. This is reference to this Piazza post.
  • replaceEmployee function: you need not handle the case where the search employee's name and id do not match. You may assume that this combination will be tested correctly.
  • Whenever you are searching for any employee on the tree, you should search with both name and id. If only id matches and name doesn't match, then you need to thrown CompanyHierarchyException.
  • Based on requests, I have added few other sample outputs in the following new sample output file: sampleOutput1.txt
  • sampleOutput1.txt updated to fix issue with last command d.
  • getCoWorkers() can return an empty List or null. However, if you return null, make sure to handle properly on the CompanyHierarchyMain case properly.
  • There is no need to handle "Invalid Command". But if you have already handled it, no harm done either.
  • Discrepancy in output of command d - missing "hierarchy" keyword in sample outputs. Either outputs are acceptable and you will not lose any points in grading. This is reference to this Piazza post.
  • sampleInput.txt has been updated to correct the issue with Olivia's date of joining format. This is reference to this Piazza post.
  • contains method description updated to reflect that always you need to match with both ID and name. This is applicable to any kind of search on your CompanyHierarchyTree. This is reference to this Piazza post.

Overview

Goals

The goals of this assignment are to:

  • Code a class that implements a general tree.
  • Understand and implement recursive algorithm.
  • Gain experience using javadoc documentation to get information about a class.

Description

In this assignment you will be writing a Java program that creates and manipulates a Company reporting hierarchy tree. Every node in the tree represents an employy with some specific features, including name, employee ID, data of joining and title. Every edge in the tree represents supervisor-employee relationship. The main program will get input from file and send its output to the console.

Specifications

The Employee Class

An Employee class is provided for you (see Employee.java). The Employee class represents a single employee that keeps track of the name (as a String), id (as an int), date of joining (as a String) and title (as a String). The Employee class has the following constructor and methods:

Constructor Description
Employee(String name, int id, String dateOfJoining, String title) Constructs an Employee with the required details.
Method Description
String getName() Return the name of the employee.
int getId() Return the id of the employee
String getDateOfJoining() Return the date of joining of the employee
String getTitle() Return the title of the employee

You may not modify the Employee class.

The TreeNode Class

A TreeNode class is also provided for you (see TreeNode.java). The TreeNode class represents a single node in the company hierarchy tree. A node has the infomation of a employee (as a Employee) and also the infomation about the employee's supervisor as a parent node (as a TreeNode) and information about the employee's workers (other employees who report to current employee) as children nodes (as a List of TreeNodes). The TreeNode class has the following constructor and methods:

Constructor Description
TreeNode (Employee employee, TreeNode supervisorNode) Constructs a TreeNode with employee and supervisorNode.
Method Description
Employee getEmployee() Return the employee in this node
TreeNode getSupervisor() Return the reporting supervisor for the employee in this node
List<TreeNode> getWorkers() Return the worker list for the employee in this node
void addWorker(TreeNode workerNode) Add new worker to this employee
void updateSupervisor(TreeNode supervisorNode) Updates supervisor of an employee TreeNode
void updateEmployee(Employee employee) Updates employee of the current TreeNode

You may not modify the TreeNode class.

The CompanyHierarchyException Class


Below are the specifications for this class:

  • Code an unchecked exception class to be used by your implementation of CompanyHierarchy to signal various exceptions.
  • Write the constructor that enables you to pass a String message.
  • Specific details about the exception will be given in each function description.

The CompanyHierarchy Class

The CompanyHierarchy class stores the root of company hierarchy tree. The CompanyHierarchy class has the constructor and methods shown in the table below. A shell of this class is also provided for you (see CompanyHierarchy.java), you must implement all the methods.
Note: In addition to the information given below, your CompanyHierarchy class will need to be able to detect null parameter values and, when a null parameter value is passed, or <0 value is passed for id, throw a java.lang.IllegalArgumentException. If root of the CompanyHierarchy tree is null, then return an appropriate value.


When you run into ParseException while using SimpleDateFormat, catch the exception and throw a CompanyHierarchyException with this message: "Date parsing failed!".
To be more specific, move your parse code into a try-catch block where your catch is supposed to catch ParseException and inside your catch throw the new exception.
Constructor Description
CompanyHierarchy() Constructs an empty company hierarchy tree.
Method Description
String getCEO() Get the name of the CEO in this company tree
Return null if root is null
int getNumEmployees() Return the number of employees in this company tree
Return 0 if root is null
int getMaxLevels() Return the number of levels in the tree : 0+ values
Return 0 if root is null
Employee getEmployee(int id, String name) Return the employee details of given employee id and name
Return null if no such employee was found
If you found a match with employee id, but the name is different, then throw a CompanyHierarchyException with this message: "Incorrect employee name for id!"
boolean addEmployee(Employee employee, int supervisorId, String supervisorName) Adds employee as a child to the given supervisor node if supervisor exists on tree
When the root and supervisorName are both null, you should set the employee as the root and return true. Do not throw an IllegalArgumentException for this circumstance alone.
If there is no such supervisor, return false
If the company hierarchy tree already has this employee, don't do anything and return false; otherwise add the employee and return true
If you found that another employee in the CompanyHierarchy tree that has this same id (that is your employee instance will have an ID) then throw CompanyHierarchyException with this message: "Id already used!"
If you found a match with supervisor id, but the supervisor name is different, then throw a CompanyHierarchyException with this message: "Incorrect supervisor name for id!"
boolean contains(int id, String name, String exceptionMessage) Return true if the company hierarchy tree contains employee with given ID and name, otherwise return false.
If the employee id matches, but name doesn't match, then throw a CompanyHierarchyException with the message as passed by argument exceptionMessage
boolean removeEmployee(int id, String name) Removes the given employee(if found on the tree) and updates all the workers to report to the given employee's supervisor
Make sure to update all the required fields due to this supervisor-worker relationship change
Returns true or false accordingly
If you found a match with employee id, but the name is different, then throw a CompanyHierarchyException with this message: "Incorrect employee name for id!"
If asked to remove the root, then throw a CompanyHierarchyException with this message: "Cannot remove CEO of the company!"
You may use any methods in the Java's ArrayList<E> class
boolean replaceEmployee(int id, String name, Employee newEmployee) Replaces the given employee(if found on the tree) and if the new employee title matches with old employee
Returns true or false accordingly
If the new employee id (in this case consider only full employee details match) already exists on the company tree, then throw a CompanyHierarchyException with this message: "Replacing employee already exists on the Company Tree!"
If you found that another employee in the CompanyHierarchy tree that has this same id (that is your newEmployee instance will have an ID) then throw CompanyHierarchyException with this message: "Id already used!"
If the new employee title doesn't match with the old employee's title, then throw a CompanyHierarchyException with this message: "Replacement title does not match existing title!"
List<Employee> getEmployeeWithTitle(String title) Search and return the list of employees with the provided title
If none found return null
List<Employee> getEmployeeInJoiningDateRange(String startDate, String endDate) Search and return the list of employees with date of joing within the provided range
If none found return null
Assume that mm/dd/yyyy is the format which you have to expect. Use the SimpleDateFormat to parse the date and once parsed use any relevant functions from Date to perform comparison.
List<Employee> getCoWorkers(int id, String name) Return the list of employees who are in the same level as the given employee sharing the same supervisor
If you found a match with employee id, but the name is different, then throw a CompanyHierarchyException with this message: "Incorrect employee name for id!"
List<Employee> getSupervisorChain(int id, String name) Returns the supervisor list(till CEO) for a given employee
Returns null if employee is not found
If you found a match with employee id, but the name is different, then throw a CompanyHierarchyException with this message: "Incorrect employee name for id!"
If asked to find supervisor chain of the root, then throw a CompanyHierarchyException with this message: "No Supervisor Chain found for that employee!"

You may not add any public methods to the CompanyHierarchy class, but you should add private helper methods. Wherever possible, you should write any repititive code inside a private helper function. Two such example functions are already provided on the shell of this class.


Employee Records File


A text file storing information of employee information will be read by your program. Each line in the text file (except the first line) corresponds to a employee's information in this format:

name,employee id,date of joining,title,supervisor name,supervisor employee id The first line in the text file corresponds to CEO's information in this format: name,employee id,date of joining,title It should be the root of the company hierarchy tree.
  • See this example input file sampleInput.txt.
  • You may assume that the input files are in the specified format and contain at least one employee.
  • String data in this program should be stored and output with the same capitalization as in the input file; don't convert them to all lowercase or uppercase.
  • The input file may contain whitespaces, which should not go into the tree. Trim all data before entering them into the tree.

The CompanyHierarchyMain Class


The application program, CompanyHierarchyMain, creates and uses a CompanyHierarchy to represent and process information about company employees. The employee information is read from a text file (explained above) and then the program processes user commands.

The CompanyHierarchyMain.java file contains the outline of the CompanyHierarchyMain class. Download this file and use it as the starting point for your CompanyHierarchyMain implementation.

The command line format for the program is:

java -cp . CompanyHierarchyMain FileName

where FileName is the name of the text file to be processed. See below for more information about command line arguments.

The main method of the CompanyHierarchyMain class does the following:

  1. Check whether exactly one command-line argument is given; if not, display "Usage: java -cp . CompanyHierarchyMain FileName" and quit.
  2. Check whether the input file exists and is readable; if not, display "Error: Cannot access input file" and quit.
  3. Load the data from the input file and use it to construct a company hierarchy tree. Note: people are to be added to the company hierarchy tree in the order in which they appear in the text file.
  4. Prompt the user to enter command options and process them until the user types x for exit. Add a try-catch for CompanyHierarchyException where appropriate and display the exception message.

The command options are:

Command format Description
c id,name Print the name(s) of the co-employees(sharing the same supervisor) of the employee with given id and name. Print the names on separate lines. If no such employee is found, display "Employee not found!". If the employee has no co-employee under the same supervisor, display "The employee has no co-workers.".
d Display information about the company hierarchy tree by doing the following:
  1. Display on a line: "# of employees in company hierarchy tree: integer"
    This is the number of employees in this company hierarchy tree.

  2. Display on a line: "max levels in company hierarchy tree: integer"
    This is the maximum number of levels in the company hierarchy tree.

  3. Dispaly on a line: "CEO: name"
    This is the name of the CEO in the company hierarchy tree

e title Print the name(s) of the employee(s) that has the given title. Print the names on separate lines. If no such employee is found, display "Employee not found!"
a newid,newname,DOJ,title,
supervisorId,supervisorName
Add a new employee with given details to the company tree. Display "Employee added" if the addition was successful. If there is no such supervisor in the company tree, display "Cannot add employee as supervisor was not found!". If employee already exists in the company tree, then display "Employee already exists!".
r id,name Remove the employee with given id and name from the company tree and re-assign the worker's to the removed employee's supervisor. Display "Employee removed" after the removal. If there is no such employee in the company tree, display "Employee not found!".
s id,name Print the name(s) of all the supervisors in the supervisor chain of the given employee. Print the names on separate lines. If no such employee is found, display "Employee not found!"
u id,name,newid,newname,DOJ,title Replace the employee with give id and name from the company tree with the provided employee details. Display "Employee replaced" after the removal. If there is no such employee in the company tree, display "Employee not found!"
j startDate,endDate Print the name(s) of the employee(s) whose date of joining are between startDate and endDate(you may assume that startDate is equal to or before end date). Print the names on separate lines. If no such employee is found, display "Employee not found!"
x exit

You may not add any additional commands to those listed above.

Command-line arguments

Recall that in Java, when you run a program it is a main method that runs and that main method always has the following header:

public static void main(String[] args)

The array-of-Strings parameter, args, contains the command-line arguments that are specified when the program is run. If the program is run from a Linux prompt (i.e., not from a programming environment like Eclipse), the command-line arguments are simply typed after the name of the class whose main method is to be executed. For example:

java -cp . CompanyHierarchyMain sampleInput.txt

runs the Java interpreter on the main method of the CompanyHierarchyMain class, passing the string "sampleInput.txt" as the command-line argument.

To use command-line arguments when you run a Java program using Eclipse:

  1. Right click on the source file that contains the main class you want to run in the "Package Explorer" window.
  2. Select "Run As" from the pop-up menu.
  3. Select "Run Configurations..." from the pop-up menu, which brings up the "Run Configurations" window.
  4. Click on the "(x)= Arguments" tab.
  5. Enter the arguments in the "Program arguments:" text box.
  6. Click either the "Run" button or the "Apply" and "Run" buttons.

Steps

After you have read this program page and given thought to the problem we suggest the following steps:

  1. You may use the Java development environment of your choice in CS 367. However, all programs must compile and run on the lab computers for grading.
  2. Download the following to your programming assignment 2 directory:
  3. Implement and thoroughly test your CompanyHierarchy class and any additional supporting classes.
  4. Incrementally implement the CompanyHierarchyMain class as specified in the main program section above.
  5. Test each step to ensure your program is working correctly before implementing the next step.
  6. Create a small text file for testing (it will be easier to debug than using a larger one) and make sure you test all the boundary and negative cases as well as the positive cases.
  7. Try this sample input file, sampleInput.txt, and make sure your program produces the exact same output, sampleOutput.txt (i.e., when the user enters the same commands shown in the sample output).
  8. Once you've got your program working on the small text file, create larger text files and make sure your program works on those as well.
  9. If you are not using the lab computers to develop your program, make sure you compile and run your program to ensure that it works on the Linux lab computers. You can compile your Java source using javac in a terminal window as in this example: javac -cp . *.java and the run your program using java as in: java -cp . CompanyHierarchyMain sampleInput.txt
  10. Submit your work for grading.

SUBMISSION

  • Make sure your code follows the style and commenting standards. You should write appropriate private methods, instead of repeating the same code inside multiple public methods.
  • Follow the submission instructions from Programs page
  • For this pogram, you need to turn in the following files:
    • "Employee.java"
    • "Treenode.java"
    • "CompanyHierarchy.java" containing your implementation of the CompanyHierarchy class, and
    • "CompanyHierarchyMain.java" containing your company hierarchy tree processing application,
    • "CompanyHierarchyException.java" containing your implementation of the CompanyHierarchyException class, and
    • "*.java" additional classes (if any) that you've implemented for your program.