From ad05e9e95a0143007dc6778e4c3f205e93e9eb9f Mon Sep 17 00:00:00 2001 From: David Guler Date: Tue, 8 Nov 2022 07:31:04 +0100 Subject: [PATCH 1/2] refactor: remove exception-based control-flow --- .../plantList/PlantListModel.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/ch/zhaw/gartenverwaltung/plantList/PlantListModel.java b/src/main/java/ch/zhaw/gartenverwaltung/plantList/PlantListModel.java index 4bfc9b1..ffccb30 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/plantList/PlantListModel.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/plantList/PlantListModel.java @@ -116,16 +116,17 @@ public class PlantListModel { if (searchString.length() == 0) { return getPlantList(zone); } else if (searchString.charAt(0) == '#') { - try { - return getFilteredPlantListById(zone, Long.parseLong(searchString.substring(1))); - } catch (NumberFormatException e) { + if (isPositiveIntegral(searchString.substring(1))) { + Long searchId = Long.parseLong(searchString.substring(1)); + return getFilteredPlantListById(zone, searchId); + } else { return new ArrayList<>(); } } else { String caseInsensitiveSearchString = searchString.toLowerCase(); return getFilteredPlantList(zone, plant -> - plant.name().toLowerCase().contains(caseInsensitiveSearchString) || - plant.description().toLowerCase().contains(caseInsensitiveSearchString) + plant.name().toLowerCase().contains(caseInsensitiveSearchString) || + plant.description().toLowerCase().contains(caseInsensitiveSearchString) ); } } @@ -169,15 +170,24 @@ public class PlantListModel { } /** - * * @param zone selected hardiness zone * @param from the earliest date to for the filter - * @param to the lastest date for the filter + * @param to the lastest date for the filter * @return List of Plants with selected saison * @throws HardinessZoneNotSetException If no {@link HardinessZone} was specified - * @throws IOException If the database cannot be accessed + * @throws IOException If the database cannot be accessed */ public List getFilteredPlantListBySaisonWithoutGrowthPhase(HardinessZone zone, MonthDay from, MonthDay to) throws HardinessZoneNotSetException, IOException { return getFilteredPlantList(zone, plant -> plant.lifecycle().stream().anyMatch(growthPhase -> growthPhase.startDate().compareTo(from) >= 0 && (growthPhase.startDate().compareTo(to) <= 0))); } + + /** + * Check if a string can safely be parsed as a positive Integral value (short/int/long) + * + * @param subject The string to be tested + * @return Whether the string contains only digits + */ + private boolean isPositiveIntegral(String subject) { + return subject != null && subject.matches("[0-9]+"); + } } From 590049b9cf81c199fcadbcd4a3930681987e543d Mon Sep 17 00:00:00 2001 From: David Guler Date: Tue, 8 Nov 2022 07:36:31 +0100 Subject: [PATCH 2/2] feat: Added logging and refactored code to accommodate --- .../gartenverwaltung/MainFXMLController.java | 6 +- .../gartenverwaltung/PlantsController.java | 94 +++++++++---------- .../gartenverwaltung/io/JsonGardenPlan.java | 1 - .../json/GrowthPhaseTypeDeserializer.java | 5 +- .../json/HardinessZoneDeserializer.java | 5 +- .../json/PlantImageDeserializer.java | 4 +- src/main/java/module-info.java | 1 + 7 files changed, 57 insertions(+), 59 deletions(-) diff --git a/src/main/java/ch/zhaw/gartenverwaltung/MainFXMLController.java b/src/main/java/ch/zhaw/gartenverwaltung/MainFXMLController.java index 7c21101..032bdb8 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/MainFXMLController.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/MainFXMLController.java @@ -4,7 +4,6 @@ import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; -import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.layout.AnchorPane; @@ -14,12 +13,15 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.Logger; public class MainFXMLController implements Initializable { /** * Caching the panes */ private final Map panes = new HashMap<>(); + private static final Logger LOG = Logger.getLogger(MainFXMLController.class.getName()); @FXML private Button home_button; @@ -100,7 +102,7 @@ public class MainFXMLController implements Initializable { loadPane("Home.fxml"); styleChangeButton(home_button); } catch (IOException e) { - e.printStackTrace(); + LOG.log(Level.SEVERE, "Failed to load FXML-Pane!", e); } } } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java b/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java index 9ae9b4c..c8ff333 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java @@ -7,8 +7,6 @@ import ch.zhaw.gartenverwaltung.types.Plant; import ch.zhaw.gartenverwaltung.types.Seasons; import javafx.beans.property.ListProperty; import javafx.beans.property.SimpleListProperty; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.event.ActionEvent; import javafx.fxml.FXML; @@ -29,8 +27,11 @@ import java.net.URL; import java.util.List; import java.util.Objects; import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.Logger; public class PlantsController implements Initializable { + private static final Logger LOG = Logger.getLogger(PlantsController.class.getName()); private final PlantListModel plantListModel = new PlantListModel(); private Plant selectedPlant = null; private final HardinessZone DEFAULT_HARDINESS_ZONE = HardinessZone.ZONE_8A; @@ -98,8 +99,10 @@ public class PlantsController implements Initializable { lookForSelectedListEntry(); try { viewFilteredListBySearch(); - } catch (HardinessZoneNotSetException | IOException e) { - e.printStackTrace(); + } catch (HardinessZoneNotSetException e) { + LOG.log(Level.WARNING, "Hardiness Zone not set!"); + } catch (IOException e) { + LOG.log(Level.WARNING, "Could not retrieve data!", e); } } @@ -107,7 +110,7 @@ public class PlantsController implements Initializable { * set text of list view to plant name */ private void setListCellFactory() { - list_plants.setCellFactory(param -> new ListCell() { + list_plants.setCellFactory(param -> new ListCell<>() { @Override protected void updateItem(Plant plant, boolean empty) { super.updateItem(plant, empty); @@ -143,13 +146,15 @@ public class PlantsController implements Initializable { search_plants.textProperty().addListener((observable, oldValue, newValue) -> { if (newValue.isEmpty()) { fillPlantListWithHardinessZone(); - }else { + } else { try { List filteredPlants = plantListModel.getFilteredPlantListByString(DEFAULT_HARDINESS_ZONE, newValue); clearListView(); plantListProperty.addAll(filteredPlants); - } catch (HardinessZoneNotSetException | IOException e) { - e.printStackTrace(); + } catch (HardinessZoneNotSetException e) { + LOG.log(Level.WARNING, "Hardiness Zone not set!"); + } catch (IOException e) { + LOG.log(Level.WARNING, "Could not retrieve data!", e); } } }); @@ -163,8 +168,10 @@ public class PlantsController implements Initializable { try { clearListView(); plantListProperty.addAll(plantListModel.getPlantList(plantListModel.getCurrentZone())); - } catch (HardinessZoneNotSetException | IOException e) { - e.printStackTrace(); + } catch (HardinessZoneNotSetException e) { + LOG.log(Level.WARNING, "Hardiness Zone not set!"); + } catch (IOException e) { + LOG.log(Level.WARNING, "Could not retrieve data!", e); } } @@ -182,12 +189,9 @@ public class PlantsController implements Initializable { if (zone.equals(DEFAULT_HARDINESS_ZONE)) { radioButton.setSelected(true); } - radioButton.selectedProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) { - plantListModel.setCurrentZone(zone); - fillPlantListWithHardinessZone(); - } + radioButton.selectedProperty().addListener((observable, oldValue, newValue) -> { + plantListModel.setCurrentZone(zone); + fillPlantListWithHardinessZone(); }); climate_zones.getChildren().add(radioButton); } @@ -207,20 +211,19 @@ public class PlantsController implements Initializable { if (season.equals(Seasons.AllSEASONS)) { radioButton.setSelected(true); } - radioButton.selectedProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) { - if (season.equals(Seasons.AllSEASONS)) { - fillPlantListWithHardinessZone(); - } else { - try { - viewFilteredListBySeason(season); - } catch (HardinessZoneNotSetException | IOException e) { - e.printStackTrace(); - } + radioButton.selectedProperty().addListener((observable, oldValue, newValue) -> { + if (season.equals(Seasons.AllSEASONS)) { + fillPlantListWithHardinessZone(); + } else { + try { + viewFilteredListBySeason(season); + } catch (HardinessZoneNotSetException e) { + LOG.log(Level.WARNING, "Hardiness Zone not set!"); + } catch (IOException e) { + LOG.log(Level.WARNING, "Could not retrieve data!", e); } - } + }); seasons.getChildren().add(radioButton); } @@ -237,27 +240,24 @@ public class PlantsController implements Initializable { selectSowDay_button.setDisable(true); Image img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png"))); img_plant.setImage(img); - list_plants.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, Plant oldValue, Plant newValue) { - if(newValue != null) { - selectedPlant = newValue; - description_plant.setText(selectedPlant.description()); - selectSowDay_button.setDisable(false); - Image img; - if(selectedPlant.image() != null) { - img = selectedPlant.image(); - } else { - img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png"))); - } - img_plant.setImage(img); + list_plants.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + if(newValue != null) { + selectedPlant = newValue; + description_plant.setText(selectedPlant.description()); + selectSowDay_button.setDisable(false); + Image img1; + if(selectedPlant.image() != null) { + img1 = selectedPlant.image(); } else { - selectedPlant = null; - description_plant.setText(""); - selectSowDay_button.setDisable(true); - Image img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png"))); - img_plant.setImage(img); + img1 = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png"))); } + img_plant.setImage(img1); + } else { + selectedPlant = null; + description_plant.setText(""); + selectSowDay_button.setDisable(true); + Image img1 = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png"))); + img_plant.setImage(img1); } }); } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/io/JsonGardenPlan.java b/src/main/java/ch/zhaw/gartenverwaltung/io/JsonGardenPlan.java index 3100301..cfe2663 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/io/JsonGardenPlan.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/io/JsonGardenPlan.java @@ -145,7 +145,6 @@ public class JsonGardenPlan implements GardenPlan { .registerModule(new Jdk8Module()) .writeValue(new File(dataSource.toURI()), cropMap.values()); } catch (URISyntaxException e) { - // TODO: Log throw new IOException(INVALID_DATASOURCE_MSG, e); } } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/json/GrowthPhaseTypeDeserializer.java b/src/main/java/ch/zhaw/gartenverwaltung/json/GrowthPhaseTypeDeserializer.java index 285536a..35956a1 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/json/GrowthPhaseTypeDeserializer.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/json/GrowthPhaseTypeDeserializer.java @@ -16,13 +16,12 @@ public class GrowthPhaseTypeDeserializer extends StdDeserializer { @Override public HardinessZone deserialize(JsonParser parser, DeserializationContext context) throws IOException { - HardinessZone result = null; + HardinessZone result; String token = parser.getText(); try { result = HardinessZone.valueOf(token.toUpperCase()); } catch (IllegalArgumentException e) { - // TODO: Log - System.err.printf("Unknown Hardiness Zone \"%s\"\n", token); + throw new IOException(String.format("Unknown Hardiness Zone \"%s\"\n", token), e); } return result; } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/json/PlantImageDeserializer.java b/src/main/java/ch/zhaw/gartenverwaltung/json/PlantImageDeserializer.java index f22cb35..14da20c 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/json/PlantImageDeserializer.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/json/PlantImageDeserializer.java @@ -23,9 +23,7 @@ public class PlantImageDeserializer extends JsonDeserializer { try (InputStream is = new FileInputStream(new File(imageUrl.toURI()))) { result = new Image(is); } catch (IllegalArgumentException | URISyntaxException e) { - // TODO: Log - e.printStackTrace(); - System.err.printf("Cannot find Image \"%s\"\n", imageUrl.getFile()); + throw new IOException(String.format("Cannot find Image \"%s\"\n", imageUrl.getFile())); } } return result; diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 00cf813..6900f7f 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -4,6 +4,7 @@ module ch.zhaw.gartenverwaltung { requires com.fasterxml.jackson.databind; requires com.fasterxml.jackson.datatype.jsr310; requires com.fasterxml.jackson.datatype.jdk8; + requires java.logging; opens ch.zhaw.gartenverwaltung to javafx.fxml; opens ch.zhaw.gartenverwaltung.types to com.fasterxml.jackson.databind;