Bug 552127 - ValidationService can only validate a collection of Objects
Add API for validating any generic iterable of EObjects.
Change-Id: I6d997ea7c174b7ad43c777698b9f90caccff3bf9
Signed-off-by: Christian W. Damus <give.a.damus@gmail.com>
diff --git a/bundles/org.eclipse.emf.ecp.view.validation/src/org/eclipse/emf/ecp/view/internal/validation/ValidationServiceImpl.java b/bundles/org.eclipse.emf.ecp.view.validation/src/org/eclipse/emf/ecp/view/internal/validation/ValidationServiceImpl.java
index b92dd7b..e747b00 100644
--- a/bundles/org.eclipse.emf.ecp.view.validation/src/org/eclipse/emf/ecp/view/internal/validation/ValidationServiceImpl.java
+++ b/bundles/org.eclipse.emf.ecp.view.validation/src/org/eclipse/emf/ecp/view/internal/validation/ValidationServiceImpl.java
@@ -10,7 +10,7 @@
*
* Contributors:
* Eugen - initial API and implementation
- * Christian W. Damus - bugs 533522, 543160, 545686, 527686, 548761
+ * Christian W. Damus - bugs 533522, 543160, 545686, 527686, 548761, 552127
******************************************************************************/
package org.eclipse.emf.ecp.view.internal.validation;
@@ -543,7 +543,14 @@
}
@Override
+ public void validate(Iterable<? extends EObject> objects) {
+ objects.forEach(validationQueue::add);
+ processValidationQueue();
+ }
+
+ @Override
public void validate(Collection<EObject> eObjects) {
+ // Delegate the opposite direction to how the default interface method does
validationQueue.addAll(eObjects);
processValidationQueue();
}
diff --git a/bundles/org.eclipse.emf.ecp.view.validation/src/org/eclipse/emf/ecp/view/spi/validation/ValidationService.java b/bundles/org.eclipse.emf.ecp.view.validation/src/org/eclipse/emf/ecp/view/spi/validation/ValidationService.java
index 86a3087..8beedc5 100644
--- a/bundles/org.eclipse.emf.ecp.view.validation/src/org/eclipse/emf/ecp/view/spi/validation/ValidationService.java
+++ b/bundles/org.eclipse.emf.ecp.view.validation/src/org/eclipse/emf/ecp/view/spi/validation/ValidationService.java
@@ -10,11 +10,13 @@
*
* Contributors:
* Eugen - initial API and implementation
- * Christian W. Damus - bug 548761
+ * Christian W. Damus - bugs 548761, 552127
******************************************************************************/
package org.eclipse.emf.ecp.view.spi.validation;
import java.util.Collection;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
@@ -85,11 +87,34 @@
void deregisterValidationListener(ViewValidationListener listener);
/**
+ * Validate the {@code objects} provided by an iterable.
+ *
+ * @param objects the iterable from which to obtain objects to validate
+ *
+ * @since 1.23
+ */
+ default void validate(Iterable<? extends EObject> objects) {
+ if (objects instanceof Collection<?>) {
+ // This should be safe because a correct implementation must never modify the collection
+ @SuppressWarnings("unchecked")
+ final Collection<EObject> collection = (Collection<EObject>) objects;
+ validate(collection);
+ } else {
+ // Create a new collection
+ final Collection<EObject> collection = StreamSupport.stream(objects.spliterator(), false)
+ .collect(Collectors.toList());
+ validate(collection);
+ }
+ }
+
+ /**
* Validates all given eObjects.
*
* @param eObjects the eObjects to validate
+ *
+ * @see {@link #validate(Iterable)} for an alternative that is more convenient when validating
+ * content trees covered by EMF {@code TreeIterator}s
*/
- // TODO this should be refactored to use an iterator rather than a collection
void validate(Collection<EObject> eObjects);
/**
diff --git a/tests/org.eclipse.emf.ecp.view.validation.test/src/org/eclipse/emf/ecp/view/validation/test/ValidationService_PTest.java b/tests/org.eclipse.emf.ecp.view.validation.test/src/org/eclipse/emf/ecp/view/validation/test/ValidationService_PTest.java
index 214c7d9..1501c3a 100644
--- a/tests/org.eclipse.emf.ecp.view.validation.test/src/org/eclipse/emf/ecp/view/validation/test/ValidationService_PTest.java
+++ b/tests/org.eclipse.emf.ecp.view.validation.test/src/org/eclipse/emf/ecp/view/validation/test/ValidationService_PTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011-2018 EclipseSource Muenchen GmbH and others.
+ * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,17 +10,24 @@
*
* Contributors:
* Stefan Dirix - initial API and implementation
- * Christian W. Damus - bug 533522
+ * Christian W. Damus - bugs 533522, 552127
******************************************************************************/
package org.eclipse.emf.ecp.view.validation.test;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EObject;
@@ -35,6 +42,7 @@
import org.eclipse.emf.ecp.view.spi.model.VViewFactory;
import org.eclipse.emf.ecp.view.spi.validation.ValidationProvider;
import org.eclipse.emf.ecp.view.spi.validation.ValidationService;
+import org.eclipse.emf.ecp.view.spi.validation.ViewValidationListener;
import org.eclipse.emf.ecp.view.validation.test.model.CrossReferenceContainer;
import org.eclipse.emf.ecp.view.validation.test.model.CrossReferenceContent;
import org.eclipse.emf.ecp.view.validation.test.model.TableContentWithInnerChild;
@@ -389,4 +397,82 @@
/* assert no NPE */
}
+ @Test
+ public void testValidate_Iterable() {
+ final AtomicReference<Collection<EObject>> validated = new AtomicReference<>();
+
+ // CHECKSTYLE.OFF: AnonInnerLength - it's a test
+ final ValidationService validationService = new ValidationService() {
+
+ @Override
+ public void validate(Collection<EObject> eObjects) {
+ validated.set(eObjects);
+ }
+
+ @Override
+ public void instantiate(ViewModelContext context) {
+ // Not interesting
+ }
+
+ @Override
+ public int getPriority() {
+ // Not interesting
+ return 0;
+ }
+
+ @Override
+ public void dispose() {
+ // Not interesting
+ }
+
+ @Override
+ public void childViewModelContextAdded(ViewModelContext childContext) {
+ // Not interesting
+ }
+
+ @Override
+ public void removeValidationProvider(ValidationProvider validationProvider, boolean revalidate) {
+ // Not interesting
+ }
+
+ @Override
+ public void removeValidationProvider(ValidationProvider validationProvider) {
+ // Not interesting
+ }
+
+ @Override
+ public void registerValidationListener(ViewValidationListener listener) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void deregisterValidationListener(ViewValidationListener listener) {
+ // Not interesting
+ }
+
+ @Override
+ public void addValidationProvider(ValidationProvider validationProvider, boolean revalidate) {
+ // Not interesting
+ }
+
+ @Override
+ public void addValidationProvider(ValidationProvider validationProvider) {
+ // Not interesting
+ }
+ };
+ // CHECKSTYLE.ON: AnonInnerLength
+
+ final List<EObject> eObjects = Arrays.asList(
+ mock(EObject.class, "a"),
+ mock(EObject.class, "b"),
+ mock(EObject.class, "c"));
+
+ final Iterable<EObject> iterable = eObjects::iterator;
+ validationService.validate(iterable);
+
+ assertThat("No collection passed to validation service", validated.get(), notNullValue());
+ assertThat("Collection has wrong size", validated.get().size(), is(eObjects.size()));
+ assertThat("Collection has wrong elements", new ArrayList<>(validated.get()), equalTo(eObjects));
+ }
+
}