blob: 7bce74511c28f83d5c49745bf1dfc8a8a3d3dc6f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 protos software gmbh (http://www.protos.de).
* 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:
* Henrik Rentz-Reichert (initial contribution)
*
*******************************************************************************/
package org.eclipse.etrice.core.genmodel.fsm
import com.google.inject.Inject
import org.eclipse.etrice.core.fsm.fSM.ChoicepointTerminal
import org.eclipse.etrice.core.fsm.fSM.ModelComponent
import org.eclipse.etrice.core.fsm.fSM.NonInitialTransition
import org.eclipse.etrice.core.fsm.fSM.StateGraph
import org.eclipse.etrice.core.fsm.fSM.StateGraphNode
import org.eclipse.etrice.core.fsm.fSM.StateTerminal
import org.eclipse.etrice.core.fsm.fSM.SubStateTrPointTerminal
import org.eclipse.etrice.core.fsm.fSM.TrPointTerminal
import org.eclipse.etrice.core.fsm.fSM.Transition
import org.eclipse.etrice.core.fsm.util.FSMHelpers
import org.eclipse.etrice.core.genmodel.fsm.fsmgen.FsmGenFactory
import org.eclipse.etrice.core.genmodel.fsm.fsmgen.Graph
import org.eclipse.etrice.core.genmodel.fsm.fsmgen.GraphContainer
import org.eclipse.etrice.core.fsm.fSM.State
import org.eclipse.etrice.core.fsm.fSM.RefinedState
import org.eclipse.etrice.core.fsm.fSM.SimpleState
import org.eclipse.etrice.core.genmodel.fsm.fsmgen.Node
import com.google.inject.Injector
import org.eclipse.etrice.core.fsm.fSM.RefinedTransition
class FsmGenBuilder {
@Inject extension FSMHelpers fsmHelpers
val factory = FsmGenFactory.eINSTANCE
new(Injector injector) {
injector.injectMembers(this)
}
def GraphContainer createTransformedModel(ModelComponent mc) {
mc.createContainer
}
private def GraphContainer create factory.createGraphContainer createContainer(ModelComponent mc) {
it.component = mc
it.graph = createStateMachine(mc)
}
private def Graph createStateMachine(ModelComponent mc) {
// neither we nor all of our base classes need to have a state machine.
// So we ask for the super state machine rather than for the base class'
// state machine
val superFSM = mc.superStateMachine
if (superFSM!=null) {
// if we have a super state machine we first recurse down
val baseGraph = createStateMachine(superFSM.modelComponent)
// and then merge with our (actual) state machine
mergeGraph(baseGraph, mc.actualStateMachine)
}
else {
// first state machine in the hierarchy: create it
mc.actualStateMachine.createGraph
}
}
private def Graph mergeGraph(Graph graph, StateGraph sg) {
// mark existing items as inherited
graph.nodes.forEach[inherited = true]
graph.links.forEach[inherited = true]
// add items to already existing graph
graph.createContents(sg)
// point to the current state graph
graph.stateGraph = sg
return graph
}
private def create factory.createGraph createGraph(StateGraph sg) {
it.stateGraph = sg
createContents(sg)
}
private def createContents(Graph graph, StateGraph sg) {
graph.nodes.addAll(sg.chPoints.map[createNode])
graph.nodes.addAll(sg.trPoints.map[createNode])
graph.nodes.addAll(sg.states.filter(typeof(SimpleState)).map[createNode])
graph.links.addAll(sg.transitions.map[createLink])
// refined states and transitions
sg.states.filter(typeof(RefinedState)).forEach[handleRefinedState]
sg.refinedTransitions.forEach[handleRefinedTransition]
}
private def handleRefinedState(RefinedState s) {
// handle the sub graphs
if (s.subgraph!=null) {
if (s.target.subgraph!=null) {
val targetGraph = s.target.subgraph.createGraph
targetGraph.mergeGraph(s.subgraph)
}
else {
s.target.createNode.subgraph = s.subgraph.createGraph
}
}
// else nothing to do, whether the targetGraph exist or not
// change the target Node's stateGraphNode to our RefinedState
val target = s.target.createNode
target.stateGraphNode = s
}
private def handleRefinedTransition(RefinedTransition t) {
// change the target link's transition to the refined transition
t.target.createLink.transition = t
}
private def create factory.createLink createLink(Transition tr) {
it.transition = tr
it.source = if (tr instanceof NonInitialTransition) {
tr.from.createNode
}
else {
null
}
it.target = tr.to.createNode
}
private def dispatch create factory.createNode createNode(StateGraphNode s) {
it.stateGraphNode = s
it.subgraph =
if (s instanceof State && (s as State).subgraph!=null) {
(s as State).subgraph.createGraph
}
else null
}
private def dispatch Node createNode(ChoicepointTerminal tt) {
tt.cp.createNode
}
private def dispatch Node createNode(TrPointTerminal tt) {
tt.trPoint.createNode
}
private def dispatch Node createNode(StateTerminal tt) {
tt.state.createNode
}
private def dispatch Node createNode(SubStateTrPointTerminal tt) {
tt.trPoint.createNode
}
}