1 | import "../libraries/decent/common.eol"; |
---|
2 | import "../libraries/decent/logging.eol"; |
---|
3 | import "../libraries/arff/common.eol"; |
---|
4 | |
---|
5 | var selectedType = Native("java.lang.System").getProperty("epsilon.transformation.decent2arffx.type"); |
---|
6 | var skipSource = Native("java.lang.System").getProperty("epsilon.transformation.decent2arffx.skipSource").asBoolean(); |
---|
7 | |
---|
8 | var Type = DECENT!ArtifactType.allInstances().select(a|a.name = selectedType).first(); |
---|
9 | if (Type.isUndefined()) { |
---|
10 | //handle wrong arguments here ? |
---|
11 | } |
---|
12 | |
---|
13 | var types = new OrderedSet(); |
---|
14 | types.add("code"); |
---|
15 | //types.add("Class"); |
---|
16 | //types.add("Method"); |
---|
17 | //types.add("Function"); |
---|
18 | //types.add("Module"); |
---|
19 | |
---|
20 | //TODO: move to common, use for tagging states? |
---|
21 | var nestedAnonymousClassFilter = "\"[\\w]+\\$[\\d]+.*\""; |
---|
22 | |
---|
23 | var Model = DECENT!Model.allInstances().first(); |
---|
24 | |
---|
25 | var TouchCountAttribute = addAttribute("TouchCount", "Number of touches to an artifact"); |
---|
26 | var ArtifactCountAttribute = addAttribute("ArtifactCount", "Number of known artifacts of the same type"); |
---|
27 | var AuthorCountAttribute = addAttribute("AuthorCount", "Number of known authors for an artifact up to the current state"); |
---|
28 | var GlobalAuthorCountAttribute = addAttribute("GlobalAuthorCount", "Number of known authors for all artifacts up to the current state"); |
---|
29 | var FileCountAttribute = addAttribute("FileCount", "Number of existing artifacts up to the current state"); |
---|
30 | |
---|
31 | "Running preprocess".log(1); |
---|
32 | var start = Native("java.lang.System").currentTimeMillis(); |
---|
33 | |
---|
34 | for (type in types) { |
---|
35 | ("Processing type "+type).log(1); |
---|
36 | preprocessArtifacts(type); |
---|
37 | } |
---|
38 | updateDeltas(); |
---|
39 | |
---|
40 | |
---|
41 | var end = Native("java.lang.System").currentTimeMillis(); |
---|
42 | var duration = end - start; |
---|
43 | ("Duration: "+duration.toMinutes().round(5)).log(1); |
---|
44 | |
---|
45 | |
---|
46 | operation updateDeltas() { |
---|
47 | for (a in DECENT!Artifact.allInstances()) { |
---|
48 | (""+a.name).log(3); |
---|
49 | for (s in a.states.select(x|x.isHit())) { |
---|
50 | for (v in s.values.select(v|v.isTypeOf(DoubleValue) or v.isTypeOf(IntegerValue))) { |
---|
51 | ("["+a.type.name+"]"+a.name+"@"+s.ID+"::"+v.ofAttribute.name).log(4); |
---|
52 | s.fromActivity.get(0).addDelta(v.ofAttribute); |
---|
53 | } |
---|
54 | } |
---|
55 | } |
---|
56 | } |
---|
57 | |
---|
58 | operation preprocessArtifacts(typeName : String) { |
---|
59 | var type = DECENT!ArtifactType.allInstances().select(t|t.name = typeName).first(); |
---|
60 | if (type.isUndefined()) { |
---|
61 | //TODO: check that type is set |
---|
62 | //handle wrong arguments here ? |
---|
63 | return; |
---|
64 | } |
---|
65 | |
---|
66 | var artifacts = Artifact.allInstances().select(x|x.type = type and not x.name.matches(nestedAnonymousClassFilter)).sortBy(x|x.name); |
---|
67 | |
---|
68 | var artifactDevelopers = new Set(); |
---|
69 | |
---|
70 | |
---|
71 | for (a in artifacts) { |
---|
72 | var sCount = 0; |
---|
73 | for (s in a.states.select(x|x.isHit()).sortBy(x|x.ID)) { |
---|
74 | ("Processing ["+a.type.name+"]"+a.name+"@"+s.ID).log(4); |
---|
75 | sCount = sCount+1; |
---|
76 | s.addValue(TouchCountAttribute, sCount); |
---|
77 | |
---|
78 | |
---|
79 | |
---|
80 | |
---|
81 | |
---|
82 | // Count artifacts and put existing ones in filecount value |
---|
83 | var existingArtifacts = artifacts.select(x|x.states.select(y|y.fromActivity.first().date.time <= s.fromActivity.first().date.time).size() > 0); |
---|
84 | var fileCount = existingArtifacts.size(); |
---|
85 | s.addValue(FileCountAttribute, fileCount); |
---|
86 | |
---|
87 | //this refers more to the state of the project at a given point in time |
---|
88 | //thus the information will be identical in all states of artifacts with the same state.ID |
---|
89 | //perhaps it should be calculated during the export rather than stored in the model |
---|
90 | //(note however that it is still artifact type related) |
---|
91 | var aCount = artifacts.select(x|x.states.select(y|y.fromActivity.first().date <= s.fromActivity.first().date).size() > 0).size(); |
---|
92 | //(a.name+"@"+s.ID+ " -> Number of known artifacts of type "+a.type.name+": "+aCount).println(); |
---|
93 | s.addValue(ArtifactCountAttribute, aCount); |
---|
94 | |
---|
95 | //author count, could also be calculated from all the activities for an artifact up to a point |
---|
96 | artifactDevelopers.add(s.fromActivity.first().agent); |
---|
97 | var dCount = artifactDevelopers.size(); |
---|
98 | s.addValue(AuthorCountAttribute, dCount); |
---|
99 | |
---|
100 | //number of all known developers up to the point |
---|
101 | //NOT restricted to the type of interest!!! |
---|
102 | DECENT!Agent.allInstances().select(x|x.activities.select(y|y.date <= s.fromActivity.first().date).size() > 0).size(); |
---|
103 | var gdCount = artifactDevelopers.size(); |
---|
104 | s.addValue(GlobalAuthorCountAttribute, gdCount); |
---|
105 | } |
---|
106 | artifactDevelopers.clear(); |
---|
107 | } |
---|
108 | |
---|
109 | ("Processing to arffx ...").log(2); |
---|
110 | |
---|
111 | var arffx = new ARFFx!Model(); |
---|
112 | arffx.name = Model.name+"-artifacts-"+type.name; |
---|
113 | arffx.meta.put("DECENT.ArtifactType", type.name); |
---|
114 | arffx.meta.put("ARFFx.Type", "artifact"); |
---|
115 | |
---|
116 | for (a in artifacts) { |
---|
117 | (" Artifact " +a.name).log(3); |
---|
118 | |
---|
119 | //we exclude first and last states! |
---|
120 | //careful with the filtering here... |
---|
121 | // for (s in a.states.excluding(a.states.first()).excluding(a.states.last()).select(x|x.isHit() and x.next.first().isHit()).sortBy(x|x.ID)) { |
---|
122 | for (s in a.states.excluding(a.states.first()).select(x|x.isHit()).sortBy(x|x.ID)) { |
---|
123 | s.processTargetState(arffx); |
---|
124 | } |
---|
125 | } |
---|
126 | |
---|
127 | //on transformation to Weka instances - either transform to ARFFx and then use Java EMF API on ARFFx |
---|
128 | //or use Java EMF API on DECENT |
---|
129 | } |
---|
130 | |
---|
131 | |
---|
132 | operation DECENT!State processTargetState (arffx : ARFFx!Model) { |
---|
133 | var p = self.previous.first(); |
---|
134 | while (p.isDefined() and not p.isHit()) { |
---|
135 | //TODO: what if more than one? |
---|
136 | p = p.previous.first(); |
---|
137 | } |
---|
138 | if (p.isDefined() or skipSource){ |
---|
139 | |
---|
140 | var i = new ARFFx!Instance(); |
---|
141 | arffx.data.add(i); |
---|
142 | |
---|
143 | i.addValue('\"'+self.artifact.name.asString()+'\"', "Artifact.Name"); |
---|
144 | i.addValue(self.ID.asString(), "Artifact.Target.StateID"); |
---|
145 | i.addValue('\"'+self.fromActivity.first().agent.name+'\"', "Agent.Name"); |
---|
146 | |
---|
147 | for (v in self.values.select(x|x.isTypeOf(DECENT!DoubleValue) or x.isTypeOf(DECENT!IntegerValue))) { |
---|
148 | i.addValue(v.content.asString(), "Artifact.Target."+v.name); |
---|
149 | } |
---|
150 | |
---|
151 | var ax = self.fromActivity.first(); |
---|
152 | |
---|
153 | //TODO: add activity meta-data |
---|
154 | for (v in ax.values.select(x|x.isTypeOf(DECENT!DoubleValue) or x.isTypeOf(DECENT!IntegerValue))) { |
---|
155 | i.addValue(v.content.asString(), "Activity."+v.name); |
---|
156 | } |
---|
157 | |
---|
158 | for (v in ax.deltas) { |
---|
159 | i.addValue(v.change.asString(), "Artifact.Delta."+v.onAttribute.name); |
---|
160 | } |
---|
161 | |
---|
162 | //TODO: these are notably missing in several places! |
---|
163 | if (ax.agentState.isDefined()) { |
---|
164 | for (v in ax.agentState.values.select(x|x.isTypeOf(DECENT!DoubleValue) or x.isTypeOf(DECENT!IntegerValue))) { |
---|
165 | //i.addValue(v.content.asString(), "Agent."+v.name); |
---|
166 | } |
---|
167 | } |
---|
168 | |
---|
169 | if (not skipSource) { |
---|
170 | i.addValue(p.ID.asString(), "Artifact.Source.StateID"); |
---|
171 | |
---|
172 | for (v in p.values.select(x|x.isTypeOf(DECENT!DoubleValue) or x.isTypeOf(DECENT!IntegerValue))) { |
---|
173 | i.addValue(v.content.asString(), "Artifact.Source."+v.name); |
---|
174 | } |
---|
175 | } |
---|
176 | } else { |
---|
177 | } |
---|
178 | } |
---|