blob: 2e2178f1e62c21e13f2f53243dca4219f648072b [file] [log] [blame]
package org.eclipse.bpmn2.modeler.core.validation;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.bpmn2.modeler.core.Activator;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.ui.util.EditUIMarkerHelper;
import org.eclipse.emf.validation.marker.MarkerUtil;
import org.eclipse.emf.validation.model.ConstraintStatus;
import org.eclipse.emf.validation.model.IModelConstraint;
import org.eclipse.emf.validation.service.ConstraintFactory;
import org.eclipse.emf.validation.service.ConstraintRegistry;
import org.eclipse.emf.validation.service.IConstraintDescriptor;
import org.eclipse.graphiti.ui.editor.DiagramEditor;
public class BPMN2ValidationStatusLoader {
DiagramEditor editor;
public BPMN2ValidationStatusLoader(DiagramEditor editor) {
this.editor = editor;
}
public Set<EObject> load(List<IMarker> markers) {
if (markers == null) {
return Collections.emptySet();
}
Set<EObject> touched = new LinkedHashSet<EObject>();
for (IMarker marker : markers) {
final EObject markedObject = getTargetObject(marker);
if (markedObject == null) {
continue;
}
ValidationStatusAdapter statusAdapter = (ValidationStatusAdapter) EcoreUtil.getRegisteredAdapter(
markedObject, ValidationStatusAdapter.class);
// add the adapter factory for tracking validation errors
if (statusAdapter==null) {
ResourceSet resourceSet = editor.getEditingDomain().getResourceSet();
resourceSet.getAdapterFactories().add(new ValidationStatusAdapterFactory());
statusAdapter = (ValidationStatusAdapter) EcoreUtil.getRegisteredAdapter(
markedObject, ValidationStatusAdapter.class);
}
// convert the problem marker to an IStatus suitable for the validation status adapter
IStatus status = convertMarker(marker, markedObject);
// also add an adapter to each affected EObject in the result locus
// TODO: do we need this? it causes duplicate messages to be created for each marker
// better to have the constraint handler create additional error messages as needed.
// if (status instanceof ConstraintStatus) {
// ConstraintStatus cs = (ConstraintStatus) status;
// for (EObject result : cs.getResultLocus()) {
// // CAUTION: the result locus WILL contain references to object
// // features (EStructuralFeatures) that identify the feature in
// // error for the Property Sheets. We don't want to add a validation
// // status adapter to these EObjects.
// EPackage pkg = result.eClass().getEPackage();
// if (pkg != EcorePackage.eINSTANCE) {
// ValidationStatusAdapter sa = (ValidationStatusAdapter) EcoreUtil.getRegisteredAdapter(
// result, ValidationStatusAdapter.class);
// sa.addValidationStatus(status);
// touched.add(result);
// }
// }
// }
statusAdapter.addValidationStatus(status);
touched.add(markedObject);
}
return touched;
}
private EObject getTargetObject(IMarker marker) {
final String uriString = marker.getAttribute(EValidator.URI_ATTRIBUTE, null);
final URI uri = uriString == null ? null : URI.createURI(uriString);
if (uri == null) {
return null;
}
return editor.getEditingDomain().getResourceSet().getEObject(uri, false);
}
@SuppressWarnings("unchecked")
private IStatus convertMarker(IMarker marker, EObject target) {
final String message = marker.getAttribute(IMarker.MESSAGE, "");
final String constraintId = marker.getAttribute(MarkerUtil.RULE_ATTRIBUTE, null);
final IConstraintDescriptor icd = constraintId == null ? null : ConstraintRegistry.getInstance().getDescriptor(
constraintId);
final IModelConstraint imc = icd == null ? null : ConstraintFactory.getInstance().newConstraint(icd);
if (imc == null) {
final int severity;
switch (marker.getAttribute(IMarker.SEVERITY, -1)) {
case IMarker.SEVERITY_INFO:
severity = IStatus.INFO;
break;
case IMarker.SEVERITY_WARNING:
severity = IStatus.WARNING;
break;
case IMarker.SEVERITY_ERROR:
severity = IStatus.ERROR;
break;
default:
severity = IStatus.OK;
}
return new Status(severity, Activator.PLUGIN_ID, message);
}
List<?> locus = new EditUIMarkerHelper().getTargetObjects(editor.getEditingDomain(), marker);
for (Iterator<?> it = locus.iterator(); it.hasNext();) {
if (!(it.next() instanceof EObject)) {
it.remove();
}
}
return new ConstraintStatus(imc, target, message, locus == null ? null : new LinkedHashSet<EObject>(
(List<? extends EObject>) locus));
}
}