Seminar 05 - Export, Validation, Import
In the fifth seminar, you will still work with the Employee Records. Since the last seminar, several changes have appeared in the repository (again).
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: firstName,lastName,gender,birthDate,department
. The department
shall be serialized to number:name
e.g.:
Josef,Dvořák,MALE,1951-01-06,666:Sales
Hints:
- For simplicity, do not store the CSV file header.
- Consider using
BufferedWriter
in combo withFileWriter
for writing to the CSV file. - For converting
LocalDate
orGender
toString
simply use theirtoString()
method. - 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:
- For simplicity, do not consider invalid data in the CSV file.
- Consider using
BufferedReader
in combo withFileReader
for reading the CSV file. - For converting
String
toGender
simply use static factory methodGender.valueOf(String)
. - For converting
String
toLocalDate
simply use static factory methodLocalDate.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:
- 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.
- 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:
- The name must have length within [1;50] range.
- 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.