blob: 0013e7569b18a658d0ab1beb3dfd524c1b54b10e [file] [log] [blame]
package org.eclipse.uml2.diagram.common.validation;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.util.EcoreUtil.CrossReferencer;
import org.eclipse.emf.validation.AbstractModelConstraint;
import org.eclipse.emf.validation.IValidationContext;
import org.eclipse.gmf.runtime.common.core.util.StringStatics;
import org.eclipse.ocl.ParserException;
import org.eclipse.ocl.uml.OCL;
import org.eclipse.ocl.uml.OCL.Helper;
import org.eclipse.uml2.diagram.common.constraint.ConstraintUtils;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Stereotype;
public class OCLFromStereoConstraint extends AbstractModelConstraint {
final private OCL myOCL = org.eclipse.ocl.uml.OCL.newInstance();
@Override
public IStatus validate(IValidationContext ctx) {
Element selected = (Element) ctx.getTarget();
Helper oclHelper = myOCL.createOCLHelper();
for (Stereotype stereo : selected.getApplicableStereotypes()) {
oclHelper.setContext(stereo);
for (Constraint c : getConstraints(stereo)) {
try {
boolean success = runConstraintOn(oclHelper, selected, c);
if (!success) {
String name = (selected instanceof NamedElement) ? ((NamedElement) selected).getName() : StringStatics.BLANK;
return ctx.createFailureStatus(name, stereo.getName(), c.getName());
}
} catch (ParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return ctx.createSuccessStatus();
}
private boolean runConstraintOn(Helper oclHelper, Element selected, Constraint umlConstraint) throws ParserException {
String body = ConstraintUtils.getOCLConstraintBody(umlConstraint);
if (body == null) {
return true;
}
Constraint constraint = oclHelper.createInvariant(body);
return myOCL.check(selected, constraint);
}
private static final List<Constraint> getConstraints(EObject stereotype) {
LinkedList<Constraint> result = new LinkedList<Constraint>();
for (EObject next : getReferencingObjects(stereotype)) {
if (isConstraintFor(next, stereotype)) {
result.add((Constraint) next);
}
}
return result;
}
private static boolean isConstraintFor(EObject constraint, EObject constrainedElement) {
return constraint instanceof Constraint && ((Constraint) constraint).getConstrainedElements().contains(constrainedElement);
}
private static final List<EObject> getReferencingObjects(EObject target) {
LinkedList<EObject> result = new LinkedList<EObject>();
Collection<EStructuralFeature.Setting> settings = CrossReferencer.find(target.eResource().getContents()).get(target);
if (settings == null) {
return Collections.emptyList();
}
for (Setting setting : settings) {
result.add(setting.getEObject());
}
return result;
}
}