Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 76fb47b39f0de7162dfc3143b256f158b837a3cf (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
/*******************************************************************************
 * Copyright (c) 2011 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 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * CONTRIBUTORS:
 * 		Henrik Rentz-Reichert (initial contribution)
 * 
 *******************************************************************************/

package org.eclipse.etrice.generator.doc.gen

import com.google.inject.Inject
import com.google.inject.Singleton
import java.io.File
import org.eclipse.etrice.core.genmodel.etricegen.AbstractInstance
import org.eclipse.etrice.core.genmodel.etricegen.ActorInstance
import org.eclipse.etrice.core.genmodel.etricegen.ActorInterfaceInstance
import org.eclipse.etrice.core.genmodel.etricegen.Root
import org.eclipse.etrice.core.genmodel.etricegen.StructureInstance
import org.eclipse.etrice.core.genmodel.etricegen.SystemInstance
import org.eclipse.etrice.generator.generic.RoomExtensions
import org.eclipse.xtext.generator.JavaIoFileSystemAccess

import static java.lang.Runtime.*
import org.eclipse.etrice.core.etmap.util.ETMapUtil
import org.eclipse.etrice.generator.base.logging.ILogger

@Singleton
class InstanceDiagramGen {

	@Inject extension JavaIoFileSystemAccess fileAccess
	@Inject extension RoomExtensions roomExt
	@Inject ILogger logger
	
	def doGenerate(Root root) {
		for (model: root.models) {
			var path = model.generationTargetPath + "/images"
			fileAccess.setOutputPath(path)
			var batchFile = "dot2jpg.bat"
			for (sys : root.systemInstances) {
				var file = sys.name+"_instanceTree.dot"
				logger.logInfo("generating instance tree diagram: '"+file+"' in '"+path+"'")
				fileAccess.generateFile(file, root.generate(sys))
			}
			fileAccess.generateFile(batchFile, root.generate2jpg())
			runDot2Jpg(path, batchFile)
		}
	}
	
	// generate batch file to convert .dot to .jpg
	// dot -Tjpg -oSS.jpg SS.dot	
	def private generate2jpg(Root root){
		'''
			«FOR sys : root.systemInstances»
				dot -Tjpg -o «sys.name»_instanceTree.jpg «sys.name»_instanceTree.dot
			«ENDFOR»
		'''
	}
	
	def private generate(Root root, SystemInstance sys) {
		'''
			digraph «sys.name» {
				rankdir=LR;
				node [shape=box];
				«sys.path.getPathName()» [label="«sys.name»\n(«sys.name»)" style=filled color=red];
				«FOR ssi : sys.instances»
					«ssi.path.getPathName()» [label="«ssi.name»\n(«ssi.subSystemClass.name»)" style=filled color=yellow];
					«sys.path.getPathName()» -> «ssi.path.getPathName()»;  
					«FOR ai : ssi.instances»
						«instance(ai)»
					«ENDFOR»
				«ENDFOR»
			}
		'''
	}
	
	def private String instance(AbstractInstance ai) {
		val parent = ai.eContainer as StructureInstance
		val pthread = ETMapUtil::getMappedThread(ai)
		val tname = if (pthread===null) "?" else pthread.thread.name
		val node = ETMapUtil::getNodeRef(ai)
		val nname = if (node===null) "?" else node.name
		val optional = if (ai instanceof ActorInterfaceInstance) "optional " else ""
		val clsname = if (ai instanceof ActorInstance) (ai as ActorInstance).actorClass.name
			else if (ai instanceof ActorInterfaceInstance) (ai as ActorInterfaceInstance).actorClass.name else "?"
			
		'''
			«ai.path.getPathName()» [label="«optional»«ai.name»\n(«clsname»)\n@«nname»:«tname»"«IF !optional.empty» color=blue style=dashed«ENDIF»];
			«parent.path.getPathName()» -> «ai.path.getPathName()»;
			«IF ai instanceof StructureInstance»
				«FOR sub_ai : (ai as StructureInstance).instances»
					«instance(sub_ai)»
				«ENDFOR»
			«ENDIF» 
		'''
	}

 	def private runDot2Jpg(String path, String bat){
 		var wdir = new File(path)
 		try {
			val p = getRuntime.exec("cmd /C "+bat, null, wdir)
			logger.logInfo(bat+" finished with "+p.waitFor)
		}
		catch (Exception e) {
			e.printStackTrace();
		}

	}
}
	

Back to the top