Migrate Pet controllers to REST API

This commit is contained in:
2026-03-07 13:28:45 -07:00
parent 58e29f307e
commit 87f616d08e
4 changed files with 125 additions and 155 deletions

View File

@@ -1,5 +1,6 @@
package org.example.petshopdesktop.controllers;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
@@ -10,16 +11,18 @@ import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.example.petshopdesktop.api.dto.pet.PetResponse;
import org.example.petshopdesktop.api.endpoints.PetApi;
import org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController;
import org.example.petshopdesktop.database.PetDB;
import org.example.petshopdesktop.database.ProductDB;
import org.example.petshopdesktop.models.Pet;
import org.example.petshopdesktop.util.ActivityLogger;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.time.LocalDate;
import java.time.Period;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class PetController {
@@ -83,48 +86,24 @@ public class PetController {
//if confirmed, start deletion
if (result.isPresent() && result.get() == ButtonType.OK) {
int successCount = 0;
int failCount = 0;
StringBuilder errors = new StringBuilder();
List<Long> ids = selectedPets.stream()
.map(p -> (long) p.getPetId())
.collect(Collectors.toList());
for (Pet pet : selectedPets) {
try{
int numRows = PetDB.deletePet(pet.getPetId());
if (numRows > 0) {
successCount++;
} else {
failCount++;
}
}
catch (SQLIntegrityConstraintViolationException e){
ActivityLogger.getInstance().logException(
"PetController.btnDeleteClicked",
e,
String.format("Attempting to delete pet ID %d - foreign key constraint", pet.getPetId()));
failCount++;
errors.append("Pet '").append(pet.getPetName()).append("' is referenced in another table\n");
}
catch (SQLException e) {
ActivityLogger.getInstance().logException(
"PetController.btnDeleteClicked",
e,
String.format("Attempting to delete pet ID %d", pet.getPetId()));
failCount++;
errors.append("Failed to delete '").append(pet.getPetName()).append("'\n");
}
}
//show results
if (failCount > 0) {
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setHeaderText("Delete Operation Completed with Errors");
alert.setContentText(String.format("Deleted: %d\nFailed: %d\n\n%s",
successCount, failCount, errors.toString()));
alert.showAndWait();
} else if (successCount > 0) {
try {
PetApi.getInstance().deletePets(ids);
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("Database Operation Confirmed");
alert.setContentText("Successfully deleted " + successCount + " pet(s)");
alert.setContentText("Successfully deleted " + ids.size() + " pet(s)");
alert.showAndWait();
} catch (Exception e) {
ActivityLogger.getInstance().logException(
"PetController.btnDeleteClicked",
e,
"Deleting pets");
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Delete Operation Failed");
alert.setContentText(e.getMessage());
alert.showAndWait();
}
@@ -187,39 +166,55 @@ public class PetController {
}
private void displayFilteredPet(String filter) {
data.clear();
try{
if (txtSearch.getText() == null || txtSearch.getText().isEmpty()){
displayPets();
}
else {
data = PetDB.getFilteredPets(filter);
tvPets.setItems(data);
}
} catch (Exception e) {
ActivityLogger.getInstance().logException(
"PetController.displayFilteredPet",
e,
"Filtering pets with filter: " + filter);
System.out.println("Error while fetching table data: " + e.getMessage());
if (txtSearch.getText() == null || txtSearch.getText().isEmpty()){
displayPets();
} else {
new Thread(() -> {
try {
List<PetResponse> pets = PetApi.getInstance().listPets(filter);
List<Pet> petList = pets.stream()
.map(this::mapToPet)
.collect(Collectors.toList());
Platform.runLater(() -> {
data.setAll(petList);
tvPets.setItems(data);
});
} catch (Exception e) {
Platform.runLater(() -> {
System.out.println("Error while fetching table data: " + e.getMessage());
ActivityLogger.getInstance().logException(
"PetController.displayFilteredPet",
e,
String.format("Filtering pets with keyword: %s", filter));
});
}
}).start();
}
}
private void displayPets() {
data.clear();
new Thread(() -> {
try {
List<PetResponse> pets = PetApi.getInstance().listPets(null);
List<Pet> petList = pets.stream()
.map(this::mapToPet)
.collect(Collectors.toList());
try{
data = PetDB.getPets();
}
catch(SQLException e){
ActivityLogger.getInstance().logException(
"PetController.displayPets",
e,
"Fetching pet data for table display");
System.out.println("Error while fetching table data: " + e.getMessage());
}
tvPets.setItems(data);
Platform.runLater(() -> {
data.setAll(petList);
tvPets.setItems(data);
});
} catch (Exception e) {
Platform.runLater(() -> {
System.out.println("Error while fetching table data: " + e.getMessage());
ActivityLogger.getInstance().logException(
"PetController.displayPets",
e,
"Fetching pet data for table display");
});
}
}).start();
}
private void openDialog(Pet pet, String mode){
@@ -261,4 +256,20 @@ public class PetController {
txtSearch.setText("");
}
private Pet mapToPet(PetResponse response) {
int age = 0;
if (response.getDateOfBirth() != null) {
age = Period.between(response.getDateOfBirth(), LocalDate.now()).getYears();
}
return new Pet(
response.getId().intValue(),
response.getPetName(),
response.getSpecies(),
response.getBreed(),
age,
response.getPetStatus(),
response.getPrice().doubleValue()
);
}
}

View File

@@ -21,7 +21,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors
import java.util.stream.Collectors;
/**
* The controller for any operations in the products view
@@ -286,13 +286,14 @@ public class ProductController {
}
private ProductDTO mapToProductDTO(ProductResponse response) {
ProductDTO dto = new ProductDTO();
dto.setProdId(response.getId().intValue());
dto.setProdName(response.getProductName());
dto.setProdPrice(response.getPrice().doubleValue());
dto.setCategoryName(response.getCategoryName());
dto.setProdDesc(response.getDescription());
return dto;
return new ProductDTO(
response.getId().intValue(),
response.getProductName(),
response.getPrice().doubleValue(),
0,
response.getCategoryName(),
response.getDescription()
);
}
}

View File

@@ -8,14 +8,15 @@ import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import org.example.petshopdesktop.DTOs.ProductDTO;
import org.example.petshopdesktop.Validator;
import org.example.petshopdesktop.database.PetDB;
import org.example.petshopdesktop.models.Category;
import org.example.petshopdesktop.api.dto.pet.PetRequest;
import org.example.petshopdesktop.api.dto.pet.PetResponse;
import org.example.petshopdesktop.api.endpoints.PetApi;
import org.example.petshopdesktop.models.Pet;
import org.example.petshopdesktop.util.ActivityLogger;
import java.sql.SQLException;
import java.math.BigDecimal;
import java.time.LocalDate;
public class PetDialogController {
@@ -77,7 +78,6 @@ public class PetDialogController {
}
private void buttonSaveClicked(MouseEvent mouseEvent) {
int numRow = 0;
String errorMsg = "";
//Check validation (input required)
@@ -102,46 +102,30 @@ public class PetDialogController {
errorMsg += Validator.isNonNegativeInteger(txtPetAge.getText(), "Age");
if(errorMsg.isEmpty()){
Pet pet = collectPet();
if(mode.equals("Add")) {
try{
numRow = PetDB.insertPet(pet);
PetRequest request = buildPetRequest();
try {
if(mode.equals("Add")) {
PetApi.getInstance().createPet(request);
} else {
Long petId = Long.parseLong(lblPetId.getText().split(": ")[1]);
PetApi.getInstance().updatePet(petId, request);
}
catch (SQLException e) {
ActivityLogger.getInstance().logException(
"PetDialogController.buttonSaveClicked",
e,
"Inserting new pet record");
throw new RuntimeException(e);
}
}
else {
try {
numRow = PetDB.updatePet(pet.getPetId(), pet);
}
catch (SQLException e) {
ActivityLogger.getInstance().logException(
"PetDialogController.buttonSaveClicked",
e,
"Updating pet with ID: " + pet.getPetId());
throw new RuntimeException(e);
}
}
//if no rows were affected then there was an error (prompt user of error)
if (numRow == 0){
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Database Operation Error");
alert.setContentText(mode + " failed");
alert.showAndWait();
}
else {
//tell the user operation was successful
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("Saved");
alert.setContentText(mode + " succeeded");
alert.showAndWait();
closeStage(mouseEvent);
} catch (Exception e) {
ActivityLogger.getInstance().logException(
"PetDialogController.buttonSaveClicked",
e,
mode + " pet record");
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Operation Error");
alert.setContentText(mode + " failed: " + e.getMessage());
alert.showAndWait();
}
}
else{
@@ -152,23 +136,19 @@ public class PetDialogController {
}
}
private Pet collectPet() {
int petId =0;
Pet pet = null;
private PetRequest buildPetRequest() {
PetRequest request = new PetRequest();
request.setPetName(txtPetName.getText());
request.setSpecies(txtPetSpecies.getText());
request.setBreed(txtPetBreed.getText());
request.setPetStatus(cbPetStatus.getValue());
request.setPrice(new BigDecimal(txtPetPrice.getText()));
if(lblPetId.isVisible()){
petId = Integer.parseInt(lblPetId.getText().split(": ")[1]);
}
pet = new Pet(
petId,
txtPetName.getText(),
txtPetSpecies.getText(),
txtPetBreed.getText(),
Integer.parseInt(txtPetAge.getText()),
cbPetStatus.getValue(),
Double.parseDouble(txtPetPrice.getText())
);
return pet;
int age = Integer.parseInt(txtPetAge.getText());
LocalDate dateOfBirth = LocalDate.now().minusYears(age);
request.setDateOfBirth(dateOfBirth);
return request;
}
private void closeStage(MouseEvent mouseEvent) {

View File

@@ -17,7 +17,7 @@ import org.example.petshopdesktop.api.endpoints.ProductApi;
import org.example.petshopdesktop.util.ActivityLogger;
import java.math.BigDecimal;
import java.util.List
import java.util.List;
public class ProductDialogController {
@@ -145,28 +145,6 @@ public class ProductDialogController {
}
}
/**
* Collect the product info
* @return product info with the id or the new product
*/
private Product collectProduct(){
int prodId = 0;
Product product = null;
if(lblProdId.isVisible()){ //Edit mode
//get product id from lblId (split the string so we only get the int)
prodId = Integer.parseInt(lblProdId.getText().split(": ")[1]);
}
product = new Product(
prodId,
txtProdName.getText(),
Double.parseDouble(txtProdPrice.getText()),
cbProdCategory.getSelectionModel().getSelectedItem().getCategoryId(),
txtProdDesc.getText()
);
return product;
}
/**
* Display the product data in text fields and combobox
* @param product the product entity containing data to display