ocarina-backends-connection_matrix-main.adb 23.2 KB
Newer Older
1
2
3
4
5
6
7
8
------------------------------------------------------------------------------
--                                                                          --
--                           OCARINA COMPONENTS                             --
--                                                                          --
--                 OCARINA.BACKENDS.CONNECTION_MATRIX.MAIN                  --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
--                   Copyright (C) 2011-2015 ESA & ISAE.                    --
--                                                                          --
-- Ocarina  is free software; you can redistribute it and/or modify under   --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion. Ocarina is distributed in the hope that it will be useful, but     --
-- WITHOUT ANY WARRANTY; without even the implied warranty of               --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
26
--                                                                          --
jhugues's avatar
jhugues committed
27
28
--                 Ocarina is maintained by the TASTE project               --
--                      (taste-users@lists.tuxfamily.org)                   --
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
--                                                                          --
------------------------------------------------------------------------------

with Ocarina.ME_AADL;
with Ocarina.ME_AADL.AADL_Instances.Nodes;
with Ocarina.ME_AADL.AADL_Instances.Nutils;
with Ocarina.ME_AADL.AADL_Instances.Entities;

with Ocarina.Instances.Queries;

with Ocarina.ME_AADL.AADL_Tree.Nodes;

with Ocarina.Backends.Properties;
with Ocarina.Backends.XML_Tree.Nodes;
with Ocarina.Backends.XML_Tree.Nutils;

45
with Ocarina.Namet; use Ocarina.Namet;
46
47
48
49
50
51
52
53
54
55
56

package body Ocarina.Backends.Connection_Matrix.Main is

   use Ocarina.ME_AADL;
   use Ocarina.ME_AADL.AADL_Instances.Nodes;
   use Ocarina.ME_AADL.AADL_Instances.Entities;
   use Ocarina.Backends.Properties;
   use Ocarina.Backends.XML_Tree.Nutils;

   use Ocarina.Instances.Queries;

57
58
59
60
   package ATN renames Ocarina.ME_AADL.AADL_Tree.Nodes;
   package AIN renames Ocarina.ME_AADL.AADL_Instances.Nodes;
   package AINU renames Ocarina.ME_AADL.AADL_Instances.Nutils;
   package XTN renames Ocarina.Backends.XML_Tree.Nodes;
61
62
63
64
65

   procedure Visit_Architecture_Instance (E : Node_Id);
   procedure Visit_Component_Instance (E : Node_Id);
   procedure Visit_System_Instance (E : Node_Id);

66
67
   Current_Parent_Node : Node_Id;
   My_Root             : Node_Id;
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

   -----------
   -- Visit --
   -----------

   procedure Visit (E : Node_Id) is
   begin
      case Kind (E) is
         when K_Architecture_Instance =>
            Visit_Architecture_Instance (E);

         when K_Component_Instance =>
            Visit_Component_Instance (E);

         when others =>
            null;
      end case;
   end Visit;

   ---------------------------------
   -- Visit_Architecture_Instance --
   ---------------------------------

   procedure Visit_Architecture_Instance (E : Node_Id) is
92
93
      N     : constant Node_Id := New_Node (XTN.K_HI_Node);
      D     : constant Node_Id := New_Node (XTN.K_HI_Distributed_Application);
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
      U     : Node_Id;
      T     : Node_Id;
      P     : Node_Id;
      Q     : Node_Id;
      Tmp   : Node_Id;
      H1    : Node_Id;
      Title : Node_Id;
   begin
      My_Root := Root_System (E);

      XML_Root := D;

      Get_Name_String (To_XML_Name (AIN.Name (AIN.Identifier (My_Root))));

      XTN.Set_Name (D, Name_Find);
      XTN.Set_Units (D, New_List (XTN.K_List_Id));
      XTN.Set_HI_Nodes (D, New_List (XTN.K_List_Id));

      Push_Entity (D);

      Set_Str_To_Name_Buffer ("general");
      XTN.Set_Name (N, Name_Find);

      XTN.Set_Units (N, New_List (XTN.K_List_Id));

      --  Append the partition N to the node list

      Append_Node_To_List (N, XTN.HI_Nodes (Current_Entity));
      XTN.Set_Distributed_Application (N, Current_Entity);

      Push_Entity (N);

      U := New_Node (XTN.K_HI_Unit, AIN.Identifier (My_Root));
127
      Get_Name_String (To_XML_Name (Display_Name (Identifier (My_Root))));
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
      Add_Str_To_Name_Buffer ("_connection_matrix");
      T := Make_Defining_Identifier (Name_Find);
      P := Make_XML_File (T);

      --  This is a special XML file, we specify .html extension
      XTN.Set_Is_HTML (P, True);
      XTN.Set_Distributed_Application_Unit (P, U);
      XTN.Set_XML_File (U, P);

      --   Make the main <html> node in the XML file.
      XTN.Set_Root_Node (P, Make_XML_Node ("html"));

      Append_Node_To_List (U, XTN.Units (Current_Entity));
      XTN.Set_Entity (U, Current_Entity);

      Push_Entity (U);

145
      Current_Parent_Node := XTN.Root_Node (XTN.XML_File (U));
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

      --  Make the <head> node of the HTML file.
      Tmp := Make_XML_Node ("head");

      Append_Node_To_List (Tmp, XTN.Subitems (Current_Parent_Node));

      --  Add a title in the <head> section node
      Title := Make_XML_Node ("title");

      Set_Str_To_Name_Buffer ("Connectivity Matrix for System ");
      Get_Name_String_And_Append (Display_Name (Identifier (My_Root)));

      XTN.Set_Node_Value (Title, Make_Defining_Identifier (Name_Find));

      Append_Node_To_List (Title, XTN.Subitems (Tmp));

      --  Make the <body>...</body> node of the HTML file.
      Tmp := Make_XML_Node ("body");
      Append_Node_To_List (Tmp, XTN.Subitems (Current_Parent_Node));
      Current_Parent_Node := Tmp;

      --  Title of the document, using a <h1>...</h1> node
      Tmp := Make_XML_Node ("h1");
      Append_Node_To_List (Tmp, XTN.Subitems (Current_Parent_Node));

      --  Style of the <h1> node
      Set_Str_To_Name_Buffer
173
        ("font-family: Arial;" &
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
         "text-align: center; font-weight: bold; font-size: 1.2em");
      P := Make_Defining_Identifier (Name_Find);
      Set_Str_To_Name_Buffer ("style");
      Q := Make_Defining_Identifier (Name_Find);
      Append_Node_To_List (Make_Assignement (Q, P), XTN.Items (Tmp));

      --  Title of the document
      Set_Str_To_Name_Buffer ("Connectivity Matrix for System ");
      Get_Name_String_And_Append (Display_Name (Identifier (My_Root)));
      H1 := Make_Defining_Identifier (Name_Find);

      XTN.Set_Node_Value (Tmp, H1);

      Visit (My_Root);

      Pop_Entity;
      Pop_Entity;
      Pop_Entity;
   end Visit_Architecture_Instance;

   ------------------------------
   -- Visit_Component_Instance --
   ------------------------------

   procedure Visit_Component_Instance (E : Node_Id) is
199
      Category : constant Component_Category := Get_Category_Of_Component (E);
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
   begin
      case Category is
         when CC_System =>
            Visit_System_Instance (E);

         when others =>
            null;
      end case;
   end Visit_Component_Instance;

   ---------------------------
   -- Visit_System_Instance --
   ---------------------------

   procedure Visit_System_Instance (E : Node_Id) is
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
      S                : Node_Id;
      N                : Node_Id;
      Conn             : Node_Id;
      T                : Node_Id;
      TR               : Node_Id;
      TD               : Node_Id;
      UL               : Node_Id;
      LI               : Node_Id;
      H2               : Node_Id;
      Table            : Node_Id;
      P                : Node_Id;
      Q                : Node_Id;
      Connected        : Boolean;
      Source_Component : Node_Id;
      Dest_Component   : Node_Id;
      Bandwidth        : Unsigned_Long_Long;
      Bandwidth_Unit   : Name_Id;
      Latency          : Unsigned_Long_Long;
      Latency_Unit     : Name_Id;
      Associated_Bus   : Node_Id;
      Has_Bus          : Boolean := False;
      Bus_Instance     : Node_Id;
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
   begin
      --  Declare the table node that will contain the connectivity matrix.
      Table := Make_XML_Node ("table");

      --  Some CSS style to apply on the table.
      Set_Str_To_Name_Buffer ("border-style: solid; border-width: 1px;");
      P := Make_Defining_Identifier (Name_Find);
      Set_Str_To_Name_Buffer ("style");
      Q := Make_Defining_Identifier (Name_Find);
      Append_Node_To_List (Make_Assignement (Q, P), XTN.Items (Table));

      if not AINU.Is_Empty (Subcomponents (E)) then

         --  Add a <tr> node that represent a line.
         TR := Make_XML_Node ("tr");

         --  Add a <td> node that represent a colon in the line.
         TD := Make_XML_Node ("td");

256
         Append_Node_To_List (TD, XTN.Subitems (TR));
257
258
259
260
261
262

         S := First_Node (Subcomponents (E));

         --  In the following loop, we build a complete line
         --  that contains the name of all system subcomponents.
         while Present (S) loop
263
264
265
            if Get_Category_Of_Component (S) = CC_Bus then
               Has_Bus := True;
            else
266
267
268
269

               TD := Make_XML_Node ("td");

               Set_Str_To_Name_Buffer
270
                 ("font-family: Arial; background-color: #0a97ac;" &
271
272
273
274
275
276
277
278
279
280
281
                  "text-align: center; font-weight: bold; font-size: 0.8em");
               P := Make_Defining_Identifier (Name_Find);
               Set_Str_To_Name_Buffer ("style");
               Q := Make_Defining_Identifier (Name_Find);
               Append_Node_To_List (Make_Assignement (Q, P), XTN.Items (TD));

               Get_Name_String (Display_Name (Identifier (S)));

               N := Make_Defining_Identifier (Name_Find);
               XTN.Set_Node_Value (TD, N);

282
               Append_Node_To_List (TD, XTN.Subitems (TR));
283
284
285
286
            end if;
            S := Next_Node (S);
         end loop;

287
         Append_Node_To_List (TR, XTN.Subitems (Table));
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
      end if;

      if not AINU.Is_Empty (Subcomponents (E)) then
         S := First_Node (Subcomponents (E));

         --  In the following loop, we iterate on each subcomponents
         --  and analyzes which one is connected.
         while Present (S) loop
            if Get_Category_Of_Component (S) /= CC_Bus then
               --  Create a new line (<tr> node).
               TR := Make_XML_Node ("tr");

               --  Create a new colon that contain the name of the
               --  sub-component being analyzed.
               TD := Make_XML_Node ("td");

               Set_Str_To_Name_Buffer
305
                 ("font-family: Arial; background-color: #0a97ac;" &
306
307
308
309
310
311
312
313
314
315
316
                  "text-align: center; font-weight: bold; font-size: 0.8em");
               P := Make_Defining_Identifier (Name_Find);
               Set_Str_To_Name_Buffer ("style");
               Q := Make_Defining_Identifier (Name_Find);
               Append_Node_To_List (Make_Assignement (Q, P), XTN.Items (TD));

               Get_Name_String (Display_Name (Identifier (S)));

               N := Make_Defining_Identifier (Name_Find);
               XTN.Set_Node_Value (TD, N);

317
               Append_Node_To_List (TD, XTN.Subitems (TR));
318
319
320
321
322
323
324
325
326
327

               T := First_Node (Subcomponents (E));

               --  Here, we iterate again on all system sub-components
               --  and try to see which one is connected to the component
               --  actually analyzed (S).

               while Present (T) loop

                  if Get_Category_Of_Component (T) /= CC_Bus then
328
                     TD := Make_XML_Node ("td");
329
330
331
332
333
334
335
336
337
338
339

                     --  Default initialization.
                     Connected      := False;
                     Bandwidth      := 0;
                     Associated_Bus := No_Node;

                     if not AINU.Is_Empty (AIN.Connections (E)) then
                        Conn := First_Node (AIN.Connections (E));
                        while Present (Conn) loop
                           if Kind (Conn) = K_Connection_Instance then
                              if Get_Category_Of_Connection (Conn) =
340
341
342
343
344
345
346
347
348
349
350
351
352
                                CT_Port_Connection
                              then
                                 Source_Component :=
                                   Item
                                     (AIN.First_Node (Path (Source (Conn))));

                                 Dest_Component :=
                                   Item
                                     (AIN.First_Node
                                        (Path (Destination (Conn))));
                                 if Dest_Component = T
                                   and then Source_Component = S
                                 then
353
354

                                    Associated_Bus :=
355
                                      Get_Bound_Bus (Conn, False);
356
357

                                    if Is_Defined_Property
358
359
360
361
362
363
                                        (Conn,
                                         "bus_properties::required_bandwidth")
                                    then
                                       Bandwidth :=
                                         Get_Integer_Property
                                           (Conn,
yoogx's avatar
yoogx committed
364
365
                                            "bus_properties:" &
                                            ":required_bandwidth");
366
367
368
369
370
371
372

                                       Bandwidth_Unit :=
                                         ATN.Name
                                           (ATN.Unit_Identifier
                                            (Get_Value_Of_Property_Association
                                               (Conn,
                                                Get_String_Name
yoogx's avatar
yoogx committed
373
374
                                                  ("bus_properties:" &
                                                     ":required_bandwidth"))));
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
                                       Connected := True;
                                    end if;
                                 end if;
                              end if;
                           end if;
                           Conn := Next_Node (Conn);
                        end loop;
                     end if;

                     N := No_Node;

                     --  If S = T, then, the component analyzed and the
                     --  component on which we iterate are the same. So,
                     --  we just put the cell in grey.

                     if S = T then
                        Set_Str_To_Name_Buffer ("background-color: grey;");
                        P := Make_Defining_Identifier (Name_Find);
                        Set_Str_To_Name_Buffer ("style");
                        Q := Make_Defining_Identifier (Name_Find);
395
396
                        Append_Node_To_List
                          (Make_Assignement (Q, P),
397
398
399
400
401
402
403
404
405
406
407
408
                           XTN.Items (TD));

                     --  If Connected is true, the component being analyzed
                     --  and the component on which we iterate are not the
                     --  same AND are connected. In that case, we put the cell
                     --  in green and print the required bandwidth and (if
                     --  specified) the bus associated to the connection.

                     elsif Connected then
                        if Bandwidth /= 0 then
                           Set_Str_To_Name_Buffer ("<strong>");
                           Add_Str_To_Name_Buffer
409
                             (Unsigned_Long_Long'Image (Bandwidth));
410
411
412
413
414
415
416
417
                           Get_Name_String_And_Append (Bandwidth_Unit);
                           Add_Str_To_Name_Buffer ("</strong>");

                           --  Put information about the associated
                           --  bus if specified.

                           if Associated_Bus /= No_Node then
                              Add_Str_To_Name_Buffer ("<br/><em>(");
418
419
                              Get_Name_String_And_Append
                                (Display_Name (Identifier (Associated_Bus)));
420
421
422
                              Add_Str_To_Name_Buffer (")</em>");
                           else
                              Add_Str_To_Name_Buffer
423
                                ("<br/>(<em>unknwon bus</em>)");
424
425
426
427
                           end if;
                           N := Make_Defining_Identifier (Name_Find);

                           Set_Str_To_Name_Buffer
428
429
                             ("font-family: Arial; " &
                              "background-color: #91ff94;" &
430
431
432
433
434
                              "text-align: center; font-size: 0.8em");
                           P := Make_Defining_Identifier (Name_Find);
                           Set_Str_To_Name_Buffer ("style");
                           Q := Make_Defining_Identifier (Name_Find);
                           Append_Node_To_List
435
436
                             (Make_Assignement (Q, P),
                              XTN.Items (TD));
437
438
439
440
441
442
443
444
445
                        else

                           --  We put N/A in the cell as a text when
                           --  the required bandwidth size is not specified.

                           Set_Str_To_Name_Buffer ("N/A");
                           N := Make_Defining_Identifier (Name_Find);
                        end if;
                     else
446
447
448
449
450
451
452
453
454
455
456
457
                        --  Components are not connected, we put
                        --  the cell to red.
                        Set_Str_To_Name_Buffer
                          ("font-family: Arial; " &
                           "background-color: #b83f3f;" &
                           "text-align: center; font-size: 0.8em");
                        P := Make_Defining_Identifier (Name_Find);
                        Set_Str_To_Name_Buffer ("style");
                        Q := Make_Defining_Identifier (Name_Find);
                        Append_Node_To_List
                          (Make_Assignement (Q, P),
                           XTN.Items (TD));
458
459
460
461
462
463
                     end if;

                     if N /= No_Node then
                        XTN.Set_Node_Value (TD, N);
                     end if;

464
                     Append_Node_To_List (TD, XTN.Subitems (TR));
465
466
467
468
                  end if;
                  T := Next_Node (T);
               end loop;

469
               Append_Node_To_List (TR, XTN.Subitems (Table));
470
471
472
473
474
            end if;
            S := Next_Node (S);
         end loop;
      end if;

475
      --  Add the table to the main HTML node (<body/>).
476
      Append_Node_To_List (Table, XTN.Subitems (Current_Parent_Node));
477
478
479
480
481
482
483
484
485
486

      --  Now, we are enumerating all buses that are used
      --  in the model.

      if Has_Bus then

         --  Make a subtitle for the list of buses.
         H2 := Make_XML_Node ("h2");

         Set_Str_To_Name_Buffer
487
           ("font-family: Arial;" & "font-weight: bold; font-size: 1.2em");
488
489
490
491
492
493
494
495
496
         P := Make_Defining_Identifier (Name_Find);
         Set_Str_To_Name_Buffer ("style");
         Q := Make_Defining_Identifier (Name_Find);
         Append_Node_To_List (Make_Assignement (Q, P), XTN.Items (H2));

         Set_Str_To_Name_Buffer ("Buses used");
         N := Make_Defining_Identifier (Name_Find);
         XTN.Set_Node_Value (H2, N);

497
         Append_Node_To_List (H2, XTN.Subitems (Current_Parent_Node));
498
499
500
501
502
503
504
505
506
507
508

         --  Add a <ul> node that represent a line.
         UL := Make_XML_Node ("ul");

         S := First_Node (Subcomponents (E));

         --  In the following loop, we build a complete line
         --  that contains the name of all system subcomponents.
         while Present (S) loop
            if Get_Category_Of_Component (S) = CC_Bus then
               Bus_Instance := Corresponding_Instance (S);
509
               LI           := Make_XML_Node ("li");
510
511

               Set_Str_To_Name_Buffer
512
                 ("font-family: Arial;" & "font-size: 0.8em");
513
514
515
516
517
518
519
520
521
522
               P := Make_Defining_Identifier (Name_Find);
               Set_Str_To_Name_Buffer ("style");
               Q := Make_Defining_Identifier (Name_Find);
               Append_Node_To_List (Make_Assignement (Q, P), XTN.Items (LI));

               Bandwidth := 0;
               Latency   := 0;

               --  Try to find the bus properties: bandwidth and latency.
               if Is_Defined_Property
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
                   (Bus_Instance,
                    "bus_properties::bandwidth")
               then

                  Bandwidth :=
                    Get_Integer_Property
                      (Bus_Instance,
                       "bus_properties::bandwidth");

                  Bandwidth_Unit :=
                    ATN.Name
                      (ATN.Unit_Identifier
                         (Get_Value_Of_Property_Association
                            (Bus_Instance,
                             Get_String_Name ("bus_properties::bandwidth"))));
538
539
540
               end if;

               if Is_Defined_Property
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
                   (Bus_Instance,
                    "bus_properties::max_latency")
               then

                  Latency :=
                    Get_Integer_Property
                      (Bus_Instance,
                       "bus_properties::max_latency");

                  Latency_Unit :=
                    ATN.Name
                      (ATN.Unit_Identifier
                         (Get_Value_Of_Property_Association
                            (Bus_Instance,
                             Get_String_Name
                               ("bus_properties::max_latency"))));
557
558
559
560
561
562
563
               end if;

               --  First, display the name of the bus in bold
               --  using <strong/> tag.

               Set_Str_To_Name_Buffer ("<strong>");
               Get_Name_String_And_Append
564
                 (Display_Name (Identifier (Bus_Instance)));
565
566
567
568
               Add_Str_To_Name_Buffer ("</strong> (<em>");

               --  Then, put its properties between parenthesis.
               if Bandwidth = 0 and then Latency = 0 then
569
                  Add_Str_To_Name_Buffer ("bus properties are not declared");
570
571
572
573
574
               end if;

               if Bandwidth > 0 then
                  Add_Str_To_Name_Buffer ("bandwidth: ");
                  Add_Str_To_Name_Buffer
575
                    (Unsigned_Long_Long'Image (Bandwidth));
576
577
578
579
580
                  Get_Name_String_And_Append (Bandwidth_Unit);
               end if;

               if Latency > 0 then
                  Add_Str_To_Name_Buffer (" latency: ");
581
                  Add_Str_To_Name_Buffer (Unsigned_Long_Long'Image (Latency));
582
583
584
585
586
587
588
589
                  Get_Name_String_And_Append (Latency_Unit);
               end if;

               Add_Str_To_Name_Buffer ("</em>)");

               N := Make_Defining_Identifier (Name_Find);
               XTN.Set_Node_Value (LI, N);

590
               Append_Node_To_List (LI, XTN.Subitems (UL));
591
592
593
594
            end if;
            S := Next_Node (S);
         end loop;

595
         Append_Node_To_List (UL, XTN.Subitems (Current_Parent_Node));
596
597
      end if;

598
599
   end Visit_System_Instance;
end Ocarina.Backends.Connection_Matrix.Main;