You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _drafts/2025-03-05-a-real-example-on-using-tags.md
+63-48Lines changed: 63 additions & 48 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ layout: post
4
4
title: A real example on using tags
5
5
header-img: img/posts/DSM.jpg
6
6
subtitle: >-
7
-
In this post I show how one can use tags to perform a real, concrete, analysis.
7
+
In this post I show step by step how one can use tags to perform a real, concrete, analysis.
8
8
date: 2025-03-05
9
9
background: '/img/posts/bg-posts.jpg'
10
10
author: Nicolas Anquetil
@@ -17,7 +17,7 @@ Tags can be a powerful tool to visualize things on legacy software and perform a
17
17
For example, tags can be used to create virtual entities and see how they "interact" with the real entities of the system analyzed.
18
18
In the article [Decomposing God Classes at Siemens](https://rmod-files.lille.inria.fr/Team/Texts/Papers/Anq19a-ICSME-GodClass.pdf) we show how tags can be used to create virtual classes and see their dependencies to real classes.
19
19
20
-
In this post I will show another use of tags: how they can materialize a concept and show its instanciation in a system.
20
+
In this post I will show another use of tags: how they can materialize a concept and show its instantiation in a system.
21
21
22
22
The scenario is that of analysing Corese, a platform to "create, manipulate, parse, serialize, query, reason and validate RDF data."
23
23
Corese is an old software that dates back to the early days of Java.
@@ -40,18 +40,18 @@ Let us see how Moose can help in the task.
40
40
41
41
### Where are the constants used?
42
42
43
-
First, we need the source code of Corese-core ([https://github.com/corese-stack/corese-core](https://github.com/corese-stack/corese-core)).
44
-
As usual we will create a model of this code:
43
+
For an analysis in Moose, we need a model of the system, and this starts with getting the source code ([https://github.com/corese-stack/corese-core](https://github.com/corese-stack/corese-core)).
44
+
The model is created using VerveineJ which can be run using docker:
45
45
```
46
46
docker run -rm -v src/main/java/:/src ghcr.io/evref-bl/verveinej:latest -alllocals -o corese-core.json
47
47
```
48
48
This will create a file `corese-core.json` in the directory `src/main/java/`.
49
-
In the creation of the model we gave to VerveineJ the option `-alllocals`.
50
-
This is because VerveineJ by default only tracks uses of variables with a non primitive type (variables containing objects).
51
-
But here the constants are integers and if we want to know where they are used, we need more details.
49
+
The command to create the model as an option `-alllocals`.
50
+
This is because VerveineJ by default only tracks the uses of variables with non primitive type (variables containing objects).
51
+
Here the constants are integers and if we want to know where they are used, we need more details.
52
52
53
53
Let's import the model in Moose.
54
-
This can be done simply by draging-and-droping the file in Moose.
54
+
This can be done simply by dragging-and-dropping the file in Moose.
55
55
56
56

57
57
@@ -68,23 +68,25 @@ public interface IStats {
68
68
[...]
69
69
```
70
70
71
-
Firstwe need to find these constants to see where they are used.
72
-
Forthis, we can inspect the model and look for all "Model Attributes".
73
-
The constants are actually *attributes* of the interface/classin which they are defined.
71
+
To find where the constants are used, we need to find the representation of the constants in the model.
72
+
For this, we can inspect the model("Inspect" buttonintheModelBrowser) and look for all "Model Attributes".
73
+
The constants are *attributes* of the interface/class in which they are defined as shown in the listing above).
74
74
And they are *model attributes* because they are defined in the source code analysed, as opposed to `System.out` which may be used in the code but for which we don't have the source code.
75
75
76
76
We can then select all the model attributes named PREDICATE:
77
77
`select: [ :each | each name = 'PREDICATE']`.
78
-
Moose gives us 8 different definitions of PREDICATE (and 9 of OBJECT, and 10 of SUBJECT).
79
-
The one we are interested in is the 3rd in the list (IStats.PREDICATE).
78
+
*(note, the backslash (\\) before the square bracket ([) was added by the publishing tool and is not part of the code)*
79
+
80
+
Moose gives us 8 different definitions of PREDICATE (and9forOBJECT, and10forSUBJECT).
81
+
The one we are interested in is the 3rd in the list (`IStats.PREDICATE`).
80
82
81
83

82
84
83
-
Having the same constants defined multiple times is not good news for the analysis and for the developpers.
85
+
Having the same constants defined multiple times is not good news for the analysis and for the developers.
84
86
But this kind of thing is fairly common in old systems which evolved during a long time in the hands of many developers.
85
87
Not all of them had a complete understanding of the system and each had different skills and programming habits.
86
88
87
-
Looking closer to the lists of definitions for the 3 main constants (SUBJECT, PREDICATE, OBJECT), we find that there are at least 5 different definitions of the same constants:
89
+
Lookingat the lists of definitions for the 3 main constants (SUBJECT, PREDICATE, OBJECT), we find that there are at least 5 different definitions of these constants:
88
90
89
91
- stats.IStats:
90
92
```java
@@ -114,8 +116,8 @@ Looking closer to the lists of definitions for the 3 main constants (SUBJECT, PR
114
116
```java
115
117
116
118
publicstaticintTRIPLE=88;
117
-
publicstatic int SUBJECT = 89;
118
-
publicstatic int PREDICATE = 90;
119
+
publicstaticintSUBJECT=89;
120
+
publicstaticintPREDICATE=90;
119
121
publicstaticintOBJECT=91;
120
122
```
121
123
-kgram.core.Exp
@@ -133,78 +135,91 @@ Note: Don't close the Inspector window yet, we are going to need it soon.
133
135
### Tagging the constants and their uses
134
136
135
137
Moose can help us here with tags.
136
-
Tags are (as the name imply) just labels that we can attach to any entity in the model.
137
-
Additionnaly, tags have a color that will help us distinguish them in visualizations.
138
+
Tags are (as the name implies) just labels that can be attached to any entity in the model.
139
+
Additionally, tags have a color that will help us distinguish them in visualizations.
138
140
139
141
So let's tag our constants.
140
-
We will define 5 tags, one for each "set of constant", that is to say one for each of the 5 classes that implement these constants.
141
-
You can choose whatever name and whatever color you prefer for your tags, as long as you remember which is which.
142
+
We will define 5 tags, one for each set of constants, that is to say one for each of the 5 classes that implement these constants.
143
+
You can choose whatever name and color you prefer for your tags, as long as you remember which is which.
144
+
HereI named the tags from the name of the classes that define each set of constant.
142
145
143
146

144
147
145
148
Now we want to tag all the constants in a set with the same tag.
146
-
Let's start with the IStats set, the one listed in the previous section and that was our initial focus.
149
+
Let's see how to do it for constants in `IStats`, the ones listed in the previous section and that were our initial focus.
147
150
148
151
We select the "IStats" tag in the Tag Browser and go back to the Inspector where we have a list of all definitions of PREDICATE.
149
152
If we click on the 3rd of these PREDICATE ("fr::inria::corese::core::stats::IStats.PREDICATE"), a new pane appears on the right, focusing on this attribute.
150
153
There, we can click on its "parentType", giving yet another pane.
154
+
(The following screenshot shows the inspector right before we click on "parentType").
151
155
152
-
.
156
+
.
153
157
154
-
The right pane now focuses on the IStats interface.
158
+
The right pane now focuses on the `IStats` Java interface.
155
159
We can click on "attributes" to get the list of attributes it defines (including PREDICATE from which we started).
156
-
There are 5 attributes which are the one listed at the top of the blogpost.
160
+
There are 5 attributes which are the ones listed in the previous section.
157
161
158
162
So far so good.
159
163
160
-
If we "propagate" this list of 5 attributes (toolbar button of the inspector on the right), the list will be propagated (!) to all tools that are in "Follow" mode.
164
+
To tag these attributes, we will "propagate" them (toolbar button of the Inspector on the right) to all tools that are in "Follow" mode.
161
165
Note that if you minimized the Tag Browser at some point, it will be in "Freeze" mode like in the screenshot above.
162
-
You need to put it back in "Follow" (radio toolbar button on the left).
163
-
Then the propagated list will appear in the center pane of the Tag Browser and you can pass it to the right pane of the Tag Browser with the "\>\>\>" button.
164
-
You now have tagged these 5 constants with the "IStats" tag.
166
+
You need to put it back in "Follow" (radio toolbar button on the left) before propagating the list of constants.
167
+
168
+
Once propagated, the list appears in the center pane of the Tag Browser and you can pass it to the right pane with the "\>\>\>" button.
169
+
Doing this will effectively tag the entities with the selected tag.
165
170
171
+
We now have tagged these 5 constants with the "IStats" tag.
166
172
Ideally we want to find also the usage of these constants.
173
+
So we would like to also tag the methods that use these constants.
174
+
167
175
For this you can open a Query Browser, it will start with the same list of 5 attributes that we just propagated.
168
-
We can create a "Navigation query" and ask for all the "incoming" "accesse" to these attributes as shown below.
176
+
We can create a "Navigation query" and ask for all the "incoming" "accesses" to these attributes as shown below.
169
177
The result is a list of 6 methods.
170
178
171
179

172
180
173
-
We can also propagate these 6 methods and they will appear in the Tag Browser.
174
-
We tag the methods accessing our 5 attributes with the same tag as the attributes themselves.
181
+
We can now propagate these 6 methods and they will appear in the Tag Browser.
182
+
We tag them with the same tag as the attributes themselves.
175
183
176
184
You can repeat the same operations for the 5 sets of constants listed above and the 5 different tags.
177
185
178
186
### Visualizing the result
179
187
180
-
The idea now is to visualize where each set of constant is used.
181
-
For this, we will use an "Architectural Map" which is a fine tool to visualize tags.
188
+
All this tagging was to be able to visualize where each set of constant is defined and, most importantly, used.
189
+
We now turn to the "Architectural Map" which is a fine tool to visualize tags.
190
+
for example, we could show all the top level packages of Corese and the Architectural Map will give visual clues on which ones contain tagged entities, and what tags.
191
+
The Architectural Map allows to expand the content of entities which will allow us to deep dive into each package containing tagged entities to understand where exactly the entities is used or defined.
182
192
183
-
First we want to select all the packages at the top level in Corese core.
184
-
We go back one last time to the Inspector to the very first pane on the left (you may also "Inspect" again the model to open a new Inspector).
193
+
To select all the top level packages, we go back one last time to the Inspector to the very first pane on the left (you may also "Inspect" again the model to open a new Inspector).
185
194
We select the "Model packages" and enter this query in the "script" at the bottom: `self select: [ :each | each parentPackage isNotNil and: [each parentPackage name = 'core'] ]`.
186
-
This gives us a list of 23 packages that we can propagate.
187
-
Finally we open an Architectural Map on these 23 packages.
195
+
*(Again, ignore the backslashes)*
188
196
189
-
For easier visualization, I restricted the Architectural Map to the only 5 packages that do use the tags: "stats", "kgram", "util", "sparql", and "query".
190
-
And I expanded "kgram" that is small and contains different tags.
197
+
The result is a list of 23 packages that we can propagate.
198
+
Finally we open an Architectural Map that will start with the 23 packages that we just propagated.
199
+
200
+
In the following screenchot, I restricted the Architectural Map to the only 5 packages that do use our tags: "stats", "kgram", "util", "sparql", and "query".
201
+
This makes it easier to see the results here.
202
+
I also expanded "kgram" that is small and contains different tags.
191
203
192
204

193
205
194
-
The singlecolor square, on the right of each package name, shows that it contains entities having one, sole tag of this color.
206
+
The single-color square, on the right of each package name, shows that it contains entities having one uniq tag (of this color).
195
207
In our case it means that it contains the constants and methods accessing them, all with the same tag.
208
+
For example, "core" and "util" packages contain entities tagged with only the green tag (which corresponds to the `kgram.core.Exp` class as previously shown in the Tag Browser screenshot).
196
209
197
-
When the square is multicolored, it means it contains entities with differrent tags.
210
+
When the square is multicolored, it means it contains entities with different tags.
198
211
For example, we see that the package "kgram" contains at least the green ("Exp") and the yellow ("Const") tags.
199
212
200
-
Note that in this particular case, I added another tag for class `kgram.api.core.Node` which has its own definition of the OBJECT constant because I wanted to see where it was used also.
201
-
This is the reason for the multicolor square of class "StatsBasedEstimation", in package "stats", which uses OBJECT form `Node` and the other constants from `IStats`.
202
-
213
+
Note that in this particular case, I added another tag for class `kgram.api.core.Node` which has its own definition of the OBJECT constant.
214
+
I wanted to see where it was used also.
215
+
This is the reason for the multicolored square of class `StatsBasedEstimation`, in package "stats", which uses OBJECT from `Node` and the other constants from `IStats`.
203
216
204
217
In the end, the visualization allows to conclude that each package sticks pretty much to its own definition of the constants which is rather reassuring.
205
218
It also shows where one would have to look if we were to replace the constant by a real enum.
206
219
207
220
This is not the end of it however because the constant values used in these methods can be passed off to other methods as argument.
208
-
Here Famix alone (the dependency meta-model used in Moose by default) can no longer help us to follow the flow of usage of the constants because they are just integer being passed around.
209
-
For a finer analysis, a real AST model should be used which is the purpose of the FAST meta-model (Famix-AST).
210
-
But this is another story and falls outside of this blogpost
221
+
Here Famix alone (the meta-model used in Moose by default) can no longer help us to follow the flow of usage of the constants because they are just integer being passed around.
222
+
For a finer analysis, a complete AST model should be used.
223
+
This could be done with the FAST meta-model (Famix-AST), but it is another story that falls outside the scope of this blog-post.
0 commit comments