| /** |
| ******************************************************************************** |
| * Copyright (c) 2019-2021 Robert Bosch GmbH and others. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Robert Bosch GmbH - initial API and implementation |
| ******************************************************************************** |
| */ |
| |
| package org.eclipse.app4mc.validation.ui.util; |
| |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.concurrent.ConcurrentMap; |
| import java.util.concurrent.CopyOnWriteArraySet; |
| |
| import org.eclipse.app4mc.validation.core.IProfile; |
| import org.eclipse.app4mc.validation.util.CachedValidator; |
| import org.eclipse.app4mc.validation.util.ValidationExecutor; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.emf.common.util.TreeIterator; |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| |
| /** |
| * A validator for EMF models. Loads the validations from a list of |
| * {@link IProfile} classes |
| */ |
| public class ValidationExecutorWithMonitor extends ValidationExecutor { |
| |
| public ValidationExecutorWithMonitor(Class<? extends IProfile> profileClass) { |
| super(profileClass); |
| } |
| |
| public ValidationExecutorWithMonitor(Collection<Class<? extends IProfile>> profileClasses) { |
| super(profileClasses); |
| } |
| |
| public ValidationExecutorWithMonitor( |
| ConcurrentMap<EClassifier, CopyOnWriteArraySet<CachedValidator>> validationMap) { |
| super(validationMap); |
| } |
| |
| /** |
| * Validates the model object (and all contained objects) |
| * |
| * @param model the model object to validate |
| * @return the status |
| */ |
| public IStatus validateWithMonitor(final EObject model) { |
| return validateWithMonitor(model, new NullProgressMonitor()); |
| } |
| |
| /** |
| * Validates the model objects (and all contained objects) |
| * |
| * @param models the list of model objects to validate |
| * @return the status |
| */ |
| public IStatus validateWithMonitor(final List<EObject> models) { |
| return validateWithMonitor(models, new NullProgressMonitor()); |
| } |
| |
| /** |
| * Validates the model object (and all contained objects) |
| * |
| * @param model the model object to validate |
| * @param monitor the progress monitor |
| * @return the status |
| */ |
| public IStatus validateWithMonitor(final EObject model, final IProgressMonitor monitor) { |
| return validateWithMonitor(Collections.singletonList(model), monitor); |
| } |
| |
| /** |
| * Validates the model objects (and all contained objects) |
| * |
| * @param models the list of model objects to validate |
| * @param monitor the progress monitor |
| * @return the status |
| */ |
| public IStatus validateWithMonitor(final List<EObject> models, final IProgressMonitor monitor) { |
| results.clear(); |
| |
| try { |
| // count overall number of objects |
| int count = 0; |
| for (EObject eObject : models) { |
| count = count + getModelObjectCount(eObject); |
| } |
| |
| monitor.beginTask("Validating objects", count / 1000 + 1); |
| |
| int i = 0; |
| for (EObject eObject : models) { |
| validateObject(eObject); // need to validate the root, because the iterator misses this one |
| i++; |
| |
| TreeIterator<EObject> iterator = EcoreUtil.getAllContents(eObject, false); |
| while (iterator.hasNext()) { |
| validateObject(iterator.next()); |
| i++; |
| |
| if ((i % 1000) == 0) { |
| monitor.worked(1); |
| if (monitor.isCanceled()) { |
| return Status.CANCEL_STATUS; |
| } |
| } |
| } |
| } |
| |
| return Status.OK_STATUS; |
| } finally { |
| monitor.done(); |
| } |
| } |
| |
| // Future extension: parallel execution |
| // |
| // requires a model that is not modified by traversal of validators !! |
| // |
| // Idea: |
| // ** use a JobGroup: |
| // - e.g. with <job name> <availableProcessors> |
| // ** Iterate parallel: |
| // - Streams.stream(iterator).parallel(). ... |
| |
| private int getModelObjectCount(EObject object) { |
| int count = 1; // root object |
| for (Iterator<?> iter = object.eAllContents(); iter.hasNext(); iter.next()) { |
| count++; |
| } |
| |
| return count; |
| } |
| |
| } |