From f85f953668cd4fabbc67a19d241b1192f65846a8 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Tue, 1 Jun 2021 15:01:23 +0200 Subject: [PATCH] Bind countOfWarnSeverity and countOfCritSeverity to list --- .../ui/health/CheckDetailController.java | 84 ++++++------------- 1 file changed, 25 insertions(+), 59 deletions(-) diff --git a/main/ui/src/main/java/org/cryptomator/ui/health/CheckDetailController.java b/main/ui/src/main/java/org/cryptomator/ui/health/CheckDetailController.java index 51278e946..d579ff709 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/health/CheckDetailController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/health/CheckDetailController.java @@ -1,31 +1,27 @@ package org.cryptomator.ui.health; import com.tobiasdiez.easybind.EasyBind; +import com.tobiasdiez.easybind.EasyObservableList; +import com.tobiasdiez.easybind.Subscription; import com.tobiasdiez.easybind.optional.OptionalBinding; import org.cryptomator.cryptofs.health.api.DiagnosticResult; import org.cryptomator.ui.common.FxController; import javax.inject.Inject; import javafx.beans.binding.Binding; -import javafx.beans.property.LongProperty; import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleLongProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; import javafx.concurrent.Worker; import javafx.fxml.FXML; import javafx.scene.control.ListView; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; +import java.util.function.Function; +import java.util.stream.Stream; @HealthCheckScoped public class CheckDetailController implements FxController { - private final Map, WarnAndErrorEntry> cachedWarnAndCritCounts; - private final Binding> results; + private final EasyObservableList results; private final OptionalBinding taskState; private final Binding taskName; private final Binding taskDuration; @@ -37,15 +33,15 @@ public class CheckDetailController implements FxController { private final Binding taskSucceeded; private final Binding taskFailed; private final Binding taskCancelled; - private final LongProperty countOfWarnSeverity; - private final LongProperty countOfCritSeverity; + private final Binding countOfWarnSeverity; + private final Binding countOfCritSeverity; public ListView resultsListView; + private Subscription resultSubscription; @Inject public CheckDetailController(ObjectProperty selectedTask, ResultListCellFactory resultListCellFactory) { - selectedTask.addListener(this::rebindWarnAndCritProperties); - this.results = EasyBind.wrapNullable(selectedTask).map(HealthCheckTask::results).orElse(FXCollections.emptyObservableList()); + this.results = EasyBind.wrapList(FXCollections.observableArrayList()); this.taskState = EasyBind.wrapNullable(selectedTask).mapObservable(HealthCheckTask::stateProperty); this.taskName = EasyBind.wrapNullable(selectedTask).map(HealthCheckTask::getTitle).orElse(""); this.taskDuration = EasyBind.wrapNullable(selectedTask).mapObservable(HealthCheckTask::durationInMillisProperty).orElse(-1L); @@ -57,46 +53,27 @@ public class CheckDetailController implements FxController { this.taskFailed = taskState.map(Worker.State.FAILED::equals).orElse(false); this.taskCancelled = taskState.map(Worker.State.CANCELLED::equals).orElse(false); this.taskFinished = EasyBind.combine(taskSucceeded, taskFailed, taskCancelled, (a, b, c) -> a || b || c); - this.countOfWarnSeverity = new SimpleLongProperty(0); - this.countOfCritSeverity = new SimpleLongProperty(0); - this.cachedWarnAndCritCounts = new IdentityHashMap<>(); //important to use an identity hashmap, because collections violate the immnutable hashkey contract + this.countOfWarnSeverity = results.reduce(countSeverity(DiagnosticResult.Severity.WARN)); + this.countOfCritSeverity = results.reduce(countSeverity(DiagnosticResult.Severity.CRITICAL)); + selectedTask.addListener(this::selectedTaskChanged); } - private synchronized void rebindWarnAndCritProperties(ObservableValue observable, HealthCheckTask oldVal, HealthCheckTask newVal) { - //create and cache properites for the newList, if not already present - final var listToUpdate = newVal.results(); - cachedWarnAndCritCounts.computeIfAbsent(listToUpdate, key -> { - var warnProperty = new SimpleLongProperty(countSeverityInList(listToUpdate, DiagnosticResult.Severity.WARN)); - var errProperty = new SimpleLongProperty(countSeverityInList(listToUpdate, DiagnosticResult.Severity.CRITICAL)); - return new WarnAndErrorEntry(warnProperty, errProperty); - }); - listToUpdate.addListener(this::updateListSpecificWarnAndCritCount); - - //updateBindings - countOfCritSeverity.bind(cachedWarnAndCritCounts.get(listToUpdate).errorCount); - countOfWarnSeverity.bind(cachedWarnAndCritCounts.get(listToUpdate).warningCount); - } - - private synchronized void updateListSpecificWarnAndCritCount(ListChangeListener.Change c) { - long tmpErr = cachedWarnAndCritCounts.get(c.getList()).errorCount.get(); - long tmpWarn = cachedWarnAndCritCounts.get(c.getList()).warningCount.get(); - while (c.next()) { - if (c.wasAdded()) { - tmpWarn += countSeverityInList(c.getAddedSubList(), DiagnosticResult.Severity.WARN); - tmpErr += countSeverityInList(c.getAddedSubList(), DiagnosticResult.Severity.CRITICAL); - } + private void selectedTaskChanged(ObservableValue observable, HealthCheckTask oldValue, HealthCheckTask newValue) { + if (resultSubscription != null) { + resultSubscription.unsubscribe(); + } + if (newValue != null) { + resultSubscription = EasyBind.bindContent(results, newValue.results()); } - cachedWarnAndCritCounts.get(c.getList()).errorCount.set(tmpErr); - cachedWarnAndCritCounts.get(c.getList()).warningCount.set(tmpWarn); } - private long countSeverityInList(List list, DiagnosticResult.Severity severityToCount) { - return list.stream().map(DiagnosticResult::getServerity).filter(severityToCount::equals).count(); + private Function, Long> countSeverity(DiagnosticResult.Severity severity) { + return stream -> stream.filter(item -> severity.equals(item.getServerity())).count(); } @FXML public void initialize() { - resultsListView.itemsProperty().bind(results); + resultsListView.setItems(results); resultsListView.setCellFactory(resultListCellFactory); } @@ -119,18 +96,18 @@ public class CheckDetailController implements FxController { } public long getCountOfWarnSeverity() { - return countOfWarnSeverity.get(); + return countOfWarnSeverity.getValue().longValue(); } - public LongProperty countOfWarnSeverityProperty() { + public Binding countOfWarnSeverityProperty() { return countOfWarnSeverity; } public long getCountOfCritSeverity() { - return countOfCritSeverity.get(); + return countOfCritSeverity.getValue().longValue(); } - public LongProperty countOfCritSeverityProperty() { + public Binding countOfCritSeverityProperty() { return countOfCritSeverity; } @@ -190,15 +167,4 @@ public class CheckDetailController implements FxController { return taskCancelled; } - private static class WarnAndErrorEntry { - - WarnAndErrorEntry(LongProperty warningCount, LongProperty errorCount) { - this.warningCount = warningCount; - this.errorCount = errorCount; - } - - final LongProperty warningCount; - final LongProperty errorCount; - } - }