Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
2141 ghuddy 1
using System;
2
using System.Text;
3
using System.Globalization;
4
using System.Collections;
5
using System.Windows.Forms;
6
using ReqPro40;
7
 
8
 
9
namespace EA_ReqPro
10
{
11
 
12
	/// <summary>
13
	/// Summary description for ImportReqProDatabase.
14
	/// </summary>
15
	public class ImportReqProDatabase : CopyReqProDatabaseToMemory
16
	{
17
      /// <summary>
18
      /// Constructor logic
19
      /// </summary>
20
      /// <param name="ea_repository"></param>
21
      public ImportReqProDatabase(EA.Repository ea_repository): base(ea_repository)
22
		{
23
		}
24
 
25
 
26
      /// <summary>
27
      /// Method to parse a ReqPro database using the information in a ReqProDB artifact,
28
      /// assumed to be selected in EA's project browser prior to the method call.
29
      /// </summary>
30
      /// <param name="ea_repository"></param>
31
      /// <returns></returns>
2145 ghuddy 32
      public override bool prompt_and_parse(EA.Repository ea_repository, ReqProDB_Artifact.MODE mode)
2141 ghuddy 33
      {
34
         try
35
         {
2145 ghuddy 36
            if (true == base.prompt_and_parse(ea_repository, mode))
2141 ghuddy 37
            {
38
               ea_repository.EnsureOutputVisible(Main.GUI_OUTPUT_TAB_NAME);
39
               ImportFromReqPro(ea_repository);
2145 ghuddy 40
 
41
               // Configure the ReqProDB artifact as a traceability artifact
42
               RQ_Artifact.set_traceability_mode(ea_repository, RQ_Element);
43
 
2141 ghuddy 44
               return true;
45
            }
46
         }
47
         catch (Exception ex)
48
         {
49
            MessageBox.Show(ex.Message, "Error (ImportReqProDatabase::parse)", MessageBoxButtons.OK);
50
         }      
51
         return false;
52
      }
53
 
54
      /// <summary>
55
      /// Displays the content of the change log element to the output trace display. This method must
56
      /// be kept in sync with the ImportFromReqPro method, obviously.
57
      /// </summary>
58
      /// <param name="ea_repository"></param>
59
      /// <param name="changeLog"></param>
60
      public void displayChangeLog(EA.Repository ea_repository, EA.Element changeLog)
61
      {
62
         // The change log element contains all the log in its notes section. Break it up into
63
         // lines, because each line is a single log entry, so that we can process them one at
64
         // a time.
65
         string delimStr = "\n";
66
         char [] delim = delimStr.ToCharArray();
67
         string[] log_strings = changeLog.Notes.Split(delim,2000);
68
 
69
         // Prepare a string to form an updated change log (needed to support the activity of orphaned 
70
         // requirement deletion).
71
         string newList = "";
72
 
73
         // modify delimiters to : character so that we can extract the parameters for each log entry
74
         delimStr = ":";
75
         delim = delimStr.ToCharArray();
76
 
77
         ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,"Displaying Import Change Log", -1);
78
 
79
         foreach(string s in log_strings)
80
         {
81
            // over time, users may delete the orphaned requirements from the EA database, but their
82
            // GUIDs will still exist in the change log. Use of such a GUID will cause 
83
            // an exception in the GetElementByGuid() function. What should we do? We can attempt
84
            // to remove those GUIDs from the list. We can do this by accumulating a new list of GUIDs
85
            // that is formed from the old list, where only good items from the old list find their 
86
            // way into the new list. Gradually, the list is wittled away as EA users delete orphaned
87
            // requirements having first dealt with the design change impacts that resulted from their
88
            // orphanage.
89
            try
90
            {
91
               if (s.StartsWith("{"))
92
               {
93
                  string trimmed_s = s.Trim();
94
 
95
                  // Get log entry;s parameters.
96
                  string[] parameters = trimmed_s.Split(delim, 10);
97
 
98
                  // The first parameter is the GUID so use it to get the requirement element
99
                  EA.Element ea_req = ea_repository.GetElementByGuid(parameters[0]);
100
 
101
                  // Now discriminate actions based on the second parameter
102
 
103
                  if (parameters[1].StartsWith("Created"))
104
                  {
105
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,"  Created : " + ea_req.Name, ea_req.ElementID );
106
                  }
107
                  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
108
                  else if (parameters[1].StartsWith("Orphaned"))
109
                  {
110
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,"  Orphaned : " + ea_req.Name, ea_req.ElementID );
111
 
112
                     foreach (EA.Connector theConnector in ea_req.Connectors)
113
                     {
114
                        EA.Element tgt_ele = (EA.Element)ea_repository.GetElementByID( theConnector.SupplierID );
115
                        if (tgt_ele != null)
116
                        {
117
                           if (!tgt_ele.Type.StartsWith("Requirement"))
118
                           {
119
                              ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     --> " + tgt_ele.Name, tgt_ele.ElementID);
120
                           }
121
                        }
122
                     }
123
                  }
124
                  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
125
                  else if (parameters[1].StartsWith("Name"))
126
                  {
127
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "  Modified Name: " + ea_req.Name, ea_req.ElementID );
128
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     <<< " + parameters[2], ea_req.ElementID);
129
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     >>> " + parameters[3], ea_req.ElementID);
130
                  }
131
                  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
132
                  else if (parameters[1].StartsWith("Notes"))
133
                  {
134
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "  Modified Description: " + ea_req.Name, ea_req.ElementID );
135
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     <<< " + parameters[2], ea_req.ElementID);
136
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     >>> " + parameters[3], ea_req.ElementID);
137
                  }
138
                  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
139
                  else if (parameters[1].StartsWith("Difficulty"))
140
                  {
141
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "  Modified Difficulty: " + ea_req.Name, ea_req.ElementID );
142
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     <<< " + parameters[2], ea_req.ElementID);
143
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     >>> " + parameters[3], ea_req.ElementID);
144
                  }
145
                  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
146
                  else if (parameters[1].StartsWith("Priority"))
147
                  {
148
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "  Modified Priority: " + ea_req.Name, ea_req.ElementID );
149
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     <<< " + parameters[2], ea_req.ElementID);
150
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     >>> " + parameters[3], ea_req.ElementID);
151
                  }
152
                  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
153
                  else if (parameters[1].StartsWith("Version"))
154
                  {
155
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "  Modified Version: " + ea_req.Name, ea_req.ElementID );
156
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     <<< " + parameters[2], ea_req.ElementID);
157
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     >>> " + parameters[3], ea_req.ElementID);
158
                  }
159
                  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
160
                  else if (parameters[1].StartsWith("Status"))
161
                  {
162
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "  Modified Status: " + ea_req.Name, ea_req.ElementID );
163
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     <<< " + parameters[2], ea_req.ElementID);
164
                     ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "     >>> " + parameters[3], ea_req.ElementID);
165
                  }
166
 
167
                  // accumulate good item into the newList
168
                  newList += trimmed_s + "\r\n";
169
               }
170
            }
171
            catch
172
            {
173
               // do nothing - the newList accumulator will not have the GUID that caused the exception
174
               // so the next time a display operation is attempted, the exception wont happen.
175
            }
176
         }
177
 
178
         // Update the change log
179
         changeLog.Notes = newList;
180
         changeLog.Update();
181
      }
182
 
2147 ghuddy 183
 
184
      /// <summary>
185
      /// Rid a string of any : char because we use that as a delimiter in the change log and so we 
186
      /// do not want a users use of the character to confuse the change log display mechanism.
187
      /// </summary>
188
      /// <param name="s"></param>
189
      /// <returns></returns>
190
      private string NO_COLONS(string s)
191
      {
192
         string sc =  s.Replace(':', ' ');
193
         sc = sc.Replace('\r' , ' ');
194
         sc = sc.Replace('\n' , ' ');
195
 
196
         return sc;
197
      }
2141 ghuddy 198
 
199
 
200
      /// <summary>
201
      /// A method that imports requirements from a ReqPro database into EA for the purpose
202
      /// of supporting requirement-to-design traceability.
203
      /// </summary>
204
      /// <param name="repository"></param>
205
      private void ImportFromReqPro(EA.Repository ea_repository)
206
      {
207
         try
208
         {
209
            //IFormatProvider cultureInfo = new CultureInfo("en-US", true);
210
 
211
            string importDateTime = System.TimeZone.CurrentTimeZone.ToUniversalTime( System.DateTime.Now ).ToString();
212
 
213
            ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "EA Requirement import at " + importDateTime, -1 );
214
 
215
            // Update the ReqProDB stereotypes element with all the EA requirements in the package
2145 ghuddy 216
            base.RQ_Artifact.UpdatePackageToReqProDatabaseAssociation(ea_repository, base.RQ_Element);
2141 ghuddy 217
 
218
            // Get a list of EA requirements and their associated ReqPro GUIDs
219
            ArrayList ea_reqs = new ArrayList();
220
            ArrayList ea_GUIDs = new ArrayList();
221
            ArrayList ea_req_matched = new ArrayList();
2145 ghuddy 222
            foreach (EA.Connector connector in base.RQ_Element.Connectors)
2141 ghuddy 223
            {
224
               EA.Element ea_req = ea_repository.GetElementByID( connector.SupplierID );
225
               if (ea_req != null)
226
               {
227
                  ea_reqs.Add(ea_req);
228
                  string GUID = EA_Utils.ReadTag(ea_req, "GUID");
229
                  ea_GUIDs.Add(GUID);
230
                  ea_req_matched.Add(false);
231
               }
232
            }
233
 
234
            // Obtain the EA parent package so that we can create under it an import package
235
            // if need be.
2145 ghuddy 236
            EA.Package parentPackage = ea_repository.GetPackageByID( base.RQ_Element.PackageID );
2141 ghuddy 237
 
238
            EA.Package importPackage = (EA.Package )parentPackage.Packages.AddNew( "import " + importDateTime, "Package");
239
            importPackage.Update();
240
 
241
            EA.Element changeLog = (EA.Element)importPackage.Elements.AddNew("Change Log","InformationItem");
242
            changeLog.Update();
243
 
244
            // Get a flattened list of requirements from the hierarchical data the user has filtered
245
            ArrayList rq_req_collection = new ArrayList();
246
            get_rq_req_collection(ea_repository, ref rq_req_collection);
247
 
248
            int newRequirementCount = 0;
249
            int modifiedRequirementCount = 0;
250
            int statusUpdatedRequirementCount = 0;
251
            int orphanedCount = 0;
252
 
253
 
254
            // loop through all of the ReqPro requirements
255
            foreach(ReqPro_object rq_obj in rq_req_collection)
256
            {
257
               try
258
               {
259
                  // Find which EA requirement element refers to the current ReqPro GUID
260
                  int i_ea_req;
261
                  i_ea_req = ea_GUIDs.IndexOf( rq_obj.guid );
262
 
263
                  // If EA element was found
264
                  if (0 <= i_ea_req)
265
                  {
266
                     ea_req_matched[i_ea_req] = true;
267
 
268
                     EA.Element ea_req = ((EA.Element)ea_reqs[i_ea_req]);
269
 
270
                     // This ReqPro requirement already has a counterpart in EA, so we must simply
271
                     // update the counterpart. But, to aid the designer, we need to try to tell them
2145 ghuddy 272
                     // how the requirement has changed, which could ofcoarse change the meaning 
273
                     // of the requirement and require design changes to be done.
2141 ghuddy 274
 
275
                     bool meaningMayHaveChanged = false;
276
                     bool statusMayHaveChanged = false;
277
 
278
                     string ea_req_name = rq_obj.tag + " " + rq_obj.name;
279
 
280
                     if ( ea_req.Name.CompareTo(ea_req_name) != 0 )
281
                     {
2147 ghuddy 282
                        changeLog.Notes += ea_req.ElementGUID + ":Name:" + NO_COLONS(ea_req.Name) + ":" + NO_COLONS(ea_req_name) + "\r\n";
2141 ghuddy 283
                        changeLog.Update();
284
                        meaningMayHaveChanged = true;
285
                        ea_req.Name  = ea_req_name;
286
                     }
287
 
288
                     if ( ea_req.Notes.CompareTo(rq_obj.text) != 0 )
289
                     {
2147 ghuddy 290
                        changeLog.Notes += ea_req.ElementGUID + ":Notes:" + NO_COLONS(ea_req.Notes) + ":" + NO_COLONS(rq_obj.text) + "\r\n";
2141 ghuddy 291
                        changeLog.Update();
292
                        meaningMayHaveChanged = true;
293
                        ea_req.Notes = rq_obj.text;
294
                     }
295
 
296
                     if (ea_req.Difficulty != rq_obj.difficulty)
297
                     {
298
                        changeLog.Notes += ea_req.ElementGUID + ":Difficulty:" + ea_req.Difficulty + ":" + rq_obj.difficulty + "\r\n";
299
                        changeLog.Update();
300
                        statusMayHaveChanged = true;
301
                        ea_req.Difficulty    = rq_obj.difficulty;
302
                     }
303
                     if (ea_req.Priority != rq_obj.priority)
304
                     {
305
                        changeLog.Notes += ea_req.ElementGUID + ":Priority:" + ea_req.Priority + ":" + rq_obj.priority + "\r\n";
306
                        changeLog.Update();
307
                        statusMayHaveChanged = true;
308
                        ea_req.Priority      = rq_obj.priority;
309
                     }
310
                     if (ea_req.Version != rq_obj.version)
311
                     {
312
                        changeLog.Notes += ea_req.ElementGUID + ":Version:" + ea_req.Version + ":" + rq_obj.version + "\r\n";
313
                        changeLog.Update();
314
                        statusMayHaveChanged = true;
315
                        ea_req.Version       = rq_obj.version;
316
                     }
317
                     if (ea_req.Status != rq_obj.status)
318
                     {
319
                        changeLog.Notes += ea_req.ElementGUID + ":Status:" + ea_req.Status + ":" + rq_obj.status + "\r\n";
320
                        changeLog.Update();
321
                        statusMayHaveChanged = true;
322
                        ea_req.Status        = rq_obj.status;
323
                     }
324
 
325
                     ea_req.Update();
326
 
327
                     if (meaningMayHaveChanged)
328
                     {
329
                        modifiedRequirementCount++;
330
                     }
331
 
332
                     if (statusMayHaveChanged)
333
                     {
334
                        statusUpdatedRequirementCount++;
335
                     }
336
                  }
337
                  else
338
                  {
339
                     // This ReqPro requirement does not have a counterpart in EA, so we must create
340
                     // a new one.
341
                     newRequirementCount++;
342
 
343
                     // create the new EA requirement in the import package
344
                     EA.Element ea_req = (EA.Element)importPackage.Elements.AddNew( rq_obj.tag + " " + rq_obj.name, "Requirement");
345
                     ea_req.Notes = rq_obj.text;
346
 
347
                     ea_req.Difficulty = rq_obj.difficulty;
348
                     ea_req.Priority   = rq_obj.priority;
349
                     ea_req.Version    = rq_obj.version;
350
                     ea_req.Status     = rq_obj.status;
351
 
352
                     EA_Utils.WriteTag(ea_req, "GUID", rq_obj.guid);
353
                     EA_Utils.WriteTag(ea_req, "TAG", rq_obj.tag);
354
                     ea_req.Update();
355
 
356
                     // Connect the new requirement to the ea_rq_artifact
2145 ghuddy 357
                     base.RQ_Artifact.add_connection(ea_repository, base.RQ_Element, ea_req);
2141 ghuddy 358
 
359
                     changeLog.Notes += ea_req.ElementGUID + ":Created:" + ea_req.Name + "\r\n";
360
                     changeLog.Update();
361
                  }
362
 
363
               }
364
               catch (Exception ex)
365
               {
366
                  ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Exception (ImportFromReqPro), " + ex.Message + ", " + rq_obj.name, -1);
367
               }
368
            }
369
 
370
 
371
            // Now check for orphaned EA requirements
372
            for (int i = 0; i < ea_GUIDs.Count; i++)
373
            {
374
               string rq_GUID = (string)ea_GUIDs[i];
375
               if (rq_GUID != "")
376
               {
377
                  if ((bool)ea_req_matched[i] == false)
378
                  {
379
                     EA.Element ea_req = (EA.Element)ea_reqs[i];
380
 
381
                     orphanedCount++;
382
 
383
                     changeLog.Notes += ea_req.ElementGUID + ":Orphaned:" + ea_req.Name + "\r\n";
384
                     changeLog.Update();
385
                  }
386
               }
387
            }
388
 
389
            displayChangeLog(ea_repository, changeLog);
390
 
391
            ea_repository.RefreshModelView(parentPackage.PackageID);
392
 
2145 ghuddy 393
            // display summary stats
2141 ghuddy 394
            ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, newRequirementCount.ToString() + " new requirements", -1);
395
            ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, modifiedRequirementCount.ToString() + " requirements modified", -1);
396
            ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, statusUpdatedRequirementCount.ToString() + " requirements had status changes", -1);
397
            ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, orphanedCount.ToString() + " requirements were orphaned", -1);
398
 
399
            ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Completed import", -1);
400
 
401
            MessageBox.Show("Import Completed");
402
         }
403
         catch (Exception ex)
404
         {
405
            MessageBox.Show(ex.Message, "Error (ImportFromReqPro)", MessageBoxButtons.OK);
406
         }
407
      }
408
 
409
 
410
 
411
 
412
      /// <summary>
413
      /// This method (along with its sibling overload) obtains a flattened view of the 
414
      /// hierarchical requirements obtained from the ReqPro database. This accumulation
415
      /// takes account of the users filtering requests.
416
      /// </summary>
417
      /// <param name="ea_repository"></param>
418
      private void get_rq_req_collection(EA.Repository ea_repository, ref ArrayList rq_req_collection)
419
      {
420
         foreach( ReqPro_object sub_obj in rq_root_package.ReqPro_objects )
421
         {
422
            get_rq_req_collection(ea_repository, ref rq_req_collection, sub_obj);
423
         }
424
      }
425
 
426
      private void get_rq_req_collection(EA.Repository ea_repository,
427
                                         ref ArrayList rq_req_collection,
428
                                         ReqPro_object rq_obj )
429
      {
430
         if (rq_obj.isPackage)
431
         {
2147 ghuddy 432
            // if the package is not filtered, or if we are allowed to dig beneath filtered
433
            // packages...
434
            if (rq_obj.filtered == false || base.allowPackageStructureFragments)
2141 ghuddy 435
            {
436
               // Using recursion, scan this objects sub-objects
437
               foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
438
               {
2147 ghuddy 439
                  // if the sub-object is a package, always recurse to process it, else
440
                  // if the sub-object is a requirement, only recurse if the containing package
441
                  // is not filtered, so that requirements of filtered packages are themselves
442
                  // filtered out by virtue of their parent packages filtering state.
443
                  if (  sub_obj.isPackage
444
                     || (sub_obj.isRequirement && rq_obj.filtered == false))
445
                  {
446
                     get_rq_req_collection(ea_repository, ref rq_req_collection, sub_obj);
447
                  }
2141 ghuddy 448
               }
449
            }
450
         }
451
         else if (rq_obj.isRequirement)
452
         {
453
            if ( ! (reqTypeIsFiltered(rq_obj) || reqStatusTypeIsFiltered(rq_obj)) )
454
            {
455
               // Add this requirement to the flattened list we are accumulating
456
               rq_req_collection.Add(rq_obj);
457
 
2147 ghuddy 458
               // Using recursion, scan this objects sub-objects, which in practise will all
459
               // be requirement objects. At this time requirement objects cannot have packages 
460
               // as children.
2141 ghuddy 461
               foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
462
               {
463
                  get_rq_req_collection(ea_repository, ref rq_req_collection, sub_obj);
464
               }
465
            }
466
         }
467
      }
468
 
469
 
470
	}
471
}