Subversion Repositories DevTools

Rev

Rev 2124 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2088 ghuddy 1
using System;
2
using System.Collections;
2104 ghuddy 3
using System.Text;
2088 ghuddy 4
using System.ComponentModel;
5
using System.Windows.Forms;
6
 
7
namespace EA_DocGen
8
{
9
	/// <summary>
10
	/// Summary description for EA_RelationshipMatrix.
11
	/// </summary>
12
	public class EA_RelationshipMatrix
13
	{
14
 
2122 ghuddy 15
      public struct RM_ColumnType
16
      {
17
         public string columnTitle;
2088 ghuddy 18
 
2122 ghuddy 19
         public string packageGUID;
20
         public string packageName;
21
 
22
         public ArrayList elementTypes;
23
 
24
         public bool packageRecursion;
25
         public bool packageTrimming;
26
         public bool elementNotes;
2124 ghuddy 27
         public bool reqTagSort;
2122 ghuddy 28
      };
29
 
30
      public struct RM_TableType
31
      {
32
         public string introText;
33
         public string title;
34
      };
35
 
36
      public struct RM_MatrixType
37
      {
38
         public int style;
39
         public RM_TableType fromToTable;
40
         public RM_TableType toFromTable;
41
         public RM_ColumnType from;
42
         public RM_ColumnType to;
43
      };
44
 
45
      // DATA
46
      private static RM_MatrixType RM_Matrix;
47
 
48
      private static EA.Element RM_Element = null;
49
 
2106 ghuddy 50
      private static EA.Package fromPackage = null;
51
      private static EA.Package toPackage = null;
2104 ghuddy 52
 
2122 ghuddy 53
      private static ArrayList processedElements = null;
2094 ghuddy 54
 
2106 ghuddy 55
      private static string [] options_string = null;
2088 ghuddy 56
 
2118 ghuddy 57
      private enum DictionaryValueType
58
      {
59
         DVT_EA_ELEMENT,
60
         DVT_STRING
61
      };
2088 ghuddy 62
 
2106 ghuddy 63
		public static void initialise(ArrayList processedElementsRef)
2088 ghuddy 64
		{
2104 ghuddy 65
         processedElements = processedElementsRef;
66
 
2122 ghuddy 67
         RM_Matrix.from.elementTypes = new ArrayList();
68
         RM_Matrix.to.elementTypes = new ArrayList();
2088 ghuddy 69
		}
70
 
2106 ghuddy 71
      private static void reset()
2088 ghuddy 72
      {
2122 ghuddy 73
         RM_Matrix.style = 1;
2104 ghuddy 74
 
2122 ghuddy 75
         RM_Matrix.fromToTable.introText = null;
76
         RM_Matrix.fromToTable.title = null;
77
 
78
         RM_Matrix.from.columnTitle = null;
79
         RM_Matrix.from.packageGUID = null;
80
         RM_Matrix.from.elementTypes.Clear();
81
         RM_Matrix.from.packageRecursion = true;
82
         RM_Matrix.from.packageTrimming = false;
83
         RM_Matrix.from.elementNotes = false;
84
         RM_Matrix.from.packageName = null;
2124 ghuddy 85
         RM_Matrix.from.reqTagSort = true;
2122 ghuddy 86
 
2088 ghuddy 87
         fromPackage = null;
2122 ghuddy 88
 
89
         RM_Matrix.toFromTable.introText = null;
90
         RM_Matrix.toFromTable.title = null;
91
 
92
         RM_Matrix.to.columnTitle = null;
93
         RM_Matrix.to.packageGUID = null;
94
         RM_Matrix.to.elementTypes.Clear();
95
         RM_Matrix.to.packageRecursion = true;
96
         RM_Matrix.to.packageTrimming = false;
97
         RM_Matrix.to.elementNotes = false;
98
         RM_Matrix.to.packageName = null;
2124 ghuddy 99
         RM_Matrix.to.reqTagSort = true;
2122 ghuddy 100
 
2088 ghuddy 101
         toPackage = null;
102
      }
103
 
104
 
2106 ghuddy 105
      public static bool processRelationshipMatrixOptions(EA.Element theElement)
2088 ghuddy 106
      {
2122 ghuddy 107
         RM_Element = theElement;
108
 
2088 ghuddy 109
         reset();
110
 
111
         // Extract the control options from the notes of the element
112
 
113
         string delimStr = "\n";
114
         char [] delim = delimStr.ToCharArray();
2132 ghuddy 115
         options_string = theElement.Notes.Split(delim,100);
2088 ghuddy 116
         int i = 0;
117
         foreach(string s in options_string)
118
         {
119
            options_string[i] = s.Trim();
120
            i++;
121
         }
122
 
123
         // scan the options string and assign values into the options variables as required
124
         foreach(string s in options_string)
125
         {
126
            if (s.Length > 0 && s != "\n" && s != "\r" && s[0] != '\\')
127
            {
2104 ghuddy 128
               if (s.StartsWith("style="))
129
               {
2122 ghuddy 130
                  RM_Matrix.style = EA_DocGenOptions.getOptionValue(s, RM_Matrix.style);
2104 ghuddy 131
               }
2118 ghuddy 132
                  // FROM items
2104 ghuddy 133
               else if (s.StartsWith("fromIntroText="))
2088 ghuddy 134
               {
2122 ghuddy 135
                  RM_Matrix.fromToTable.introText = EA_DocGenOptions.getOptionValue(s, null);
2088 ghuddy 136
               }
2104 ghuddy 137
               else if (s.StartsWith("fromToTableTitle=")) 
2088 ghuddy 138
               {
2122 ghuddy 139
                  RM_Matrix.fromToTable.title = EA_DocGenOptions.getOptionValue(s, null);
2088 ghuddy 140
               }
2104 ghuddy 141
               else if (s.StartsWith("fromColumnTitle=")) 
2088 ghuddy 142
               {
2122 ghuddy 143
                  RM_Matrix.from.columnTitle = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.columnTitle);
2088 ghuddy 144
               }
2104 ghuddy 145
               else if (s.StartsWith("fromPackageRecursion=")) 
2088 ghuddy 146
               {
2122 ghuddy 147
                  RM_Matrix.from.packageRecursion = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.packageRecursion);
2088 ghuddy 148
               }
2104 ghuddy 149
               else if (s.StartsWith("fromPackageTrimming="))
2094 ghuddy 150
               {
2122 ghuddy 151
                  RM_Matrix.from.packageTrimming = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.packageTrimming);
2094 ghuddy 152
               }
2104 ghuddy 153
               else if (s.StartsWith("fromPackage=")) 
2088 ghuddy 154
               {
2122 ghuddy 155
                  RM_Matrix.from.packageGUID = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.packageGUID);
2088 ghuddy 156
               }
2118 ghuddy 157
               else if (s.StartsWith("fromElementNotes="))
158
               {
2122 ghuddy 159
                  RM_Matrix.from.elementNotes = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.elementNotes);
2118 ghuddy 160
               }
2122 ghuddy 161
               else if (s.StartsWith("fromPackageName="))
162
               {
163
                  RM_Matrix.from.packageName = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.packageName);
164
               }
2104 ghuddy 165
               else if (s.StartsWith("fromElementType=")) 
2088 ghuddy 166
               {
2106 ghuddy 167
                  string et = EA_DocGenOptions.getOptionValue(s,null);
2088 ghuddy 168
                  if (et != null) 
169
                  {
2122 ghuddy 170
                     RM_Matrix.from.elementTypes.Add( et );
2088 ghuddy 171
                  }
172
               }
2124 ghuddy 173
               else if (s.StartsWith("fromUsesTagSort="))
174
               {
175
                  RM_Matrix.from.reqTagSort = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.reqTagSort);
176
               }
2088 ghuddy 177
 
178
                  // TO items
2104 ghuddy 179
               else if (s.StartsWith("toIntroText="))
2088 ghuddy 180
               {
2122 ghuddy 181
                  RM_Matrix.toFromTable.introText = EA_DocGenOptions.getOptionValue(s, null);
2088 ghuddy 182
               }
2104 ghuddy 183
               else if (s.StartsWith("toFromTableTitle=")) 
2088 ghuddy 184
               {
2122 ghuddy 185
                  RM_Matrix.toFromTable.title = EA_DocGenOptions.getOptionValue(s, null);
2088 ghuddy 186
               }
2104 ghuddy 187
               else if (s.StartsWith("toColumnTitle=")) 
2088 ghuddy 188
               {
2122 ghuddy 189
                  RM_Matrix.to.columnTitle = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.columnTitle);
2088 ghuddy 190
               }
2104 ghuddy 191
               else if (s.StartsWith("toPackageRecursion=")) 
2088 ghuddy 192
               {
2122 ghuddy 193
                  RM_Matrix.to.packageRecursion = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.packageRecursion);
2088 ghuddy 194
               }
2104 ghuddy 195
               else if (s.StartsWith("toPackageTrimming=")) 
2094 ghuddy 196
               {
2122 ghuddy 197
                  RM_Matrix.to.packageTrimming = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.packageTrimming);
2094 ghuddy 198
               }               
2104 ghuddy 199
               else if (s.StartsWith("toPackage=")) 
2088 ghuddy 200
               {
2122 ghuddy 201
                  RM_Matrix.to.packageGUID = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.packageGUID);
2088 ghuddy 202
               }
2118 ghuddy 203
               else if (s.StartsWith("toElementNotes="))
204
               {
2122 ghuddy 205
                  RM_Matrix.to.elementNotes = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.elementNotes);
2118 ghuddy 206
               }
2122 ghuddy 207
               else if (s.StartsWith("toPackageName="))
208
               {
209
                  RM_Matrix.to.packageName = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.packageName);
210
               }               
2104 ghuddy 211
               else if (s.StartsWith("toElementType=")) 
2088 ghuddy 212
               {
2106 ghuddy 213
                  string et = EA_DocGenOptions.getOptionValue(s,null);
2088 ghuddy 214
                  if (et != null) 
215
                  {
2122 ghuddy 216
                     RM_Matrix.to.elementTypes.Add( et );
2088 ghuddy 217
                  }
218
               }
2124 ghuddy 219
               else if (s.StartsWith("toUsesTagSort="))
220
               {
221
                  RM_Matrix.to.reqTagSort = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.reqTagSort);
222
               }
2088 ghuddy 223
            }
224
         }
225
 
226
         // Verify that we have all the necessary compulsory options
2122 ghuddy 227
         if (RM_Matrix.fromToTable.title == null && RM_Matrix.toFromTable.title == null)
2088 ghuddy 228
         {
229
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
230
               "Missing option: Must specify at least one table title");
231
            return false;
232
         }
233
 
234
         // FROM items
2122 ghuddy 235
         if (RM_Matrix.from.columnTitle == null)
2088 ghuddy 236
         {
237
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
238
               "Missing option: fromColumnTitle");
239
            return false;
240
         }
2122 ghuddy 241
         if (RM_Matrix.from.packageGUID == null)
2088 ghuddy 242
         {
243
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
244
               "Missing option: fromPackageGUID");
245
            return false;
246
         }
2122 ghuddy 247
         if (RM_Matrix.from.elementTypes.Count == 0)
2088 ghuddy 248
         {
249
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
250
               "Missing option(s): fromElementTypes");
251
            return false;
252
         }      
253
 
254
         // TO items
2122 ghuddy 255
         if (RM_Matrix.to.columnTitle == null)
2088 ghuddy 256
         {
257
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
258
               "Missing option: toColumnTitle");
259
            return false;
260
         }
2122 ghuddy 261
         if (RM_Matrix.to.packageGUID == null)
2088 ghuddy 262
         {
263
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
264
               "Missing option: toPackageGUID");
265
            return false;
266
         }
2122 ghuddy 267
         if (RM_Matrix.to.elementTypes.Count == 0)
2088 ghuddy 268
         {
269
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
270
               "Missing option(s): toElementTypes");
271
            return false;
272
         }   
273
 
274
         // Find GUID linked packages in the repository
2122 ghuddy 275
         fromPackage = Main.EA_Repository.GetPackageByGuid( RM_Matrix.from.packageGUID );
2088 ghuddy 276
         if (fromPackage == null)
277
         {
278
            MessageBox.Show("Error processing EA_DocGenRelationshipMatrix\n\n" +
279
               "could not locate fromPackage in Repository");
280
            return false;
281
         }
282
 
2122 ghuddy 283
         toPackage = Main.EA_Repository.GetPackageByGuid( RM_Matrix.to.packageGUID );
2088 ghuddy 284
         if (toPackage == null)
285
         {
286
            MessageBox.Show("Error processing EA_DocGenRelationshipMatrix\n\n" +
287
               "could not locate toPackage in Repository");
288
            return false;
289
         }
290
 
291
         return true;
292
      }
293
 
294
 
2104 ghuddy 295
      public static string optionTemplateForRelationshipMatrix(int style)
2088 ghuddy 296
      {
2104 ghuddy 297
         switch (style)
298
         {
299
            case 1:
300
               return
301
               "style=1\r\n"
302
               + "fromToTableTitle=\r\n"
303
               + "fromIntroText=\r\n"
304
               + "fromColumnTitle=\r\n"
305
               + "fromPackage=\r\n"
306
               + "fromElementType=\r\n"
307
               + "fromElementType=\r\n"
308
               + "fromPackageRecursion=true\r\n"
309
               + "fromPackageTrimming=false\r\n"
2124 ghuddy 310
               + "fromElementNotes=false\r\n"
311
               + "fromUsesTagSort=true\r\n"
2104 ghuddy 312
 
313
               + "toFromTableTitle=\r\n"
314
               + "toIntroText=\r\n"
315
               + "toColumnTitle=\r\n"
316
               + "toPackage=\r\n"
317
               + "toElementType=\r\n"
318
               + "toPackageRecursion=true\r\n"
2118 ghuddy 319
               + "toPackageTrimming=false\r\n"
2124 ghuddy 320
               + "toElementNotes=false\r\n"
321
               + "toUsesTagSort=true\r\n";
2104 ghuddy 322
            case 2:
323
               return
324
               "style=2\r\n"
325
               + "fromToTableTitle=Requirement Dependencies\r\n"
326
               + "fromIntroText=The following table identifies the source requirements (if any) for each requirement stated in this document.\r\n"
327
               + "fromColumnTitle=Requirement\r\n"
328
               + "fromPackage=\r\n"
329
               + "fromElementType=Requirement\r\n"
330
               + "fromPackageRecursion=true\r\n"
331
               + "fromPackageTrimming=false\r\n"
2118 ghuddy 332
               + "fromElementNotes=false\r\n"
2124 ghuddy 333
               + "fromUsesTagSort=true\r\n"
2104 ghuddy 334
 
335
               + "toPackageRecursion=true\r\n"
336
               + "toPackage=\r\n"
337
               + "toColumnTitle=Source Requirements\r\n"
338
               + "toElementType=Requirement\r\n";
339
            default:
340
               return "";
341
         }
2088 ghuddy 342
      }
343
 
2122 ghuddy 344
 
2104 ghuddy 345
      /// <summary>
346
      /// This function will insert one or more relationship matrix tables into the document, 
347
      /// built from content specified in options that are provided in the notes section of 
348
      /// the special element that has led to this function being called.
349
      /// </summary>
350
      /// <param name="theElement"></param>
351
      /// <param name="recurse_level"></param>
2106 ghuddy 352
      public static void processRelationshipMatrixElement( EA.Element theElement, int recurse_level )
2104 ghuddy 353
      {
2122 ghuddy 354
         RM_Element = theElement;
355
 
356
         if (RM_Matrix.from.packageName != null && fromPackage != null)
2104 ghuddy 357
         {
2122 ghuddy 358
            EA.Package newFromPackage = EA_Utilities.findNamedPackage(fromPackage, RM_Matrix.from.packageName);
359
            if (newFromPackage != null)
360
            {
361
               fromPackage = newFromPackage;
362
            }
363
            else
364
            {
365
               MessageBox.Show("Error processing EA_DocGenRelationshipMatrix\n\n" +
366
                  "could not locate fromPackageName in Repository");
367
               return;
368
            }
369
         }
370
 
371
         if (RM_Matrix.to.packageName != null && toPackage != null)
372
         {
373
            EA.Package newToPackage = EA_Utilities.findNamedPackage(toPackage, RM_Matrix.to.packageName);
374
            if (newToPackage != null)
375
            {
376
               toPackage = newToPackage;
377
            }
378
            else
379
            {
380
               MessageBox.Show("Error processing EA_DocGenRelationshipMatrix\n\n" +
381
                  "could not locate toPackageName in Repository");
382
               return;
383
            }
384
         }
385
 
386
         switch (RM_Matrix.style)
387
         {
2104 ghuddy 388
            case 1:
389
               processRelationshipMatrixElementStyle1();
390
               break;
2088 ghuddy 391
 
2104 ghuddy 392
            case 2:
393
               processRelationshipMatrixElementStyle2();
394
               break;
395
         }
396
      }
397
 
2122 ghuddy 398
 
2104 ghuddy 399
      /// <summary>
400
      /// This function will insert a relationship matrix table into the document, built from content
401
      /// specified in options that are provided in the notes section of the special element that
402
      /// has led to this function being called.
403
      /// 
404
      /// The style of these tables is that required for requirement to design traceability.
405
      /// </summary>
406
      /// <param name="EA_RelMatrix"></param>
2106 ghuddy 407
      private static void processRelationshipMatrixElementStyle1()
2104 ghuddy 408
      {
409
         int tableNum = 0;
410
         Word.Table table = null;
411
 
412
         // Scan the fromPackage to find all the "from elements".
2124 ghuddy 413
         Main.WriteOutput("   Finding elements in fromPackage", -1);
2122 ghuddy 414
         ElementAccumulator fromLister = new ElementAccumulator(RM_Matrix.from.elementTypes);
415
         EA_Utilities.findAndProcessPackageElements( fromPackage, fromLister, RM_Matrix.from.packageRecursion );
2104 ghuddy 416
 
2106 ghuddy 417
         if (createWordDoc.abortCreationThread)
418
            return;
419
 
2120 ghuddy 420
         // Scan the toPackage to find all the "to elements".
2124 ghuddy 421
         Main.WriteOutput("   Finding elements in toPackage", -1);
2122 ghuddy 422
         ElementAccumulator toLister = new ElementAccumulator(RM_Matrix.to.elementTypes);
423
         EA_Utilities.findAndProcessPackageElements( toPackage, toLister, RM_Matrix.to.packageRecursion );
2120 ghuddy 424
 
425
         if (createWordDoc.abortCreationThread)
426
            return;
427
 
2104 ghuddy 428
         // Sort the "from elements"
2124 ghuddy 429
         Main.WriteOutput("   Sorting elements in fromPackage", -1);
430
         if (RM_Matrix.from.reqTagSort)
431
         {
432
            elementSortByTAG sorter = new elementSortByTAG();
433
            fromLister.Elements.Sort( sorter );
434
         }
435
         else
436
         {
437
            elementSortByName sorter = new elementSortByName();
438
            fromLister.Elements.Sort( sorter );
439
         }
2104 ghuddy 440
 
2120 ghuddy 441
         // Sort the "to" elements
2124 ghuddy 442
         Main.WriteOutput("   Sorting elements in toPackage", -1);
443
         if (RM_Matrix.to.reqTagSort)
444
         {
445
            elementSortByTAG sorter = new elementSortByTAG();
446
            toLister.Elements.Sort( sorter );
447
         }
448
         else
449
         {
450
            elementSortByName sorter = new elementSortByName();
451
            toLister.Elements.Sort( sorter );
452
         }
2120 ghuddy 453
 
2106 ghuddy 454
         if (createWordDoc.abortCreationThread)
455
            return;
456
 
2104 ghuddy 457
         // dictionary to support from-to table construction.
458
         ArrayList fromToDictionary = new ArrayList();
459
 
460
         // dictionary to support to-from table construction.
461
         ArrayList toFromDictionary = new ArrayList();
462
 
463
         bool needFromToTable = false;
2122 ghuddy 464
         if (RM_Matrix.fromToTable.title != null && RM_Matrix.fromToTable.title.Length > 0)
2104 ghuddy 465
            needFromToTable = true;
466
 
467
         bool needToFromTable = false;
2122 ghuddy 468
         if (RM_Matrix.toFromTable.title != null && RM_Matrix.toFromTable.title.Length > 0)
2104 ghuddy 469
            needToFromTable = true;
470
 
471
         // NOTE: this code has to execute even if no from-to table is needed, in order to support the
472
         // generation of a to-from table, assuming the user has requested one.
473
         int numberOfFromToRows = 0;
2124 ghuddy 474
 
475
         Main.WriteOutput("   Creating from-to Dictionary", -1);
2104 ghuddy 476
 
477
         foreach(EA.Element fromElement in fromLister.Elements)
478
         {
2106 ghuddy 479
            if (createWordDoc.abortCreationThread)
480
               return;
481
 
2104 ghuddy 482
            // look at the elements connection collection to find references to the
483
            // destination elements
484
            bool foundToElement = false;
485
 
486
            EA.Collection conCollection = fromElement.Connectors;
487
 
488
            foreach (EA.Connector thisCon in conCollection)
489
            {
2106 ghuddy 490
               if (createWordDoc.abortCreationThread)
491
                  return;
492
 
493
               EA.Element destE = Main.EA_Repository.GetElementByID( thisCon.SupplierID );
2104 ghuddy 494
               if (destE == null)
495
                  continue;
496
 
497
               // ignore self-referential connections
498
               if (fromElement.ElementID == thisCon.SupplierID)
499
                  continue;
500
 
501
               // if the destination element is of a type that the user has requested to include...
2122 ghuddy 502
               if (!RM_Matrix.to.elementTypes.Contains( destE.Type ))
2104 ghuddy 503
                  continue;
504
 
2120 ghuddy 505
               // if the destination element is in the "to list"...
506
               if ( !toLister.ElementIds.Contains(destE.ElementID) )
507
                  continue;
508
 
2104 ghuddy 509
               // Capture the from-to relationship in a dictionary where the key is the
510
               // "from element", and the value is the "to element".
511
               DictionaryEntry newFromToEntry = new DictionaryEntry(fromElement, destE);
512
               fromToDictionary.Add( newFromToEntry );
513
               foundToElement = true;
514
 
515
               // Capture the from-to relationship in a dictionary where the key is the
516
               // ID of the destination element, and the value is the from element name.
517
               // This dictionary will enable rapid construction of the to-from table if
518
               // the user has requested it, from the exact same relationship info used
519
               // to construct the from-to table.
520
               if (needToFromTable)
521
               {
522
                  DictionaryEntry newToFromEntry = new DictionaryEntry(destE.ElementID, fromElement.Name);
523
                  toFromDictionary.Add( newToFromEntry );
524
               }
525
            }
526
 
527
            // If we found a from-to relationship that table needs a new row.
528
            if (foundToElement)
529
            {
530
               numberOfFromToRows++;
531
            }
532
               // If we did not find a from-to relationship that table still needs a new row 
533
               // if the user wants all "from elements", even if some have no "to elements".
2122 ghuddy 534
            else if (RM_Matrix.from.packageTrimming == false)
2104 ghuddy 535
            {
536
               DictionaryEntry newFromToEntry = new DictionaryEntry(fromElement, null);
537
               fromToDictionary.Add( newFromToEntry );
538
               numberOfFromToRows++;
539
            }
540
         }
541
 
2106 ghuddy 542
         if (createWordDoc.abortCreationThread)
543
            return;
544
 
2104 ghuddy 545
         if (needFromToTable)
546
         {
547
            // Now we can actually serialise the table
548
 
2124 ghuddy 549
            Main.WriteOutput("   Creating from-to table", -1);
550
 
2122 ghuddy 551
            if (RM_Matrix.fromToTable.introText != null && RM_Matrix.fromToTable.introText.Length > 0)
2104 ghuddy 552
            {
2122 ghuddy 553
               Word.Range wr = TextualContent.appendAndSelectText( RM_Matrix.fromToTable.introText, EA_Constants.styleName_Body1 );
554
               object obj = string.Format("EA_DocGen Informational Comment - This table has been produced using the following options:\n\n{0}", RM_Element.Notes);
555
               createWordDoc.WordDocument.Comments.Add(wr, ref obj);
2104 ghuddy 556
            }
557
 
558
            // create the from-to table in the word doc
2122 ghuddy 559
            tableNum = TabularContent.Table_Create( RM_Matrix.fromToTable.title, true, numberOfFromToRows + 1, 2 );
2106 ghuddy 560
            table = createWordDoc.WordDocument.Tables[tableNum];
2104 ghuddy 561
 
2122 ghuddy 562
            TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.from.columnTitle, 1);
563
            TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.to.columnTitle, 2);
2104 ghuddy 564
 
2118 ghuddy 565
            fillInTable(fromToDictionary, table, DictionaryValueType.DVT_EA_ELEMENT);
2104 ghuddy 566
         }
567
 
2106 ghuddy 568
         if (createWordDoc.abortCreationThread)
569
            return;
570
 
2104 ghuddy 571
         // Does user want a to-from table ?
572
         if (needToFromTable)
573
         {
2124 ghuddy 574
            Main.WriteOutput("   Creating to-from Dictionary", -1);
575
 
2118 ghuddy 576
            // update fromElementNotes with toElementNotes setting
2122 ghuddy 577
            RM_Matrix.from.elementNotes = RM_Matrix.to.elementNotes;
2118 ghuddy 578
 
2104 ghuddy 579
            // re-use the fromToDictionary to prepare the to-from table content 
580
            fromToDictionary.Clear();
581
 
2120 ghuddy 582
            // We've already found all elements for the left hand column of the to-from table.
583
            // They are stored in the toLister
2104 ghuddy 584
 
2106 ghuddy 585
            if (createWordDoc.abortCreationThread)
586
               return;
587
 
2104 ghuddy 588
            // To make the to-from table, we use the dictionary that was built when making the from-to
589
            // table. The dictionary will allow rapid determination of what "from" items belong to each
590
            // "to" item, without us having to go back to EA and enquire on the database.
591
            // We build a new fromToDictionary from the toFromDictionary, in advance of actually making 
592
            // the table so that we can figure out how many rows the table needs to have.
593
            numberOfFromToRows = 0;
594
 
595
            foreach(EA.Element toElement in toLister.Elements)
596
            {
2106 ghuddy 597
               if (createWordDoc.abortCreationThread)
598
                  return;
599
 
2104 ghuddy 600
               bool foundToElement = false;
601
 
602
               // right-column cell content
603
               foreach (DictionaryEntry de in toFromDictionary)
604
               {
605
                  if ((int)de.Key == toElement.ElementID)
606
                  {
607
                     DictionaryEntry newFromToEntry = new DictionaryEntry(toElement, (string)de.Value);
608
                     fromToDictionary.Add( newFromToEntry );
609
                     foundToElement = true;
610
                  }
611
               }
612
 
2106 ghuddy 613
               if (createWordDoc.abortCreationThread)
614
                  return;
615
 
2104 ghuddy 616
               // If we found a from-to relationship that table needs a new row.
617
               if (foundToElement)
618
               {
619
                  numberOfFromToRows++;
620
               }
621
                  // if user wants all "from elements", even if some have no "to elements", then add a dictionary
622
                  // entry and bump row count.
2122 ghuddy 623
               else if (RM_Matrix.to.packageTrimming == false)
2104 ghuddy 624
               {
625
                  DictionaryEntry newFromToEntry = new DictionaryEntry(toElement, "");
626
                  fromToDictionary.Add( newFromToEntry );
627
                  numberOfFromToRows++;
628
               }
629
            }
630
 
2106 ghuddy 631
            if (createWordDoc.abortCreationThread)
632
               return;
633
 
2104 ghuddy 634
            // Now begin to add the to-from table to the word document
2124 ghuddy 635
            Main.WriteOutput("   Creating to-from table", -1);
636
 
2122 ghuddy 637
            if (RM_Matrix.toFromTable.introText != null && RM_Matrix.toFromTable.introText.Length > 0)
2104 ghuddy 638
            {
2122 ghuddy 639
               Word.Range wr = TextualContent.appendAndSelectText( RM_Matrix.toFromTable.introText, EA_Constants.styleName_Body1 );
640
 
641
               // add options comment only if user did not generate a from-to table, since there is no point in repeating
642
               // the options comment which applies to both from-to and to-from table pair.
643
               if (!needFromToTable)
644
               {
645
                  object obj = string.Format("EA_DocGen Informational Comment - This table has been produced using the following options:\n\n{0}", RM_Element.Notes);
646
                  createWordDoc.WordDocument.Comments.Add(wr, ref obj);
647
               }
2104 ghuddy 648
            }
649
 
650
            // create the table in the word doc
2122 ghuddy 651
            tableNum = TabularContent.Table_Create( RM_Matrix.toFromTable.title, true, numberOfFromToRows + 1, 2 );
2106 ghuddy 652
            table = createWordDoc.WordDocument.Tables[tableNum];
2104 ghuddy 653
 
2122 ghuddy 654
            TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.to.columnTitle, 1);
655
            TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.from.columnTitle, 2);
2104 ghuddy 656
 
2118 ghuddy 657
            fillInTable(fromToDictionary, table, DictionaryValueType.DVT_STRING);
2104 ghuddy 658
         }
659
      }
660
 
2122 ghuddy 661
 
2118 ghuddy 662
      private static void fillInTable(ArrayList fromToDictionary, Word.Table table, DictionaryValueType valueType )
2104 ghuddy 663
      {
664
         int lastFromElementId = -1;
2118 ghuddy 665
         bool firstCellContent = true;
2104 ghuddy 666
         int row = 1;
667
         foreach (DictionaryEntry de in fromToDictionary)
668
         {
2106 ghuddy 669
            if (createWordDoc.abortCreationThread)
670
               return;
671
 
2104 ghuddy 672
            if ( ((EA.Element)de.Key).ElementID != lastFromElementId )
673
            {
674
               lastFromElementId = ((EA.Element)de.Key).ElementID;
675
               row++;
676
               table.Cell(row,1).Range.Text = ((EA.Element)de.Key).Name;
2118 ghuddy 677
               firstCellContent = true;
678
 
2122 ghuddy 679
               if (RM_Matrix.from.elementNotes)
2118 ghuddy 680
               {
2122 ghuddy 681
                  if (((EA.Element)de.Key).Notes != null && ((EA.Element)de.Key).Notes.Length > 0)
682
                  {
683
                     table.Cell(row,1).Range.Text += ((EA.Element)de.Key).Notes;
684
                  }
685
                  // Because we are including both the short description and the notes of the requirement
686
                  // in the cell, we need to discriminate them. We do this by bolding the short description,
687
                  // and reducing the font size of the notes to 8.
688
                  Word.Range wr = table.Cell(row,1).Range;
689
                  wr.Sentences[1].Font.Bold = 1;
690
                  for(int i=2; i<=wr.Sentences.Count; i++)
691
                     wr.Sentences[i].Font.Size = 8;
2118 ghuddy 692
               }
2104 ghuddy 693
            }
2122 ghuddy 694
 
2118 ghuddy 695
            if ((valueType == DictionaryValueType.DVT_EA_ELEMENT) && (((EA.Element)de.Value) != null))
2104 ghuddy 696
            {
2118 ghuddy 697
               if (firstCellContent)
2104 ghuddy 698
               {
2118 ghuddy 699
                  firstCellContent = false;
700
                  table.Cell(row,2).Range.Text = ((EA.Element)de.Value).Name;
701
               }
702
               else
703
               {
704
                  table.Cell(row,2).Range.Text += ((EA.Element)de.Value).Name;
705
               }
706
            }
707
            else if ((valueType == DictionaryValueType.DVT_STRING) && (((string)de.Value).Length > 0))
708
            {
709
               if (firstCellContent)
710
               {
711
                  firstCellContent = false;
2104 ghuddy 712
                  table.Cell(row,2).Range.Text = (string)de.Value;
713
               }
714
               else
715
               {
716
                  table.Cell(row,2).Range.Text += (string)de.Value;
717
               }
718
            }
719
            else
720
            {
2116 ghuddy 721
               if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_UN_ALLOCATED_RELATIONSHIP_WARNINGS) == false)
2104 ghuddy 722
               {
723
                  table.Cell(row,2).Range.Text = "Un-allocated relationship!";
724
                  table.Cell(row,2).Range.Font.Color = Word.WdColor.wdColorRed;
725
               }
726
            }
727
         }
728
      }
729
 
2122 ghuddy 730
 
2104 ghuddy 731
      /// <summary>
732
      /// This function will insert a relationship matrix table into the document, built from content
733
      /// specified in options that are provided in the notes section of the special element that
734
      /// has led to this function being called.
735
      /// 
736
      /// The style of this single table is that required for requirement to requirement traceability.
737
      /// Here, only a single table is generated, and the only elements in the left hand column will
738
      /// be those serialised to the document earlier on, and the content of the right hand column
739
      /// will be the parental requirements (all the way up to root requirements).
740
      /// </summary>
741
      /// <param name="EA_RelMatrix"></param>
2106 ghuddy 742
      private static void processRelationshipMatrixElementStyle2()
2104 ghuddy 743
      {
744
         int i;
745
         int tableNum = 0;
746
         Word.Table table = null;
747
 
748
         // Scan the fromPackage to find all the "from elements".
2124 ghuddy 749
         Main.WriteOutput("   Finding elements in fromPackage", -1);
750
 
2122 ghuddy 751
         ElementAccumulator fromLister = new ElementAccumulator(RM_Matrix.from.elementTypes);
752
         EA_Utilities.findAndProcessPackageElements( fromPackage, fromLister, RM_Matrix.from.packageRecursion );
2104 ghuddy 753
 
2106 ghuddy 754
         if (createWordDoc.abortCreationThread)
755
            return;
756
 
2104 ghuddy 757
         // Remove all elements from the list that did not go to form content in the document
758
         // prior to this point in the document generation process.
759
         for (i=0; i<fromLister.Elements.Count; )
760
         {
2106 ghuddy 761
            if (createWordDoc.abortCreationThread)
762
               return;
763
 
2104 ghuddy 764
            if ( !processedElements.Contains( ((EA.Element)fromLister.Elements[i]).ElementID ) )
765
            {
766
               fromLister.Elements.RemoveAt(i);
767
               continue;
768
            }
769
            i++;
770
         }
771
 
2106 ghuddy 772
         if (createWordDoc.abortCreationThread)
773
            return;
774
 
2104 ghuddy 775
         // Sort the remaining "from elements"
2124 ghuddy 776
         Main.WriteOutput("   Sorting elements in fromPackage", -1);
2106 ghuddy 777
 
2124 ghuddy 778
         if (RM_Matrix.from.reqTagSort)
779
         {
780
            elementSortByTAG sorter = new elementSortByTAG();
781
            fromLister.Elements.Sort( sorter );
782
         }
783
         else
784
         {
785
            elementSortByName sorter = new elementSortByName();
786
            fromLister.Elements.Sort( sorter );
787
         }
788
 
2106 ghuddy 789
         if (createWordDoc.abortCreationThread)
790
            return;
791
 
2104 ghuddy 792
         // Scan the toPackage to find all the "to elements".
793
         // Extract their element IDs into a new list.
2124 ghuddy 794
         Main.WriteOutput("   Finding elements in toPackage", -1);
795
 
2122 ghuddy 796
         ElementAccumulator toLister = new ElementAccumulator(RM_Matrix.to.elementTypes);
797
         EA_Utilities.findAndProcessPackageElements( toPackage, toLister, RM_Matrix.to.packageRecursion );
2104 ghuddy 798
         ArrayList acceptableParents = new ArrayList();
799
         foreach(EA.Element ele in toLister.Elements)
800
         {
2106 ghuddy 801
            if (createWordDoc.abortCreationThread)
802
               return;
803
 
2104 ghuddy 804
            acceptableParents.Add( ele.ElementID);
805
         }
806
 
2106 ghuddy 807
         if (createWordDoc.abortCreationThread)
808
            return;
809
 
2104 ghuddy 810
         // The list of from elements dictates the number of rows in our table.
811
         int numberOfFromToRows = fromLister.Elements.Count;
812
 
2124 ghuddy 813
         Main.WriteOutput("   Creating from-to table", -1);
814
 
2122 ghuddy 815
         if (RM_Matrix.fromToTable.introText != null && RM_Matrix.fromToTable.introText.Length > 0)
2104 ghuddy 816
         {
2122 ghuddy 817
            Word.Range wr = TextualContent.appendAndSelectText( RM_Matrix.fromToTable.introText, EA_Constants.styleName_Body1 );
818
            object obj = string.Format("EA_DocGen Informational Comment - This table has been produced using the following options:\n\n{0}", RM_Element.Notes);
819
            createWordDoc.WordDocument.Comments.Add(wr, ref obj);
2104 ghuddy 820
         }
821
 
822
         // create the from-to table in the word doc
2122 ghuddy 823
         tableNum = TabularContent.Table_Create( RM_Matrix.fromToTable.title, true, numberOfFromToRows + 1, 2 );
2106 ghuddy 824
         table = createWordDoc.WordDocument.Tables[tableNum];
2104 ghuddy 825
 
2122 ghuddy 826
         TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.from.columnTitle, 1);
827
         TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.to.columnTitle, 2);
2104 ghuddy 828
 
829
         int row = 2;
830
         foreach(EA.Element ele in fromLister.Elements)
831
         {
2106 ghuddy 832
            if (createWordDoc.abortCreationThread)
833
               return;
834
 
2104 ghuddy 835
            table.Cell(row,1).Range.Text = ele.Name;
836
 
2122 ghuddy 837
            if (RM_Matrix.from.elementNotes && ele.Notes != null && ele.Notes.Length > 0)
2118 ghuddy 838
            {
839
               table.Cell(row,1).Range.Text += ele.Notes;
840
            }
841
 
2104 ghuddy 842
            StringBuilder sb = new StringBuilder();
843
 
844
            ArrayList parentsDiscovered = new ArrayList();
845
 
846
            // Find this requirement's parent (source) requirements
847
            elementParenthood(ele, ref acceptableParents, ref parentsDiscovered, ref sb);
848
 
849
            // if no source requirements found and user has opted for trimming, delete the table row
2122 ghuddy 850
            if (RM_Matrix.from.packageTrimming == true && sb.Length == 0)
2104 ghuddy 851
            {
2106 ghuddy 852
               TabularContent.Table_DeleteThisRow(table, row);
2104 ghuddy 853
               continue;
854
            }
855
 
856
            // fill in the right hand cell on this row of the table with the source requirement list
857
            table.Cell(row,2).Range.Text = sb.ToString();
858
            row++;
859
         }
860
 
861
      }
862
 
2122 ghuddy 863
 
2106 ghuddy 864
      private static void elementParenthood(EA.Element ele, ref ArrayList acceptableParents, ref ArrayList parentsDiscovered, ref StringBuilder sb)
2104 ghuddy 865
      {
866
         foreach(EA.Connector con in ele.Connectors)
867
         {
2106 ghuddy 868
            if (createWordDoc.abortCreationThread)
869
               return;
870
 
2104 ghuddy 871
            // ignore downwards direction, indicated by the client ID being equal to the element ID
872
            if (con.ClientID != ele.ElementID)
873
            {
874
               // if we have not already come across this upward path before...
875
               if (!parentsDiscovered.Contains(con.ClientID))
876
               {
877
                  parentsDiscovered.Add(con.ClientID);
878
 
2120 ghuddy 879
                  // if this parent is in the list of acceptable parents...
2104 ghuddy 880
                  if (acceptableParents.Contains(con.ClientID))
881
                  {
882
                     // get the parent element, add its name to our list, and ascend through the element
883
                     // using recursion.
2106 ghuddy 884
                     EA.Element client = Main.EA_Repository.GetElementByID(con.ClientID);
2104 ghuddy 885
                     if (client != null)
886
                     {
887
                        if (sb.Length > 0)
888
                           sb.Append("\n");
889
                        sb.Append(client.Name);
890
 
891
                        elementParenthood(client, ref acceptableParents, ref parentsDiscovered, ref sb);
892
                     }
893
                  }
894
               }
895
            }
896
         }
897
      }
898
 
2088 ghuddy 899
	}
900
}