diff --git a/examples/books-example/pom.xml b/examples/books-example/pom.xml
index f9414f32e..1f75bfdbe 100644
--- a/examples/books-example/pom.xml
+++ b/examples/books-example/pom.xml
@@ -5,7 +5,7 @@
de.saxsys.mvvmfx
examples
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
diff --git a/examples/contacts-example/pom.xml b/examples/contacts-example/pom.xml
index bab2c11ea..d2b339661 100644
--- a/examples/contacts-example/pom.xml
+++ b/examples/contacts-example/pom.xml
@@ -6,7 +6,7 @@
de.saxsys.mvvmfx
examples
- 1.5.1
+ 1.5.2-SNAPSHOT
contacts-example
diff --git a/examples/mini-examples/fx-root-example/pom.xml b/examples/mini-examples/fx-root-example/pom.xml
index 35496f570..c327c7584 100644
--- a/examples/mini-examples/fx-root-example/pom.xml
+++ b/examples/mini-examples/fx-root-example/pom.xml
@@ -5,7 +5,7 @@
mini-examples
de.saxsys.mvvmfx
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
diff --git a/examples/mini-examples/helloworld-without-fxml/pom.xml b/examples/mini-examples/helloworld-without-fxml/pom.xml
index 43f11ff55..4002b7644 100644
--- a/examples/mini-examples/helloworld-without-fxml/pom.xml
+++ b/examples/mini-examples/helloworld-without-fxml/pom.xml
@@ -5,7 +5,7 @@
mini-examples
de.saxsys.mvvmfx
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
diff --git a/examples/mini-examples/helloworld/pom.xml b/examples/mini-examples/helloworld/pom.xml
index 96718839c..afae78070 100644
--- a/examples/mini-examples/helloworld/pom.xml
+++ b/examples/mini-examples/helloworld/pom.xml
@@ -5,7 +5,7 @@
mini-examples
de.saxsys.mvvmfx
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
diff --git a/examples/mini-examples/pom.xml b/examples/mini-examples/pom.xml
index 26d898a40..105edc14d 100644
--- a/examples/mini-examples/pom.xml
+++ b/examples/mini-examples/pom.xml
@@ -5,7 +5,7 @@
examples
de.saxsys.mvvmfx
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
pom
diff --git a/examples/mini-examples/scopes-example/pom.xml b/examples/mini-examples/scopes-example/pom.xml
index 333f5c562..aed7bbc21 100644
--- a/examples/mini-examples/scopes-example/pom.xml
+++ b/examples/mini-examples/scopes-example/pom.xml
@@ -5,7 +5,7 @@
mini-examples
de.saxsys.mvvmfx
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
diff --git a/examples/mini-examples/synchronizefx-example/pom.xml b/examples/mini-examples/synchronizefx-example/pom.xml
index edd09b538..8bec3c691 100644
--- a/examples/mini-examples/synchronizefx-example/pom.xml
+++ b/examples/mini-examples/synchronizefx-example/pom.xml
@@ -5,7 +5,7 @@
mini-examples
de.saxsys.mvvmfx
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
diff --git a/examples/mini-examples/welcome-example/pom.xml b/examples/mini-examples/welcome-example/pom.xml
index 4ee51c3ea..c3657f17b 100644
--- a/examples/mini-examples/welcome-example/pom.xml
+++ b/examples/mini-examples/welcome-example/pom.xml
@@ -5,7 +5,7 @@
mini-examples
de.saxsys.mvvmfx
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
diff --git a/examples/pom.xml b/examples/pom.xml
index 4d2d246eb..77d8b4401 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -5,7 +5,7 @@
de.saxsys
mvvmfx-parent
- 1.5.1
+ 1.5.2-SNAPSHOT
de.saxsys.mvvmfx
diff --git a/examples/todomvc-example/pom.xml b/examples/todomvc-example/pom.xml
index d28e0d0eb..dddd8388a 100644
--- a/examples/todomvc-example/pom.xml
+++ b/examples/todomvc-example/pom.xml
@@ -5,7 +5,7 @@
de.saxsys.mvvmfx
examples
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
diff --git a/mvvmfx-archetype/pom.xml b/mvvmfx-archetype/pom.xml
index 4c425a103..a34bdc68d 100644
--- a/mvvmfx-archetype/pom.xml
+++ b/mvvmfx-archetype/pom.xml
@@ -5,7 +5,7 @@
de.saxsys
mvvmfx-parent
- 1.5.1
+ 1.5.2-SNAPSHOT
diff --git a/mvvmfx-archetype/src/main/resources/archetype-resources/pom.xml b/mvvmfx-archetype/src/main/resources/archetype-resources/pom.xml
index 46b637a8a..330696fd9 100644
--- a/mvvmfx-archetype/src/main/resources/archetype-resources/pom.xml
+++ b/mvvmfx-archetype/src/main/resources/archetype-resources/pom.xml
@@ -16,7 +16,7 @@
de.saxsys
mvvmfx-parent
- 1.5.1
+ 1.5.2-SNAPSHOT
pom
import
diff --git a/mvvmfx-cdi/pom.xml b/mvvmfx-cdi/pom.xml
index a682d1a49..137712e53 100644
--- a/mvvmfx-cdi/pom.xml
+++ b/mvvmfx-cdi/pom.xml
@@ -20,7 +20,7 @@
de.saxsys
mvvmfx-parent
- 1.5.1
+ 1.5.2-SNAPSHOT
mvvmfx-cdi
diff --git a/mvvmfx-guice/pom.xml b/mvvmfx-guice/pom.xml
index 9bf6c36bd..4c7327717 100644
--- a/mvvmfx-guice/pom.xml
+++ b/mvvmfx-guice/pom.xml
@@ -20,7 +20,7 @@
de.saxsys
mvvmfx-parent
- 1.5.1
+ 1.5.2-SNAPSHOT
mvvmfx-guice
diff --git a/mvvmfx-testing-utils/pom.xml b/mvvmfx-testing-utils/pom.xml
index f109ccb95..6aee314d5 100644
--- a/mvvmfx-testing-utils/pom.xml
+++ b/mvvmfx-testing-utils/pom.xml
@@ -5,7 +5,7 @@
mvvmfx-parent
de.saxsys
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
diff --git a/mvvmfx-utils/pom.xml b/mvvmfx-utils/pom.xml
index b331a1cf1..ccd149eea 100644
--- a/mvvmfx-utils/pom.xml
+++ b/mvvmfx-utils/pom.xml
@@ -5,7 +5,7 @@
mvvmfx-parent
de.saxsys
- 1.5.1
+ 1.5.2-SNAPSHOT
4.0.0
diff --git a/mvvmfx/pom.xml b/mvvmfx/pom.xml
index 204c9a6ae..43666f493 100644
--- a/mvvmfx/pom.xml
+++ b/mvvmfx/pom.xml
@@ -20,7 +20,7 @@
de.saxsys
mvvmfx-parent
- 1.5.1
+ 1.5.2-SNAPSHOT
mvvmfx
diff --git a/mvvmfx/src/main/java/de/saxsys/mvvmfx/utils/validation/CompositeValidationStatus.java b/mvvmfx/src/main/java/de/saxsys/mvvmfx/utils/validation/CompositeValidationStatus.java
index 7a8133623..42cc27754 100644
--- a/mvvmfx/src/main/java/de/saxsys/mvvmfx/utils/validation/CompositeValidationStatus.java
+++ b/mvvmfx/src/main/java/de/saxsys/mvvmfx/utils/validation/CompositeValidationStatus.java
@@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright 2015 Alexander Casall, Manuel Mauky
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,14 +15,8 @@
******************************************************************************/
package de.saxsys.mvvmfx.utils.validation;
-import javafx.beans.property.ListProperty;
-import javafx.beans.property.SimpleListProperty;
-import javafx.collections.FXCollections;
-import javafx.collections.ListChangeListener;
-
-import java.util.*;
+import java.util.List;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
/**
* This class is used as {@link ValidationStatus} for {@link CompositeValidator}.
@@ -66,32 +60,41 @@ void addMessage(Validator validator, List extends ValidationMessage> messages)
getMessagesInternal().addAll(
messages.stream()
// ... we wrap them to keep track of the used validator.
- .map(message -> new CompositeValidationMessageWrapper(message, validator))
- .collect(Collectors.toList()));
+ .map(message -> new CompositeValidationMessageWrapper(message, validator))
+ .collect(Collectors.toList()));
}
/*
Remove all given messages for the given validator.
*/
- void removeMessage(Validator validator, List extends ValidationMessage> messages) {
- List messagesToRemove =
+ void removeMessage(final Validator validator, final List extends ValidationMessage> messages) {
+ final List messagesToRemove =
getMessagesInternal().stream()
- .filter(messages::contains) // only the given messages
- .filter(message -> (message instanceof CompositeValidationMessageWrapper))
- .map(message -> (CompositeValidationMessageWrapper) message)
- .filter(message -> message.getValidatorCode().equals(System.identityHashCode(validator)))
- .collect(Collectors.toList());
+ .filter(messages::contains) // only the given messages
+ .filter(message -> (message instanceof CompositeValidationMessageWrapper))
+ .map(message -> (CompositeValidationMessageWrapper) message)
+ .filter(message -> message.getValidatorCode().equals(System.identityHashCode(validator)))
+ .collect(Collectors.toList());
- getMessagesInternal().removeAll(messagesToRemove);
+ getMessagesInternal().removeIf(validationMessage -> {
+ if (validationMessage instanceof CompositeValidationMessageWrapper) {
+ final CompositeValidationMessageWrapper wrapper = (CompositeValidationMessageWrapper) validationMessage;
+ return messagesToRemove.stream()
+ .filter(m -> m.getValidatorCode().equals(wrapper.getValidatorCode()))
+ .anyMatch(wrapper::equals);
+ }
+
+ return false;
+ });
}
/*
* Remove all messages for this particular validator.
*/
- void removeMessage(Validator validator) {
+ void removeMessage(final Validator validator) {
getMessagesInternal().removeIf(validationMessage -> {
- if(validationMessage instanceof CompositeValidationMessageWrapper) {
- CompositeValidationMessageWrapper wrapper = (CompositeValidationMessageWrapper) validationMessage;
+ if (validationMessage instanceof CompositeValidationMessageWrapper) {
+ final CompositeValidationMessageWrapper wrapper = (CompositeValidationMessageWrapper) validationMessage;
return wrapper.getValidatorCode().equals(System.identityHashCode(validator));
}
diff --git a/mvvmfx/src/main/java/de/saxsys/mvvmfx/utils/validation/CompositeValidator.java b/mvvmfx/src/main/java/de/saxsys/mvvmfx/utils/validation/CompositeValidator.java
index 8c41c33f4..7cb1fb1d3 100644
--- a/mvvmfx/src/main/java/de/saxsys/mvvmfx/utils/validation/CompositeValidator.java
+++ b/mvvmfx/src/main/java/de/saxsys/mvvmfx/utils/validation/CompositeValidator.java
@@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright 2015 Alexander Casall, Manuel Mauky
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,21 +15,20 @@
******************************************************************************/
package de.saxsys.mvvmfx.utils.validation;
+import java.util.HashMap;
+import java.util.Map;
+
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
-import java.util.HashMap;
-import java.util.Map;
-
/**
* This {@link Validator} implementation is used to compose multiple other validators.
*
* The {@link ValidationStatus} of this validator will contain all messages of all registered validators.
*
- *
* @author manuel.mauky
*/
public class CompositeValidator implements Validator {
@@ -45,7 +44,7 @@ public CompositeValidator() {
validators.addListener(new ListChangeListener() {
@Override
public void onChanged(Change extends Validator> c) {
- while(c.next()) {
+ while (c.next()) {
// When validators are added...
c.getAddedSubList().forEach(validator -> {
@@ -55,7 +54,7 @@ public void onChanged(Change extends Validator> c) {
status.addMessage(validator, messages);
final ListChangeListener changeListener = change -> {
- while(change.next()) {
+ while (change.next()) {
// add/remove messages for this particular validator
status.addMessage(validator, change.getAddedSubList());
status.removeMessage(validator, change.getRemoved());
@@ -73,7 +72,7 @@ public void onChanged(Change extends Validator> c) {
c.getRemoved().forEach(validator -> {
status.removeMessage(validator);
- if(listenerMap.containsKey(validator)){
+ if (listenerMap.containsKey(validator)) {
ListChangeListener changeListener = listenerMap.get(validator);
validator.getValidationStatus().getMessages().removeListener(changeListener);
@@ -85,21 +84,21 @@ public void onChanged(Change extends Validator> c) {
});
}
-
+
public CompositeValidator(Validator... validators) {
this(); // before adding the validators we need to setup the listeners in the default constructor
addValidators(validators);
}
-
-
+
+
public void addValidators(Validator... validators) {
this.validators.addAll(validators);
}
-
+
public void removeValidators(Validator... validators) {
this.validators.removeAll(validators);
}
-
+
@Override
public ValidationStatus getValidationStatus() {
return status;
diff --git a/mvvmfx/src/test/java/de/saxsys/mvvmfx/utils/validation/CompositeValidatorTest.java b/mvvmfx/src/test/java/de/saxsys/mvvmfx/utils/validation/CompositeValidatorTest.java
index 0bca51a22..d35d58495 100644
--- a/mvvmfx/src/test/java/de/saxsys/mvvmfx/utils/validation/CompositeValidatorTest.java
+++ b/mvvmfx/src/test/java/de/saxsys/mvvmfx/utils/validation/CompositeValidatorTest.java
@@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright 2015 Alexander Casall, Manuel Mauky
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,39 +15,43 @@
******************************************************************************/
package de.saxsys.mvvmfx.utils.validation;
-import javafx.beans.property.BooleanProperty;
-import javafx.beans.property.SimpleBooleanProperty;
-import javafx.beans.property.SimpleStringProperty;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.google.common.base.Strings;
+
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import java.util.stream.Collectors;
-import static org.assertj.core.api.Assertions.assertThat;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
/**
* @author manuel.mauky
*/
public class CompositeValidatorTest {
-
+
private ValidationStatus status;
-
+
private BooleanProperty valid1 = new SimpleBooleanProperty();
private BooleanProperty valid2 = new SimpleBooleanProperty();
private CompositeValidator compositeValidator;
private ObservableRuleBasedValidator validator1;
private ObservableRuleBasedValidator validator2;
-
+
@Before
public void setup() {
validator1 = new ObservableRuleBasedValidator();
validator1.addRule(valid1, ValidationMessage.error("error1"));
-
+
validator2 = new ObservableRuleBasedValidator();
validator2.addRule(valid2, ValidationMessage.warning("warning2"));
-
-
+
+
compositeValidator = new CompositeValidator();
status = compositeValidator.getValidationStatus();
}
@@ -64,56 +68,56 @@ public void testValidatorConstructor() {
assertThat(newValidator.getValidationStatus().isValid()).isFalse();
assertThat(newValidator.getValidationStatus().getMessages()).hasSize(2);
}
-
+
@Test
public void testValidation() {
compositeValidator.addValidators(validator1, validator2);
-
+
valid1.set(true);
valid2.set(true);
-
+
assertThat(status.isValid()).isTrue();
-
+
valid1.setValue(false);
-
+
assertThat(status.isValid()).isFalse();
assertThat(asStrings(status.getErrorMessages())).containsOnly("error1");
assertThat(asStrings(status.getWarningMessages())).isEmpty();
assertThat(asStrings(status.getMessages())).containsOnly("error1");
-
+
valid2.setValue(false);
assertThat(status.isValid()).isFalse();
assertThat(asStrings(status.getErrorMessages())).containsOnly("error1");
assertThat(asStrings(status.getWarningMessages())).containsOnly("warning2");
assertThat(asStrings(status.getMessages())).containsOnly("error1", "warning2");
-
+
valid1.setValue(true);
assertThat(status.isValid()).isFalse();
assertThat(asStrings(status.getErrorMessages())).isEmpty();
assertThat(asStrings(status.getWarningMessages())).containsOnly("warning2");
assertThat(asStrings(status.getMessages())).containsOnly("warning2");
-
+
valid2.setValue(true);
assertThat(status.isValid()).isTrue();
assertThat(asStrings(status.getErrorMessages())).isEmpty();
assertThat(asStrings(status.getWarningMessages())).isEmpty();
assertThat(asStrings(status.getMessages())).isEmpty();
-
+
}
-
+
@Test
public void testLazyRegistration() {
valid1.set(false);
valid2.set(true);
-
+
assertThat(status.isValid()).isTrue(); // no validator is registered at the moment
-
+
compositeValidator.addValidators(validator2);
assertThat(status.isValid()).isTrue(); // validator2 is valid
-
+
compositeValidator.addValidators(validator1);
assertThat(status.isValid()).isFalse();
-
+
compositeValidator.removeValidators(validator1);
assertThat(status.isValid()).isTrue();
}
@@ -207,6 +211,34 @@ public void testTestability() {
}
+ /**
+ * Issue #413
+ */
+ @Test
+ public void validatorsMayNotDeleteEachOthersValidationMessages() {
+ final StringProperty prop1 = new SimpleStringProperty();
+ final StringProperty prop2 = new SimpleStringProperty();
+ final Validator notEmpty1 = new FunctionBasedValidator<>(prop1, v -> {
+ if (Strings.isNullOrEmpty(v)) {
+ return ValidationMessage.error("msg");
+ }
+ return null;
+ });
+ final Validator notEmpty2 = new FunctionBasedValidator<>(prop2, v -> {
+ if (Strings.isNullOrEmpty(v)) {
+ return ValidationMessage.error("msg");
+ }
+ return null;
+ });
+ final CompositeValidator compositeValidator = new CompositeValidator(notEmpty1, notEmpty2);
+ prop1.set("");
+ prop2.set("");
+ prop1.set("a");
+ assertThat(notEmpty1.getValidationStatus().isValid()).isTrue();
+ assertThat(notEmpty2.getValidationStatus().isValid()).isFalse();
+ assertThat(compositeValidator.getValidationStatus().isValid()).isFalse();
+ }
+
private List asStrings(List messages) {
return messages
diff --git a/pom.xml b/pom.xml
index 828a287fd..a007a7181 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
de.saxsys
mvvmfx-parent
pom
- 1.5.1
+ 1.5.2-SNAPSHOT
mvvmFX parent
Application Framework for MVVM with JavaFX.
http://www.saxsys.de