blob: f5817798ebc0fd26ec20bd708e2746ba6d2267f5 [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.Collection;
import org.eclipse.viatra2.gtasm.interpreter.exception.ViatraTransformationException;
import org.eclipse.viatra2.gtasm.patternmatcher.ParameterMode;
import org.eclipse.viatra2.gtasm.patternmatcher.PatternCallSignature;
import org.eclipse.viatra2.gtasm.patternmatcher.exceptions.PatternMatcherCompileTimeException;
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.patternmatcher.internal.MatchingFrame;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.PatternMatcher;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.internal.callgraph.FlattenedPattern;
import org.eclipse.viatra2.gtasm.patternmatcher.impl.patternmatcher.term.ITermHandler;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.ValueKind;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTPattern;
import org.eclipse.viatra2.core.IModelManager;
import org.eclipse.viatra2.logger.Logger;
/**Specific PatternMatcher for the RHS of a GTRule.
* Used to create the search graph of the pattern and then generate the according operations
* @author Akos Horvath and Gergely Varro
*
*/
public class RightHandSideMatcher extends PatternMatcher {
//private IModelElement[] scopeMapping;
private FlattenedPattern flattenedPattern;
RightHandSideMatcher(GTPattern pattern, Logger logger, IModelManager manager, ITermHandler termHandler)
throws ViatraTransformationException {
// Flattening is executed in the constructor of the superclass (PatternMatcher)
super(pattern,logger,manager,termHandler);
try{
flattenedPattern = root.getSingleFlattenedPattern();
}catch(PatternMatcherCompileTimeException e ){
throw e.addNewStackElement(pattern);
}
// Scope handling removed
// flattenedPattern.getSearchGraph().addScope(pattern, flattenedPattern.getFrameSize());
//scopeMapping = new IModelElement[pattern.getSymParameters().size()];
}
/** Returns the MatchingFrame with the already bound parameters.
* @param gtElementMappings The mapping the LHS and RHS elements
* @param inputMapping the input variable values
* @param signature signatures of the rhs input parameters
* @return
* @throws GTRuleBuildingException
*/
public MatchingFrame generateMatchingFrameofInputContext(Collection<GTElementMapping> gtElementMappings,
Object[] inputMapping,
PatternCallSignature[] signature
) throws GTRuleBuildingException
{
if (inputMapping.length != signature.length)
{
throw new GTRuleBuildingException(GTErrorStrings.INTERNAL_ERROR_INPUTPARAMS_SYMPARAMS_LENGTH
,null
,null);
}
MatchingFrame template = new MatchingFrame(flattenedPattern);
// Input processing
for (int i = 0; i < inputMapping.length; i++)
{
if (signature[i].getParameterMode() == ParameterMode.OUTPUT) {
if (inputMapping[i] == null || inputMapping[i].equals(ValueKind.UNDEF_LITERAL)) {
// Output parameter without value: do nothing
} else {
// Output parameter with value: a possible bug in the code
logger.debug("Parameter " + i +
" is an output parameter with value " +
inputMapping[i].toString());
}
} else if (signature[i].getParameterMode() == ParameterMode.INPUT) {
if (inputMapping[i] != null) {
// Input parameter with value: test and set the value
template.testAndSetValue(i, inputMapping[i]);
} else {
// Input parameter without value: throw an exception
throw new GTRuleBuildingException(GTErrorStrings.INTERNAL_ERROR_INPUTPARAM_WITHOUT_A_VALUE
,null
,null);
}
}
}
// Input scope processing
/* boolean[] inConstraints = flattenedPattern.getSearchGraph().hasinputParameterINContstraint();
Vector<IUpdatePlanOperation> operations = new Vector<IUpdatePlanOperation>();
Vector<ISearchPlanOperation> checkSet = new Vector<ISearchPlanOperation>();
for (int i = 0; i < inputMapping.length; i++) {
if(!(signature[i].getParameterScope().getParent().equals(Scope.DEFAULT_PARENT)
&& signature[i].getParameterScope().getContainmentMode().equals(Scope.DEFAULT_MODE)))
{IModelElement element = signature[i].getParameterScope().getParent();
if (element != null)
{
if(signature[i].getParameterScope().getContainmentMode().compareTo(Scope.IN) == 0)
{
if(inConstraints[i])
throw new GTRuleBuildingException(GTErrorStrings.MORE_ONE_IN_CONTAINMENT);
else // have to move the element under the container
{
operations.add(new MoveBoundunderConstant(manager,
(IEntity)element, i));
}
}
else // below type containment constraint
{
checkSet.add(new GTBelowContainmentCheckBoundUnderConstant(i,
signature[i].getParameterScope().getParent()));
}
}
// template.setValue(frameSize + i, element);}
else{
// Input parameter scope without value: throw an exception
throw new GTRuleBuildingException("Input parameter scope " + i + " does not have a value.");
}
}
}*/
return template;
}
public GTOperationContext generateGTOperation(Collection<GTElementMapping> gtElementMappings,
//Object[] inputMapping,
PatternCallSignature[] signature
//Vector<RelationShipMapping> relationShipMapping
) throws GTRuleBuildingException {
GTOperationContext finalOperations =
flattenedPattern.getSearchGraph().generateGTOperations(gtElementMappings, manager, signature);
return finalOperations;
}
}