blob: 1dcc277a7bbe4bfb2ee9b9bd7e370cfb3469194e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014-2016 IncQuery Labs Ltd.
* 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, Abel Hegedus, Marton Bur, Zoltan Ujhelyi - initial API and implementation
*******************************************************************************/
package org.eclipse.viatra.examples.cps.xform.m2m.incr.qrt.rules
import org.eclipse.viatra.examples.cps.xform.m2m.incr.qrt.queries.Transition
import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
import org.eclipse.viatra.transformation.evm.specific.Jobs
import org.eclipse.viatra.transformation.evm.specific.Lifecycles
import org.eclipse.viatra.transformation.evm.specific.Rules
import org.eclipse.viatra.transformation.evm.specific.crud.CRUDActivationStateEnum
import org.eclipse.viatra.examples.cps.deployment.DeploymentApplication
import org.eclipse.viatra.examples.cps.deployment.BehaviorTransition
class TransitionRules {
static def getRules(ViatraQueryEngine engine) {
#{
new TransitionMapping(engine).specification
}
}
}
class TransitionMapping extends AbstractRule<Transition.Match> {
new(ViatraQueryEngine engine) {
super(engine)
}
override getSpecification() {
createPriorityRuleSpecification => [
ruleSpecification = Rules.newMatcherRuleSpecification(transition, Lifecycles.getDefault(true, true),
#{appearedJob, updateJob, disappearedJob})
priority = 5
]
}
private def getAppearedJob() {
Jobs.newStatelessJob(CRUDActivationStateEnum.CREATED,
[ Transition.Match match |
addTransition(match)
])
}
private def addTransition(Transition.Match match) {
val depApp = engine.cps2depTrace.getAllValuesOfdepElement(null, null, match.appInstance).filter(
DeploymentApplication).head
val transition = match.transition
val transitionId = transition.identifier
debug('''Mapping transition with ID: «transitionId»''')
val depTransition = createBehaviorTransition => [
description = transitionId
]
depApp.behavior.transitions += depTransition
val tempDepSources = engine.cps2depTrace.getAllValuesOfdepElement(null, null, match.srcState);
val depSource = depApp.behavior.states.findFirst[tempDepSources.contains(it)]
depSource.outgoing += depTransition
val tempDepTargets = engine.cps2depTrace.getAllValuesOfdepElement(null, null,
match.transition.targetState);
val depTarget = depApp.behavior.states.findFirst[tempDepTargets.contains(it)]
depTransition.to = depTarget
val traces = engine.cps2depTrace.getAllValuesOftrace(null, transition, null)
if (traces.empty) {
trace('''Creating new trace for transition ''')
rootMapping.traces += createCPS2DeploymentTrace => [
cpsElements += transition
deploymentElements += depTransition
]
} else {
trace('''Adding new transition to existing trace''')
traces.head.deploymentElements += depTransition
}
debug('''Mapped transition with ID: «transitionId»''')
}
private def getUpdateJob() {
Jobs.newStatelessJob(CRUDActivationStateEnum.UPDATED,
[ Transition.Match match |
val transition = match.transition
val trId = transition.identifier
debug('''Updating mapped transition with ID: «trId»''')
val depApp = engine.cps2depTrace.getAllValuesOfdepElement(null, null, match.appInstance).filter(
DeploymentApplication).head
val depTransitions = engine.cps2depTrace.getAllValuesOfdepElement(null, null, transition).filter(
BehaviorTransition).toSet
val depTransition = depApp.behavior.transitions.findFirst[depTransitions.contains(it)]
val oldDesc = depTransition.description
if (oldDesc != trId) {
trace('''ID changed to «oldDesc»''')
depTransition.description = trId
}
val tempDepSources = engine.cps2depTrace.getAllValuesOfdepElement(null, null, match.srcState)
val depSource = depApp.behavior.states.findFirst[tempDepSources.contains(it)]
val tempDepTargets = engine.cps2depTrace.getAllValuesOfdepElement(null, null,
match.transition.targetState);
val depTarget = depApp.behavior.states.findFirst[tempDepTargets.contains(it)]
if (!depSource.outgoing.contains(depTransition)) {
trace('''Source state changed to «depSource.description»''')
depSource.outgoing += depTransition
}
if (depTransition.to != depTarget) {
trace('''Target state changed to «depTarget.description»''')
depTransition.to = depTarget
}
debug('''Updated mapped transition with ID: «trId»''')
])
}
private def getDisappearedJob() {
Jobs.newStatelessJob(CRUDActivationStateEnum.DELETED,
[ Transition.Match match |
deleteTransition(match)
])
}
private def deleteTransition(Transition.Match match) {
val transition = match.transition
val depApp = engine.cps2depTrace.getAllValuesOfdepElement(null, null, match.appInstance).filter(
DeploymentApplication).head
val depTransitions = engine.cps2depTrace.getAllValuesOfdepElement(null, null, transition).filter(
BehaviorTransition).toSet
val depTransition = engine.depBehaviorsStateAndTransitions.getAllValuesOfdepTransition(depApp.behavior, null).
findFirst[depTransitions.contains(it)]
val trId = depTransition.description
logger.debug('''Removing transition with ID: «trId»''')
depTransition.to = null
val tempDepSources = engine.cps2depTrace.getAllValuesOfdepElement(null, null, match.srcState)
val depSource = depApp.behavior.states.findFirst[tempDepSources.contains(it)]
depSource?.outgoing -= depTransition;
depApp.behavior.transitions -= depTransition
val smTrace = engine.cps2depTrace.getAllValuesOftrace(null, transition, null).head
smTrace.deploymentElements -= depTransition
if (smTrace.deploymentElements.empty) {
trace('''Removing empty trace''')
rootMapping.traces -= smTrace
}
logger.debug('''Removed transition with ID: «trId»''')
}
}