aboutsummaryrefslogtreecommitdiffstats
path: root/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse/CpsStateCoder.xtend
blob: 223cee031fece51c2b9bda7d3e9da111a410f123 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package hu.bme.mit.inf.dslreasoner.domains.cps.dse

import hu.bme.mit.inf.dslreasoner.domains.cps.ApplicationInstance
import hu.bme.mit.inf.dslreasoner.domains.cps.CyberPhysicalSystem
import hu.bme.mit.inf.dslreasoner.domains.cps.HostInstance
import hu.bme.mit.inf.dslreasoner.domains.cps.HostType
import hu.bme.mit.inf.dslreasoner.domains.cps.Request
import hu.bme.mit.inf.dslreasoner.domains.cps.Requirement
import org.eclipse.emf.common.notify.Notifier
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.viatra.dse.statecode.IStateCoder
import org.eclipse.viatra.dse.statecode.IStateCoderFactory
import org.eclipse.viatra.query.runtime.api.IPatternMatch
import org.eclipse.xtend2.lib.StringConcatenationClient

class CpsStateCoder implements IStateCoder {
	CyberPhysicalSystem cps

	protected new() {
	}

	override init(Notifier notifier) {
		cps = switch (notifier) {
			ResourceSet: getCpsFromResourceSet(notifier)
			Resource: getCpsFromResource(notifier)
			CyberPhysicalSystem: notifier
			default: throw new IllegalArgumentException("notifier is not a CyberPhysicalSystem")
		}
	}

	private def getCpsFromResourceSet(ResourceSet resourceSet) {
		if (resourceSet.resources.empty) {
			throw new IllegalArgumentException("No Resource in ResourceSet")
		}
		val resource = resourceSet.resources.head
		getCpsFromResource(resource)
	}

	private def getCpsFromResource(Resource resource) {
		if (resource.contents.empty) {
			throw new IllegalArgumentException("No EObject in Resource")
		}
		val cps = resource.contents.head
		if (cps instanceof CyberPhysicalSystem) {
			cps
		} else {
			throw new IllegalArgumentException("EObject in Resource is not a CyberPhysicalSystem")
		}
	}

	override String createStateCode() {
		'''«createRequestsCode»«createHostTypesCode»'''
	}

	private def StringConcatenationClient createRequestsCode() {
		'''«FOR request : cps.requests»«createRequestCode(request)»«ENDFOR»'''
	}

	private def StringConcatenationClient createRequestCode(Request request) {
		'''[«FOR requirement : request.requirements»«createRequirementCode(requirement)»«ENDFOR»]'''
	}

	private def StringConcatenationClient createRequirementCode(Requirement requirement) {
		'''[«FOR app : requirement.instances SEPARATOR ","»«createAppCode(app)»«ENDFOR»]'''
	}

	private def createAppCode(ApplicationInstance app) {
		if (app.allocatedTo === null) {
			"-"
		} else {
			createMatchArgumentCode(app.allocatedTo)
		}
	}

	private def createHostTypesCode() {
		'''(«FOR hostType : cps.hostTypes SEPARATOR ","»«hostType.instances.size»«ENDFOR»)'''
	}

	override String createActivationCode(IPatternMatch match) {
		'''«match.specification.simpleName»(«FOR arg : match.toArray SEPARATOR ","»«createMatchArgumentCode(arg)»«ENDFOR»)'''
	}

	protected dispatch def String createMatchArgumentCode(Requirement requirement) {
		val request = requirement.eContainer
		if (request instanceof Request) {
			if (request.eContainer != cps) {
				throw new IllegalArgumentException("Request is not contained in the CPS")
			}
			val requestIndex = cps.requests.indexOf(request)
			val requirementIndex = request.requirements.indexOf(requirement)
			requestIndex + "." + requirementIndex
		} else {
			throw new IllegalArgumentException("Requirement is not contained in a request")
		}
	}

	protected dispatch def String createMatchArgumentCode(ApplicationInstance app) {
		val requirement = app.requirement
		if (requirement === null) {
			throw new IllegalArgumentException("Application instance is not associated with a requirement")
		}
		val instanceIndex = requirement.instances.indexOf(app)
		createMatchArgumentCode(requirement) + "." + instanceIndex
	}

	protected dispatch def String createMatchArgumentCode(HostInstance host) {
		val hostType = host.eContainer
		if (hostType instanceof HostType) {
			val hostIndex = hostType.instances.indexOf(host)
			createMatchArgumentCode(hostType) + "." + hostIndex
		} else {
			throw new IllegalArgumentException("Host is not contained in a host type")
		}
	}

	protected dispatch def String createMatchArgumentCode(HostType hostType) {
		if (hostType.eContainer != cps) {
			throw new IllegalArgumentException("Host type is not contained in the CPS")
		}
		val hostTypeIndex = cps.hostTypes.indexOf(hostType)
		hostTypeIndex.toString
	}

	protected dispatch def createMatchArgumentCode(Object object) {
		throw new IllegalArgumentException("Unknown match argument: ")
	}

	static class Factory implements IStateCoderFactory {
		override createStateCoder() {
			new CpsStateCoder
		}
	}
}