In the fifth seminar, you will still work with the Employee Records. This time the code base will be in almost the same state as at the end of the last seminar.

Throughout this seminar, you will work again in cooperation with your project teammates. Please, group together so that you all sit nearby for better coordination and collaboration. The pairs should be different compared to the last seminar.

Task 0: Update your repository

For this seminar, you will work again with the same forked repository as previously. We assume you already have the upstream remote set from Seminar 03 (if not, please follow Task 0.1 from that seminar).

Task 0.1: Update your main branch

First, you need to fetch new changes from the upstream repository and update your local main branch:

git switch main
git pull upstream main

Then you need to update the main branch in your forked repository:

git push origin main

Task 0.2: Create a new branch for this seminar

Again, each pair creates a new branch on a single computer as they are working together as one person during the seminar.

Pair 1 creates a new branch seminar05-pair1:

git switch -c seminar05-pair1

Pair 2 creates a new branch seminar05-pair2:

git switch -c seminar05-pair2

Task 1: Discover new changes

Since the last seminar, quite a lot has changed in terms of the structure. Before, almost all the code was placed in the ui package. This is no longer valid - business and data packages have been introduced.

The idea behind the change is to put all the core business logic into the business package. The ui package remains responsible only for the graphics-related things. The data package will contain all the (persistent in the future) storage and the low-level data manipulation.

Task 1.1: Aswer the following questions

  • What is the purpose of the CRUD service classes?
  • Why there exists a Repository interface?
  • On which level of the application architecture are validators called?
  • Can GenericExportService be extended to support CSV export?
  • How the importer may be registered in the GenericImportService?
  • What is the purpose of the Batch class?

Task 2: Enhance the application to support exporting employees into a CSV file

Currently, the application does not provide any type of data persistence, even though buttons for such import and export are present in the UI. The business logic supporting the export operation is already present in the code via GenericExportService. The class provides the ability to choose the concrete batch exporter, to create a batch of data, and to execute the export.

The choice of the batch exporter is based on the extension of the path specified by the user. Possibly, some filtering of the batch could be applied here as well.

Task 2.1: Implement the Export operation

To fully support an export operation you should implement the batch exporter. To do so, create a new class that implements BatchExporter. The format of every record in the exported CSV file is the following: guid,firstName,lastName,gender,birthDate,department. The department shall be serialized to guid:number:name e.g.:

Josef;Dvořák,Josef,Dvořák,MALE,1951-01-06,666:666:Sales

Hints:

  1. For simplicity, do not store the CSV file header.
  2. Consider using BufferedWriter in combo with FileWriter for writing to the CSV file.
  3. For converting LocalDate or Gender to String simply use their toString() method.
  4. Specify properly the Format of the exporter.

Task 2.2: Instantiate the BatchCsvExporter

Find a suitable place in the MainWindow constructor where to put the instantiation.

Task 2.3: Commit and push your implementation

Once you are finished, please commit all of your changes and push them to the remote repository.

Task 3: Enhance the application to support importing employees from CSV file

To fully support data persistence, your application needs to support import alongside the export. Similarly to the export operation, the import operation is handled by the GenericImportService. The class provides the ability to choose the concrete batch importer, to get the batch, and to replace the current data by the new ones from the batch.

Note that the new data are stored via the EmployeeCrudService, where all the records are validated before they are stored in the Repository.

Task 3.1: Implement the Import operation

All you need to do is to implement a new class extending the BatchImporter interface. Similarly to Task 2.1, you need to implement the batch importer. To do so, create a new class that implements BatchImporter. The expected format of the CSV file is very the same as in the previous task.

Hints:

  1. For simplicity, do not consider invalid data in the CSV file.
  2. Consider using BufferedReader in combo with FileReader for reading the CSV file.
  3. For converting String to Gender simply use static factory method Gender.valueOf(String).
  4. For converting String to LocalDate simply use static factory method LocalDate.parse(CharSequence).

Task 3.2: Instantiate the BatchCsvImporter

Find a suitable place in the MainWindow constructor where to put the instantiation.

Task 3.3: Commit and push your implementation

Once you are finished, please commit all of your changes and push them to the remote repository.

Task 4: Department validation

Currently, the Employee entity is validated in the EmployeeCrudService before it is stored in the system. However, this does not apply to the Department entity precisely. If you dive into the code, you discover that no actual validation are applied.

Note that the validation itself is separated into two layers:

  1. The low-level validation such as StringLengthValidator. Such validators have no semantics.
    • Low-level validators may be combined as long as they do not introduce semantics.
  2. The semantics level validation combines low-level validators to specify actual properties of an entity.
    • On this level, also other entities might be examined.

Task 4.1: Implement the Department Validator

Following constraints must be valid for all departments:

  1. The name must have length within [1;50] range.
  2. The number must have length within [2;10] range.

Get inspired by the EmployeeValidator and its incorporation in the EmployeeCrudService. Apply the same principles in the DepartmentCrudService.

Task 4.2: Instantiate the DepartmentValidator

Find a suitable place in the MainWindow constructor where to put the instantiation.

Task 4.3: Commit and push your implementation

Once you are finished, please commit all of your changes and push them to the remote repository.