blob: 50267c5bd6909a4a59bfe0431ac28e04b061ee1f [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2008 E.D.Willink and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* E.D.Willink - initial API and implementation
*
* </copyright>
*
* $Id: RelationDomainOperations.java,v 1.2 2009/01/14 21:02:27 ewillink Exp $
*/
package org.eclipse.qvt.declarative.ecore.QVTRelation.operations;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.ocl.ecore.OCLExpression;
import org.eclipse.ocl.ecore.Variable;
import org.eclipse.ocl.ecore.VariableExp;
import org.eclipse.qvt.declarative.ecore.QVTBase.Domain;
import org.eclipse.qvt.declarative.ecore.QVTBase.Rule;
import org.eclipse.qvt.declarative.ecore.QVTBase.operations.DomainOperations;
import org.eclipse.qvt.declarative.ecore.QVTRelation.DomainPattern;
import org.eclipse.qvt.declarative.ecore.QVTRelation.Relation;
import org.eclipse.qvt.declarative.ecore.QVTRelation.RelationCallExp;
import org.eclipse.qvt.declarative.ecore.QVTRelation.RelationDomain;
import org.eclipse.qvt.declarative.ecore.QVTRelation.RelationDomainAssignment;
import org.eclipse.qvt.declarative.ecore.QVTTemplate.CollectionTemplateExp;
import org.eclipse.qvt.declarative.ecore.QVTTemplate.ObjectTemplateExp;
import org.eclipse.qvt.declarative.ecore.QVTTemplate.PropertyTemplateItem;
public class RelationDomainOperations extends DomainOperations
{
public static RelationDomainOperations INSTANCE = new RelationDomainOperations();
/**
* Validates the PrimitiveDomainIsUnnamed constraint of '<em>Relation Domain</em>'.
*/
public boolean checkPrimitiveDomainIsUnnamed(RelationDomain relationDomain, DiagnosticChain diagnostics, Map<Object, Object> context) {
if (relationDomain.getPattern() != null)
return true;
if (relationDomain.getName() == null)
return true;
Object[] messageSubstitutions = new Object[] { getObjectLabel(relationDomain, context) };
appendError(diagnostics, relationDomain, QVTRelationMessages._UI_RelationDomain_PrimitiveDomainMustBeUnnamed, messageSubstitutions);
return false;
}
/**
* Validates the RootVariableIsDefinedByRelation constraint of '<em>Relation Domain</em>'.
*/
public boolean checkRootVariableIsDefinedByRelation(RelationDomain relationDomain, DiagnosticChain diagnostics, Map<Object, Object> context) {
Variable rootVariable = relationDomain.getRootVariable();
if (rootVariable == null)
return true; // Multiplicity failure
Rule rule = relationDomain.getRule();
if (!(rule instanceof Relation))
return true; // Relation checks its domains
if (RelationOperations.INSTANCE.definesVariable((Relation) rule, rootVariable))
return true;
Object[] messageSubstitutions = new Object[] { getObjectLabel(rootVariable, context), getObjectLabel(rule, context) };
appendError(diagnostics, relationDomain, QVTRelationMessages._UI_RelationDomain_RootVariableIsNotDefinedByRelation, messageSubstitutions);
return false;
}
/**
* Validates the RootVariableTypeIsDeclaredByDomainTypedModel constraint of '<em>Relation Domain</em>'.
*/
public boolean checkRootVariableTypeIsDeclaredByDomainTypedModel(RelationDomain relationDomain, DiagnosticChain diagnostics, Map<Object, Object> context) {
Variable rootVariable = relationDomain.getRootVariable();
if (rootVariable == null)
return true; // Multiplicity failure
EClassifier type = getTransitiveElementType(rootVariable.getEType());
if (type == null)
return true; // Multiplicity failure
if (declaresType(relationDomain, type))
return true; // Relation checks its domains
Object[] messageSubstitutions = new Object[] { getObjectLabel(type, context), getObjectLabel(rootVariable, context), getObjectLabel(relationDomain, context) };
appendError(diagnostics, relationDomain, QVTRelationMessages._UI_RelationDomain_RootVariableTypeIsNotDeclaredByDomainTypedModel, messageSubstitutions);
return false;
}
/**
* Validates the EveryEnforceableVariableIsMatchedOrAssigned constraint of '<em>Relation Domain</em>'.
*/
public boolean checkEveryEnforceableVariableIsMatchedOrAssigned(RelationDomain relationDomain, DiagnosticChain diagnostics, Map<Object, Object> context) {
if (!relationDomain.isIsEnforceable())
return true;
Set<Variable> sharedVariables = new HashSet<Variable>();
Set<Variable> passedVariables = new HashSet<Variable>();
Set<Variable> collectedVariables = new HashSet<Variable>();
Set<Variable> defaultedVariables = new HashSet<Variable>();
Map<Variable,Set<EStructuralFeature>> matchedVariableFeatures = new HashMap<Variable,Set<EStructuralFeature>>();
for (Domain domain : relationDomain.getRule().getDomain())
if ((domain != relationDomain) && (domain instanceof RelationDomain)) {
DomainPattern pattern = ((RelationDomain) domain).getPattern();
if (pattern != null)
sharedVariables.addAll(pattern.getBindsTo());
}
for (TreeIterator<EObject> i = relationDomain.eAllContents(); i.hasNext(); ) {
EObject eObject = i.next();
if (eObject instanceof RelationCallExp) {
for (OCLExpression argument : ((RelationCallExp)eObject).getArgument()) {
if (argument instanceof VariableExp)
passedVariables.add((Variable) ((VariableExp)argument).getReferredVariable());
}
}
else if (eObject instanceof ObjectTemplateExp) {
ObjectTemplateExp templateExp = (ObjectTemplateExp)eObject;
Variable templateVariable = templateExp.getBindsTo();
Set<EStructuralFeature> matchedFeatures = matchedVariableFeatures.get(templateVariable);
if (matchedFeatures == null) {
matchedFeatures = new HashSet<EStructuralFeature>();
matchedVariableFeatures.put(templateVariable, matchedFeatures);
}
for (PropertyTemplateItem part : templateExp.getPart())
matchedFeatures.add(part.getReferredProperty());
}
else if (eObject instanceof CollectionTemplateExp) {
CollectionTemplateExp templateExp = (CollectionTemplateExp)eObject;
collectedVariables.add(templateExp.getBindsTo());
}
else if (eObject instanceof RelationDomainAssignment) {
RelationDomainAssignment assignment = (RelationDomainAssignment)eObject;
defaultedVariables.add(assignment.getVariable());
}
}
boolean allOk = true;
/* for (Variable boundVariable : relationDomain.getPattern().getBindsTo()) {
if (!sharedVariables.contains(boundVariable)
&& !passedVariables.contains(boundVariable)
&& !collectedVariables.contains(boundVariable)
&& !defaultedVariables.contains(boundVariable)) {
Set<EStructuralFeature> matchedFeatures = matchedVariableFeatures.get(boundVariable);
if (matchedFeatures == null) {
allOk = false;
Object[] messageSubstitutions = new Object[] { boundVariable.getName(), getObjectLabel(relationDomain, context) };
appendWarning(diagnostics, boundVariable, QVTRelationMessages._UI_RelationDomain_BoundVariableIsNotDefinedByEnforceableDomain, messageSubstitutions);
}
else {
for (EStructuralFeature feature : boundVariable.getEType().eClass().getEAllStructuralFeatures()) {
if (!matchedFeatures.contains(feature) && feature.isRequired()) {
allOk = false;
Object[] messageSubstitutions = new Object[] { boundVariable.getName(), feature.getName(), getObjectLabel(relationDomain, context) };
appendWarning(diagnostics, boundVariable, QVTRelationMessages._UI_RelationDomain_BoundVariableFeatureIsNotDefinedByEnforceableDomain, messageSubstitutions);
}
}
}
}
} */
return allOk;
}
}