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
|
package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph
import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric
import java.util.ArrayList
import java.util.HashSet
import java.util.List
import org.eclipse.emf.common.util.EList
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtend.lib.annotations.Accessors
class EMFGraph extends Graph{
@Accessors(PUBLIC_GETTER)
var EObject root;
def void init (EObject root, List<Metric> metrics, String name){
val otherContents = root.eAllContents.toList();
val metaModel = root.eClass.EPackage;
val referenceTypes = new ArrayList<EReference>;
this.root = root;
otherContents.add(root);
metaModel.eAllContents.forEach[
if(it instanceof EReference){
referenceTypes.add(it);
}
]
init(otherContents, metrics, name, referenceTypes);
}
/**
* init the graph with all nodes and reference types in the meta model
* @param objects: objects in the instance model (exclude root)
* @param metrics: metrics to be evaluated
* @param name: name of the instance model
* @param ReferenceTypes: reference types defined in the meta model
*/
def void init(List<EObject> objects, List<Metric> metrics, String name, List<EReference> referenceTypes){
objects.forEach[it|
// TODO: Maybe want to consider all the super types as well
var types = new HashSet();
types.add(it.eClass.name);
statistic.addNodeWithAllTypes(it, types);
]
referenceTypes.forEach[it|
// Only consider the edges that are not derived to preserve the statistical property
if(!it.derived){
statistic.addEdgeType(it.name);
}
];
objects.forEach[source|
source.eClass.EAllReferences.forEach[r|
//many references
if(r.isMany){
source.getNeighbours(r).forEach[target|
addEdge(source, target, r);
]
}else{
//single references
val target = source.eGet(r) as EObject;
addEdge(source, target, r);
}
]
]
this.metrics = metrics;
this.name = name;
}
def void removeReference(EReference r){
if (statistic.containsEdgeType(r.name)){
statistic.removeReference(r.name, r.containment);
}
}
/**
* Set basic information for the output
*/
override setBasicInformation(ArrayList<ArrayList<String>> output){
val metaInfo = new ArrayList<String>();
metaInfo.add(META_MODEL_HEADER);
metaInfo.add(this.metaModel);
val edgeInfo = new ArrayList<String>();
edgeInfo.add(NUM_EDGE_TYPE_HEADER);
edgeInfo.add(this.statistic.allTypes.size()+"");
val nodeInfo = new ArrayList<String>();
nodeInfo.add(NUM_NODE_HEADER);
nodeInfo.add(this.statistic.allNodes.size()+"");
val stateInfo = new ArrayList<String>();
stateInfo.add(STATE_ID_HEADER);
stateInfo.add(this.name);
output.add(metaInfo);
output.add(edgeInfo);
output.add(nodeInfo);
output.add(stateInfo);
}
def EList<EObject> getNeighbours(EObject o, EReference r){
return (o.eGet(r, true) as EList<EObject>);
}
def addEdge(EObject source, EObject target, EReference r){
//Only add the edge if the reference is not derived to preserve the statistical property
if(target !== null && r !== null && !r.derived){
statistic.addEdge(source, target, r.name);
}
}
override GraphStatistic getStatistic(){
return this.statistic;
}
override String getName(){
return this.name;
}
def void setMetaModel(String model){
this.metaModel = model;
}
def String getMetaModel(){
return this.metaModel;
}
}
|