blob: be1755412d665c48843bf71de986bb2951c5e32d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004-2008 Akos Horvath, Gergely Varro and Daniel Varro
* 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:
* Akos Horvath, Gergely Varro - initial API and implementation
*******************************************************************************/
package org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.viatra2.core.IEntity;
import org.eclipse.viatra2.core.IModelManager;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.exceptions.GTErrorStrings;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.exceptions.GTRuleBuildingException;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateEntity;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateEntityWithConstantContainer;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateEntityWithVariableContainment;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateInstanceofBound2Bound;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateInstanceofBound2Constant;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateInstanceofConstant2Bound;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateInstanceofConstant2Constant;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateRelationBound2Bound;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateRelationBound2Constant;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateRelationConstant2Bound;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateRelationConstant2Constant;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateSuperTypeofBound2Bound;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateSuperTypeofBound2Constant;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateSuperTypeofConstant2Bound;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.CreateSuperTypeofConstant2Constant;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.ElementManipulationOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.IUpdatePlanOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.MoveBoundunderBound;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.MoveBoundunderConstant;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.SetRelationSource;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.gtmatcher.internal.operation.SetRelationTarget;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.EdgeType;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.VPMModelElementType;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.algorithms.ISearchGraph;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.BoundToBoundCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.BoundToConstantCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.ConstantToBoundCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.ConstantToConstantCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.ISearchPlanOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.operation.IsEntityorRelationCheckOperation;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.searchgraph.ConstantSearchGraphNode;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.searchgraph.SearchGraphEdge;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.searchgraph.SearchGraphNode;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.searchgraph.VariableSearchGraphNode;
/**
* Responsible for the generation of the GT rule based operation
* @author Akos Horvath
*/
public class GTOperationGenerator {
/**
* Generates the operation related to the node element, a node can represent a vpm.entity or a vpm.relation
* @param node a node in the search graph
* @param manager the model manager of the VIATRA model space
* @param postSearchPlanOperations a collection that holds the operations related to the consistency of the matching of the rule (injectivity or containment)
* @return a simple operation that is related with the input node element
* @throws GTRuleBuildingException
*/
public static ElementManipulationOperation getModelManipulationOperation(VariableSearchGraphNode node
, IModelManager manager
, ArrayList<ISearchPlanOperation> checkSet
, ISearchGraph searchGraph
)
throws GTRuleBuildingException{
ElementManipulationOperation operation = null;
// if(!node.getTreeEdge().getSourceNode().isChecked() || node.isChecked())
// return null;
//
if(node.getVpmModelElementType().compareTo(VPMModelElementType.ENTITY) == 0)
{
SearchGraphEdge containmentEdge= null;
node.setChecked(true);
//only works when a node has none or only one IN constraint
for(SearchGraphEdge edge : node.getSources()){
if(edge.getVPMEdgeType().compareTo(EdgeType.IN) == 0
&& edge.isSource()
&& !edge.isChecked()
&& edge.getSourceNode().isChecked())
{if(containmentEdge == null)
{containmentEdge = edge;}
else
{
String[] context = {node.getName()};
throw new GTRuleBuildingException(GTErrorStrings.MORE_ONE_IN_CONTAINMENT
,context
,searchGraph.getGTASMRepresentation(node));
}
}
//the element has below containment on it
else if(edge.getVPMEdgeType().compareTo(EdgeType.BELOW) == 0
&& !edge.isChecked()
&& edge.isSource())
{edge.setChecked(true);
// if(!(edge.getSourceNode() instanceof VariableSearchGraphNode
// && edge.getVPMEdgeType().equals(EdgeType.BELOW)
// && (template.getValue(((VariableSearchGraphNode)edge.getSourceNode()).getId()) != null)
// && ((IModelElement)template.getValue(((VariableSearchGraphNode)edge.getSourceNode()).getId())).equals(manager.getRoot())))
// //check that element is below root element is not needed
checkSet.add(getBelowContainmentCheckOperation(manager,edge));
}
}
if(containmentEdge != null)
{containmentEdge.setChecked(true);
if(containmentEdge.getSourceNode() instanceof VariableSearchGraphNode) //variable type container
return new CreateEntityWithVariableContainment(node.getId(),manager,((VariableSearchGraphNode)containmentEdge.getSourceNode()));
else//constant node container
try{
return new CreateEntityWithConstantContainer(node.getId(),manager
,(IEntity)manager.getElementByName(((ConstantSearchGraphNode)containmentEdge.getSourceNode()).getElement())
,(ConstantSearchGraphNode)containmentEdge.getSourceNode());
}catch(ClassCastException e)
{
String[] context = {containmentEdge.getSourceNode().getName()};
throw new GTRuleBuildingException(GTErrorStrings.NOT_CONTAINER
,context
,searchGraph.getGTASMRepresentation(containmentEdge.getSourceNode()));
}
}
else return new CreateEntity(node.getId(),manager);
}
else
if(node.getVpmModelElementType().compareTo(VPMModelElementType.RELATION) == 0)
{SearchGraphNode target = null;
SearchGraphNode source = null;
SearchGraphEdge sourceedge = null;
SearchGraphEdge targetedge = null;
//get the target and the source of the edge
for(SearchGraphEdge edge: node.getSources())
{
if(edge.getVPMEdgeType().compareTo(EdgeType.SOURCE) == 0
&& (!edge.isSource())
&& edge.getSourceNode().isChecked())
{source = edge.getSourceNode();
sourceedge = edge;
}
else
if(edge.getVPMEdgeType().compareTo(EdgeType.TARGET) == 0
&& (!edge.isSource())
&& edge.getSourceNode().isChecked())
{target = edge.getSourceNode();
targetedge = edge;
}
}
// creates a create operation for the relation and connects it to the target and source Elements
if(target != null && source != null)
{
if(source instanceof VariableSearchGraphNode && target instanceof VariableSearchGraphNode)
operation = new CreateRelationBound2Bound(((VariableSearchGraphNode)source).getId()
,((VariableSearchGraphNode)target).getId()
,node.getId()
, manager);
else
if(source instanceof VariableSearchGraphNode && target instanceof ConstantSearchGraphNode )
operation = new CreateRelationBound2Constant(((VariableSearchGraphNode)source).getId()
,(ConstantSearchGraphNode)target
,node.getId()
, manager);
else
if(source instanceof ConstantSearchGraphNode && target instanceof VariableSearchGraphNode)
operation = new CreateRelationConstant2Bound((ConstantSearchGraphNode)source
,((VariableSearchGraphNode)target).getId()
,node.getId()
, manager);
else
if(source instanceof ConstantSearchGraphNode && target instanceof ConstantSearchGraphNode)
operation = new CreateRelationConstant2Constant((ConstantSearchGraphNode)source
,(ConstantSearchGraphNode)target
,node.getId()
, manager);
node.setChecked(true);
sourceedge.setChecked(true);
targetedge.setChecked(true);
return operation;
}
}
return null;
}
/**
* Generated the operation related to the edge input parameter, an edge represents a vpm.relatinship or target/source of a vpm.relation
* @param edge SearchGraphEdge element of the search graph
* @param manager model manager of the VIATRA model space
* @param checkSet a collection that holds the operations related to the consistency of the matching of the rule (injectivity and containment)
* @return a simple operation related to the input edge parameter
* @throws GTRuleBuildingException
*/
public static ElementManipulationOperation getModelManipulationOperation(SearchGraphEdge edge
,IModelManager manager
,ArrayList<ISearchPlanOperation> checkSet
, ISearchGraph searchGraph)
throws GTRuleBuildingException {
ElementManipulationOperation operation = null;
if( (!edge.getSourceNode().isChecked()) || !edge.getTargetNode().isChecked())
return null;
//supertypeof, traversed on the inverse edge
if(edge.getVPMEdgeType().compareTo(EdgeType.SUPERTYPEOF) == 0
&& !edge.isSource())
//TODO: have to change to handle input parameters supertype change
{
// cannot create SupertypeOf Relationships to vpm Entities or Relations
if(edge.getTargetNode() instanceof ConstantSearchGraphNode &&
( ((ConstantSearchGraphNode)edge.getTargetNode()).getElement().equals(ISearchGraph.VPM_RELATION_FQN)
|| ((ConstantSearchGraphNode)edge.getTargetNode()).getElement().equals(ISearchGraph.VPM_ENTITY_FQN) )
)
{
edge.setChecked(true);
return null;
}
if(edge.getSourceNode() instanceof VariableSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
operation = new CreateSuperTypeofBound2Bound(((VariableSearchGraphNode)edge.getSourceNode()).getId()
,((VariableSearchGraphNode) edge.getTargetNode()).getId()
, manager,edge);
else
if(edge.getSourceNode() instanceof VariableSearchGraphNode && edge.getTargetNode() instanceof ConstantSearchGraphNode )
operation = new CreateSuperTypeofBound2Constant(((VariableSearchGraphNode)edge.getSourceNode()).getId()
,manager.getElementByName(((ConstantSearchGraphNode)edge.getTargetNode()).getElement())
, manager,edge);
else
if(edge.getSourceNode() instanceof ConstantSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
operation = new CreateSuperTypeofConstant2Bound(manager.getElementByName(((ConstantSearchGraphNode)edge.getSourceNode()).getElement())
,((VariableSearchGraphNode) edge.getTargetNode()).getId()
, manager,edge);
else
if(edge.getSourceNode() instanceof ConstantSearchGraphNode && edge.getTargetNode() instanceof ConstantSearchGraphNode)
operation = new CreateSuperTypeofConstant2Constant(manager.getElementByName(((ConstantSearchGraphNode)edge.getSourceNode()).getElement())
,manager.getElementByName(((ConstantSearchGraphNode)edge.getTargetNode()).getElement())
, manager,edge);
edge.setChecked(true);
return operation;
}
//instanceof
if(edge.getVPMEdgeType().compareTo(EdgeType.INSTANCEOF) == 0
&& edge.isSource())
{
//cannot create instanceOF Relationships to vpm Entities or Relations
if(edge.getSourceNode() instanceof ConstantSearchGraphNode &&
(((ConstantSearchGraphNode)edge.getSourceNode()).getElement().equals(ISearchGraph.VPM_RELATION_FQN)
|| ((ConstantSearchGraphNode)edge.getSourceNode()).getElement().equals(ISearchGraph.VPM_ENTITY_FQN))
)
{
edge.setChecked(true);
return null;
}
if(edge.getSourceNode() instanceof VariableSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
operation = new CreateInstanceofBound2Bound(((VariableSearchGraphNode)edge.getSourceNode()).getId()
,((VariableSearchGraphNode) edge.getTargetNode()).getId()
, manager,edge);
else
if(edge.getSourceNode() instanceof VariableSearchGraphNode && edge.getTargetNode() instanceof ConstantSearchGraphNode )
operation = new CreateInstanceofBound2Constant(((VariableSearchGraphNode)edge.getSourceNode()).getId()
,manager.getElementByName(((ConstantSearchGraphNode) edge.getTargetNode()).getElement())
, manager,edge);
else
if(edge.getSourceNode() instanceof ConstantSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
operation = new CreateInstanceofConstant2Bound(manager.getElementByName(((ConstantSearchGraphNode)edge.getSourceNode()).getElement())
,((VariableSearchGraphNode) edge.getTargetNode()).getId()
, manager,edge);
else
if(edge.getSourceNode() instanceof ConstantSearchGraphNode && edge.getTargetNode() instanceof ConstantSearchGraphNode)
operation = new CreateInstanceofConstant2Constant(manager.getElementByName(((ConstantSearchGraphNode)edge.getSourceNode()).getElement())
,manager.getElementByName(((ConstantSearchGraphNode) edge.getTargetNode()).getElement())
, manager,edge);
edge.setChecked(true);
return operation;
}
if(edge.getVPMEdgeType().compareTo(EdgeType.BELOW) == 0
&& edge.isSource())
{
checkSet.add(getBelowContainmentCheckOperation(manager,edge));
//Debug
//logger.debug("Containment Check Below "+edge.getSourceNode().getName()+" below "+edge.getSourceNode().getName());
//if move is needed for input parameters than this line have to be changed
edge.setChecked(true);
}
if(edge.getVPMEdgeType().compareTo(EdgeType.IN) == 0
&& edge.isSource())
{
try{
if(edge.getSourceNode() instanceof ConstantSearchGraphNode)
operation = new MoveBoundunderConstant(manager
,(IEntity)manager.getElementByName(((ConstantSearchGraphNode)edge.getSourceNode()).getElement())
,((VariableSearchGraphNode)edge.getTargetNode()).getId()
,edge);
else
if(edge.getSourceNode() instanceof VariableSearchGraphNode)
operation = new MoveBoundunderBound(manager
,((VariableSearchGraphNode)edge.getSourceNode()).getId()
,((VariableSearchGraphNode)edge.getTargetNode()).getId()
,edge);
edge.setChecked(true);
return operation;
}catch(ClassCastException e)
{
String[] context = {edge.getSourceNode().getName()};
throw new GTRuleBuildingException(GTErrorStrings.NOT_CONTAINER
,context
,searchGraph.getGTASMRepresentation(edge.getSourceNode()));
}
}
//
// if(edge.getVPMEdgeType().compareTo(EdgeType.SOURCE) ==0
// || edge.getVPMEdgeType().compareTo(EdgeType.TARGET) ==0)
// {//Debug
// System.out.println("Relation "+edge.getName());
// }
//target and source (this cannot be processed as it is connected to the Relation searchgraph node creation
return null;
}
/**
* Generates containment check operation represented by the edge input parameter
* @param manager model manager of the viatra model space
* @param edge a containment edge in the search graph
* @return the containment check operation based on the edge input param
*/
public static ISearchPlanOperation getBelowContainmentCheckOperation(IModelManager manager,SearchGraphEdge edge) {
ISearchPlanOperation sop = null;
if(edge.getSourceNode() instanceof VariableSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
sop = new BoundToBoundCheckOperation(((VariableSearchGraphNode)edge.getSourceNode()).getId()
,((VariableSearchGraphNode)edge.getTargetNode()).getId()
,edge);
else
if(edge.getSourceNode() instanceof VariableSearchGraphNode && edge.getTargetNode() instanceof ConstantSearchGraphNode )
sop = new BoundToConstantCheckOperation(((VariableSearchGraphNode)edge.getSourceNode()).getId()
,manager.getElementByName(((ConstantSearchGraphNode)edge.getTargetNode()).getElement())
,edge);
else
if(edge.getSourceNode() instanceof ConstantSearchGraphNode && edge.getTargetNode() instanceof VariableSearchGraphNode)
sop = new ConstantToBoundCheckOperation(manager.getElementByName(((ConstantSearchGraphNode)edge.getSourceNode()).getElement())
,((VariableSearchGraphNode)edge.getTargetNode()).getId()
,edge);
else
if(edge.getSourceNode() instanceof ConstantSearchGraphNode && edge.getTargetNode() instanceof ConstantSearchGraphNode)
sop = new ConstantToConstantCheckOperation(manager.getElementByName(((ConstantSearchGraphNode)edge.getSourceNode()).getElement())
,manager.getElementByName(((ConstantSearchGraphNode)edge.getTargetNode()).getElement())
,edge);
return sop;}
/** Generates operation related to bound input parameters for the RHS.
* @param node The input search graph node
* @param manager Model manager of the model space
* @param checkSet Collection containing the check operation for the RHS
* @return The model manipulation operations related to the input node.
*/
public static Collection<IUpdatePlanOperation> getInputSpecificOperation(VariableSearchGraphNode node
, IModelManager manager,
ArrayList<ISearchPlanOperation> checkSet) {
Collection<IUpdatePlanOperation> operations = new ArrayList<IUpdatePlanOperation>();
for(SearchGraphEdge edge : node.getSources()){
/** Check Operations*/
//constant instance of relation on a variable from the lhs
if(edge.getVPMEdgeType().compareTo(EdgeType.INSTANCEOF) == 0
&& edge.isSource()
&& edge.getSourceNode() instanceof ConstantSearchGraphNode)
{
//specific operation required when the type is vpm.entity or vpm.relation
if(((ConstantSearchGraphNode)edge.getSourceNode()).getElement().equals(ISearchGraph.VPM_RELATION_FQN)
|| ((ConstantSearchGraphNode)edge.getSourceNode()).getElement().equals(ISearchGraph.VPM_ENTITY_FQN))
{
ISearchPlanOperation op = new IsEntityorRelationCheckOperation(node.getId()
,edge,
((ConstantSearchGraphNode)edge.getSourceNode()).getElement());
checkSet.add(op);
}
else
{
ISearchPlanOperation op = new ConstantToBoundCheckOperation(
manager.getElementByName(((ConstantSearchGraphNode) edge.getSourceNode()).getElement()),
node.getId(),
edge);
checkSet.add(op);
}
edge.setChecked(true);
edge.getSourceNode().setChecked(true);
}
//constant Supertype relation to an input parameter which is from the lhs pattern
else
if(edge.getVPMEdgeType().compareTo(EdgeType.SUPERTYPEOF) == 0
&& !edge.isSource()
&& edge.getSourceNode() instanceof ConstantSearchGraphNode)
{
if(((ConstantSearchGraphNode)edge.getSourceNode()).getElement().equals(ISearchGraph.VPM_RELATION_FQN)
|| ((ConstantSearchGraphNode)edge.getSourceNode()).getElement().equals(ISearchGraph.VPM_ENTITY_FQN))
{
ISearchPlanOperation op = new IsEntityorRelationCheckOperation(node.getId()
,edge,
((ConstantSearchGraphNode)edge.getSourceNode()).getElement());
checkSet.add(op);
}
else
{
ISearchPlanOperation op = new ConstantToBoundCheckOperation(
manager.getElementByName(((ConstantSearchGraphNode) edge.getSourceNode()).getElement()),
node.getId(),edge);
checkSet.add(op);
}
edge.setChecked(true);
edge.getSourceNode().setChecked(true);
}
else
//the relation is bound and only its source and target entites will have to be (re)set
if(edge.getVPMEdgeType().compareTo(EdgeType.TARGET) == 0
&& !edge.isSource()
&& edge.getSourceNode() instanceof VariableSearchGraphNode
&& node.getVpmModelElementType().equals(VPMModelElementType.RELATION))
{
IUpdatePlanOperation op = new SetRelationTarget(node.getId()
,((VariableSearchGraphNode)edge.getSourceNode()).getId()
,manager
,edge);
operations.add(op);
edge.setChecked(true);
}
else
if(edge.getVPMEdgeType().compareTo(EdgeType.SOURCE) == 0
&& !edge.isSource()
&& edge.getSourceNode() instanceof VariableSearchGraphNode
&& node.getVpmModelElementType().equals(VPMModelElementType.RELATION))
{
IUpdatePlanOperation op = new SetRelationSource(node.getId()
,((VariableSearchGraphNode)edge.getSourceNode()).getId()
,manager
,edge);
operations.add(op);
edge.setChecked(true);
}
}
return operations;
}
}