Subversion Repositories DevTools

Rev

Rev 2171 | 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;
2151 ghuddy 2
using System.Text;
3
using System.Globalization;
4
using System.Collections;
5
using System.Windows.Forms;
2141 ghuddy 6
using ReqPro40;
7
 
8
 
9
namespace EA_ReqPro
10
{
11
 
12
	/// <summary>
2173 ghuddy 13
   /// ImportReqProDatabase is a specialisation of CopyReqProDatabaseToMemory, designed to copy the
14
   /// ReqPro database content into an EA database, discarding the structure of and hierarchy of
2155 ghuddy 15
   /// packages, selecting just the requirements found in the ReqPro database for storage into EA,
16
   /// where they will be used for design traceability purposes.
2141 ghuddy 17
	/// </summary>
2155 ghuddy 18
   public class ImportReqProDatabase : CopyReqProDatabaseToMemory
19
   {
2167 ghuddy 20
      private struct req_lists_t
21
      {
22
         public ArrayList ea_reqs;
23
         public ArrayList ea_GUIDs;
24
         public ArrayList new_ea_reqs;
25
         public ArrayList new_ea_GUIDs;
2173 ghuddy 26
         public ArrayList orphaned_ea_reqs;
2167 ghuddy 27
      };
28
 
2173 ghuddy 29
      private req_lists_t gReq_lists = new req_lists_t();
2167 ghuddy 30
 
2151 ghuddy 31
      private int totalRequirements = 0;
32
 
2167 ghuddy 33
      private EA.Package gCurrentPackage = null;
34
      private EA.Package gNewReqProDBPackage = null;
35
      private EA.Package gChangeHistoryPackage = null;
36
      private EA.Package gOrphansPackage = null;
37
 
2173 ghuddy 38
      private int gNewRequirementCount = 0;
39
      private int gModifiedRequirementCount = 0;
40
      private int gStatusUpdatedRequirementCount = 0;
41
      private int gOrphanedCount = 0;
2167 ghuddy 42
 
2173 ghuddy 43
      private EA.Element gChangeLog = null;
44
 
2141 ghuddy 45
      /// <summary>
46
      /// Constructor logic
47
      /// </summary>
48
      /// <param name="ea_repository"></param>
2151 ghuddy 49
      public ImportReqProDatabase(): base()
2155 ghuddy 50
      {
2151 ghuddy 51
         totalRequirements = 0;
2155 ghuddy 52
      }
2141 ghuddy 53
 
54
 
55
      /// <summary>
56
      /// Method to parse a ReqPro database using the information in a ReqProDB artifact,
57
      /// assumed to be selected in EA's project browser prior to the method call.
58
      /// </summary>
59
      /// <param name="ea_repository"></param>
60
      /// <returns></returns>
2155 ghuddy 61
      public override bool prompt_and_parse(ReqProDB_Artifact.MODE mode, out bool cancelled)
2151 ghuddy 62
      {
2155 ghuddy 63
         cancelled = false;
64
 
2151 ghuddy 65
         try
66
         {
2155 ghuddy 67
            base.structure_only = false;
68
 
69
            string importDateTime = System.DateTime.Now.ToString();
70
 
71
            Main.WriteOutput("EA Requirement import at " + importDateTime, -1 );
72
            Main.WriteOutput("",-1);
73
 
74
            if (true == base.prompt_and_parse(mode, out cancelled))
2151 ghuddy 75
            {
76
               if (Main.mustAbort)
77
                  return false;
78
 
79
               Main.EA_Repository.EnsureOutputVisible(Main.GUI_OUTPUT_TAB_NAME);
80
 
81
               // Configure the ReqProDB artifact as a traceability artifact
82
               RQ_Artifact.set_traceability_mode(RQ_Element);
83
 
2155 ghuddy 84
               ImportFromReqPro(importDateTime);
2151 ghuddy 85
 
86
               return true;
87
            }
88
         }
89
         catch (Exception ex)
90
         {
2153 ghuddy 91
            Main.MessageBoxException(ex, "Exception (parse)");
2173 ghuddy 92
         }
2155 ghuddy 93
 
2151 ghuddy 94
         return false;
95
      }
96
 
2167 ghuddy 97
 
2141 ghuddy 98
      /// <summary>
99
      /// Displays the content of the change log element to the output trace display. This method must
100
      /// be kept in sync with the ImportFromReqPro method, obviously.
101
      /// </summary>
102
      /// <param name="ea_repository"></param>
2151 ghuddy 103
      /// <param name="changeLog"></param>
104
      public void displayChangeLog(EA.Element changeLog)
2141 ghuddy 105
      {
2167 ghuddy 106
         Main.WriteOutput("Displaying Import Change Log", -1);
2141 ghuddy 107
 
2167 ghuddy 108
         if (changeLog.Notes == null || changeLog.Notes.Length == 0 || changeLog.Notes.Trim().Length == 0)
109
         {
110
            Main.WriteOutput("  No changes", -1);
111
         }
112
         else
113
         {
114
            // The change log element contains all the log in its notes section. Break it up into
115
            // lines, because each line is a single log entry, so that we can process them one at
116
            // a time.
117
            string delimStr = "\n";
118
            char [] delim = delimStr.ToCharArray();
119
            string[] log_strings = changeLog.Notes.Split(delim,2000);
2141 ghuddy 120
 
121
 
2167 ghuddy 122
            // modify delimiters to : character so that we can extract the parameters for each log entry
123
            delimStr = ":";
124
            delim = delimStr.ToCharArray();
2141 ghuddy 125
 
2167 ghuddy 126
            foreach(string s in log_strings)
127
            {
128
               if (Main.mustAbort)
129
                  break;
2151 ghuddy 130
 
2167 ghuddy 131
               // over time, users may delete the orphaned requirements from the EA database, but their
2173 ghuddy 132
               // GUIDs will still exist in the change log. Use of such a GUID will cause
2167 ghuddy 133
               // an exception in the GetElementByGuid() function. What should we do? We can attempt
134
               // to remove those GUIDs from the list. We can do this by accumulating a new list of GUIDs
2173 ghuddy 135
               // that is formed from the old list, where only good items from the old list find their
2167 ghuddy 136
               // way into the new list. Gradually, the list is wittled away as EA users delete orphaned
137
               // requirements having first dealt with the design change impacts that resulted from their
138
               // orphanage.
139
               try
2141 ghuddy 140
               {
2167 ghuddy 141
                  if (s.StartsWith("{"))
142
                  {
143
                     string trimmed_s = s.Trim();
2141 ghuddy 144
 
2167 ghuddy 145
                     // Get log entry;s parameters.
146
                     string[] parameters = trimmed_s.Split(delim, 10);
2141 ghuddy 147
 
2167 ghuddy 148
                     // The first parameter is the GUID so use it to get the requirement element
149
                     EA.Element ea_req = Main.EA_Repository.GetElementByGuid(parameters[0]);
2141 ghuddy 150
 
2167 ghuddy 151
                     // Now discriminate actions based on the second parameter
2141 ghuddy 152
 
2167 ghuddy 153
                     if (parameters[1].StartsWith("Created"))
2141 ghuddy 154
                     {
2167 ghuddy 155
                        Main.WriteOutput("  Created : " + ea_req.Name, ea_req.ElementID );
156
                     }
157
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
158
                     else if (parameters[1].StartsWith("Orphaned"))
159
                     {
160
                        Main.WriteOutput("  Orphaned : " + ea_req.Name, ea_req.ElementID );
2159 ghuddy 161
 
2167 ghuddy 162
                        foreach (EA.Connector theConnector in ea_req.Connectors)
163
                        {
164
                           int destId = -1;
2159 ghuddy 165
 
2167 ghuddy 166
                           // we dont care about direction of relationship, so test for both
167
                           if (theConnector.ClientID == ea_req.ElementID)
168
                              destId = theConnector.SupplierID;
169
                           else if (theConnector.SupplierID == ea_req.ElementID)
170
                              destId = theConnector.ClientID;
2173 ghuddy 171
                           else
2167 ghuddy 172
                              destId = theConnector.SupplierID;
173
 
174
                           // and make sure we filter out self-referential connectors
175
                           if (destId != ea_req.ElementID)
2141 ghuddy 176
                           {
2167 ghuddy 177
                              EA.Package tgt_pkg = (EA.Package)Main.EA_Repository.GetPackageByID( destId );
178
                              if (tgt_pkg != null)
2159 ghuddy 179
                              {
2167 ghuddy 180
                                 Main.WriteOutput("     --> " + tgt_pkg.Name, tgt_pkg.PackageID);
2159 ghuddy 181
                              }
2167 ghuddy 182
                              else
183
                              {
184
                                 EA.Element tgt_ele = (EA.Element)Main.EA_Repository.GetElementByID( destId );
185
                                 if (tgt_ele != null)
186
                                 {
187
                                    //if (!tgt_ele.Type.StartsWith("Requirement"))
188
                                    Main.WriteOutput("     --> " + tgt_ele.Name, tgt_ele.ElementID);
189
                                 }
190
                              }
2159 ghuddy 191
                           }
2141 ghuddy 192
                        }
193
                     }
2167 ghuddy 194
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
195
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_NAME))
196
                     {
197
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_NAME, ea_req.Name), ea_req.ElementID );
198
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
199
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
200
                     }
201
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
202
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_NOTES)) // aka Description of the requirement
203
                     {
204
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", "Description", ea_req.Name), ea_req.ElementID );
205
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
206
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
207
                     }
208
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
209
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_DIFFICULTY))
210
                     {
211
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_DIFFICULTY, ea_req.Name), ea_req.ElementID );
212
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
213
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
214
                     }
215
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
216
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_PRIORITY))
217
                     {
218
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_PRIORITY, ea_req.Name), ea_req.ElementID );
219
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
220
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
221
                     }
222
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
223
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_VERSION))
224
                     {
225
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_VERSION, ea_req.Name), ea_req.ElementID );
226
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
227
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
228
                     }
229
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
230
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_STATUS))
231
                     {
232
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_STATUS, ea_req.Name), ea_req.ElementID );
233
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
234
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
235
                     }
236
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
237
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_SUBSYSTEM_TYPE))
238
                     {
239
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_SUBSYSTEM_TYPE, ea_req.Name), ea_req.ElementID );
240
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
241
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
242
                     }
243
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
244
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_STABILITY))
245
                     {
246
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_STABILITY, ea_req.Name), ea_req.ElementID );
247
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
248
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
249
                     }
250
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
251
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_REQ_TYPE))
252
                     {
253
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_REQ_TYPE, ea_req.Name), ea_req.ElementID );
254
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
255
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
256
                     }
257
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
258
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_SOURCE_VERSION))
259
                     {
260
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_SOURCE_VERSION, ea_req.Name), ea_req.ElementID );
261
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
262
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
263
                     }
264
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
265
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_SOURCE_SECTION))
266
                     {
267
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_SOURCE_SECTION, ea_req.Name), ea_req.ElementID );
268
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
269
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
270
                     }
271
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
272
                     else if (parameters[1].StartsWith(Constants.CHG_LOG_SOURCE))
273
                     {
274
                        Main.WriteOutput(string.Format("  Modified {0}: {1}", Constants.CHG_LOG_SOURCE, ea_req.Name), ea_req.ElementID );
275
                        Main.WriteOutput("     <<< " + parameters[2], ea_req.ElementID);
276
                        Main.WriteOutput("     >>> " + parameters[3], ea_req.ElementID);
277
                     }
2141 ghuddy 278
                  }
279
               }
2167 ghuddy 280
               catch
281
               {
282
               }
2141 ghuddy 283
            }
284
         }
285
      }
286
 
2147 ghuddy 287
 
288
      /// <summary>
2173 ghuddy 289
      /// Rid a string of any : char because we use that as a delimiter in the change log and so we
2147 ghuddy 290
      /// do not want a users use of the character to confuse the change log display mechanism.
291
      /// </summary>
292
      /// <param name="s"></param>
293
      /// <returns></returns>
294
      private string NO_COLONS(string s)
295
      {
296
         string sc =  s.Replace(':', ' ');
297
         sc = sc.Replace('\r' , ' ');
298
         sc = sc.Replace('\n' , ' ');
2173 ghuddy 299
 
2147 ghuddy 300
         return sc;
301
      }
2151 ghuddy 302
 
303
 
2155 ghuddy 304
 
305
 
2151 ghuddy 306
      /// <summary>
307
      /// A method that imports requirements from a ReqPro database into EA for the purpose
308
      /// of supporting requirement-to-design traceability.
309
      /// </summary>
310
      /// <param name="repository"></param>
2155 ghuddy 311
      private void ImportFromReqPro(string importDateTime)
2151 ghuddy 312
      {
313
         try
314
         {
2167 ghuddy 315
            DialogResult dlgres;
316
 
317
            // begin to initialise some of our element lists
2173 ghuddy 318
            gReq_lists.new_ea_reqs = new ArrayList();
319
            gReq_lists.new_ea_GUIDs = new ArrayList();
320
            gReq_lists.ea_GUIDs = new ArrayList();
321
            gReq_lists.orphaned_ea_reqs = new ArrayList();
2167 ghuddy 322
 
2151 ghuddy 323
            ArrayList ea_req_matched = new ArrayList();
324
 
2167 ghuddy 325
            // Obtain the EA parent package so that we can create under it our ReqProDB structure and change history packages
2151 ghuddy 326
            EA.Package parentPackage = Main.EA_Repository.GetPackageByID( base.RQ_Element.PackageID );
327
 
2167 ghuddy 328
            // Find or create the change history package in which to store change logs
329
            gChangeHistoryPackage = find_or_create_change_history_package(parentPackage);
330
 
331
            // create the ReqProDB structure package in the parent container package, and attach it to its counterpart
332
            // in the ReqPro_object tree structure (ie. attach it to the root node therein).
333
            gNewReqProDBPackage = (EA.Package)parentPackage.Packages.AddNew( "ReqProDB " + importDateTime, "Package");
334
            gNewReqProDBPackage.Update();
335
            rq_root_package.ea_element_ID = gNewReqProDBPackage.PackageID;
336
 
337
            // Migrate the older form of import directory and change log, into the newer format
338
            migrate_old_import_packages_to_change_history_package(parentPackage);
339
            Main.EA_Repository.RefreshModelView(parentPackage.PackageID);
340
 
341
            if (Main.mustAbort)
342
               return;
343
 
344
            // Create a package to hold orphans. This will be removed later on if it ends up empty.
345
            gOrphansPackage = find_or_create_orphans_package(parentPackage);
346
 
347
            // Get a list of EA requirements that already exist under the overall ReqProDB container package
2151 ghuddy 348
            ArrayList allowedElementTypes = new ArrayList();
349
            allowedElementTypes.Add("Requirement");
350
            allowedElementTypes.Add("UseCase");
351
 
2155 ghuddy 352
            Main.WriteOutput("Acquiring list of elements already in EA", -1);
2169 ghuddy 353
            EA_ElementAccumulator reqLister = new EA_ElementAccumulator(allowedElementTypes);
354
            EA_Parsing.findAndProcessPackageElements( parentPackage, reqLister, true );
2151 ghuddy 355
 
2173 ghuddy 356
            gReq_lists.ea_reqs = reqLister.Elements;
2167 ghuddy 357
 
2151 ghuddy 358
            if (Main.mustAbort)
359
               return;
360
 
2173 ghuddy 361
            // For the list we just found, get an adjacent list of the associated ReqPro GUIDs.
2167 ghuddy 362
            // The two lists will be indexable by the same index.
2173 ghuddy 363
            foreach (EA.Element ea_req in gReq_lists.ea_reqs)
2151 ghuddy 364
            {
2155 ghuddy 365
               string GUID = EA_TaggedValues.Read(ea_req, Constants.TAG_GUID);
2173 ghuddy 366
               gReq_lists.ea_GUIDs.Add(GUID);
2151 ghuddy 367
               ea_req_matched.Add(false);
368
            }
369
 
370
            if (Main.mustAbort)
371
               return;
372
 
373
 
2167 ghuddy 374
            // Create the change log element in the change history package
2173 ghuddy 375
            gChangeLog = (EA.Element)gChangeHistoryPackage.Elements.AddNew("Change Log" + " - import " + importDateTime, "InformationItem");
376
            gChangeLog.Notes = "";
377
            gChangeLog.TreePos = gChangeHistoryPackage.Elements.Count - 1;
378
            gChangeLog.Update();
2151 ghuddy 379
 
380
            // Get a flattened list of requirements from the hierarchical data the user has filtered
381
            ArrayList rq_req_collection = new ArrayList();
382
            get_rq_req_collection(ref rq_req_collection);
383
 
2167 ghuddy 384
            // initialise some statistical vars
2173 ghuddy 385
            gNewRequirementCount = 0;
386
            gModifiedRequirementCount = 0;
387
            gStatusUpdatedRequirementCount = 0;
388
            gOrphanedCount = 0;
2151 ghuddy 389
 
390
 
2155 ghuddy 391
            Main.WriteOutput("Merging ReqPro content to EA", -1);
2167 ghuddy 392
 
393
            // loop through all of the ReqPro requirements we have captured from the ReqPro database
2151 ghuddy 394
            foreach(ReqPro_object rq_obj in rq_req_collection)
395
            {
396
               if (Main.mustAbort)
397
                  break;
398
 
399
               try
400
               {
401
                  // Find which EA requirement element refers to the current ReqPro GUID
402
                  int i_ea_req;
2173 ghuddy 403
                  i_ea_req = gReq_lists.ea_GUIDs.IndexOf( rq_obj.guid );
2151 ghuddy 404
 
405
                  // If EA element was found
406
                  if (0 <= i_ea_req)
407
                  {
2173 ghuddy 408
                     // update orphanage detection data
2151 ghuddy 409
                     ea_req_matched[i_ea_req] = true;
2173 ghuddy 410
                     rq_obj.matched = true;
2151 ghuddy 411
 
2173 ghuddy 412
                     EA.Element ea_req = ((EA.Element)gReq_lists.ea_reqs[i_ea_req]);
2151 ghuddy 413
 
414
                     rq_obj.ea_element_ID = ea_req.ElementID;
415
 
2155 ghuddy 416
                     // Only update the requirement if it was not mastered in EA, or
417
                     // unrestricted imports have been enabled
418
                     if (  (false == EA_TaggedValues.Read(ea_req, Constants.TAG_CREATED_IN_EA, Constants.DEFAULT_CREATED_IN_EA))
419
                        || (true == EA_TaggedValues.Read(ea_req, Constants.TAG_UNRESTRICTED_IMPORTS, Constants.DEFAULT_UNRESTRICTED_IMPORTS)) )
420
                     {
421
                        // This ReqPro requirement already has a counterpart in EA, so we must simply
422
                        // update the counterpart. But, to aid the designer, we need to try to tell them
2173 ghuddy 423
                        // how the requirement has changed, which could ofcoarse change the meaning
2155 ghuddy 424
                        // of the requirement and require design changes to be done.
2151 ghuddy 425
 
2155 ghuddy 426
                        bool meaningMayHaveChanged = false;
427
                        bool statusMayHaveChanged = false;
2173 ghuddy 428
 
2155 ghuddy 429
                        string ea_req_name = rq_obj.tag + " " + rq_obj.name;
2151 ghuddy 430
 
2155 ghuddy 431
                        Main.WriteOutput("Updating: " + ea_req_name, rq_obj.ea_element_ID);
2151 ghuddy 432
 
2173 ghuddy 433
                        ea_req.Name       = updated_property_value_if_changed(gChangeLog, ea_req, ea_req.Name, Constants.CHG_LOG_NAME, ea_req_name, ref meaningMayHaveChanged);
2151 ghuddy 434
 
2173 ghuddy 435
                        ea_req.Notes      = updated_property_value_if_changed(gChangeLog, ea_req, ea_req.Notes, Constants.CHG_LOG_NOTES, rq_obj.text, ref meaningMayHaveChanged);
2151 ghuddy 436
 
2173 ghuddy 437
                        ea_req.Difficulty = updated_property_value_if_changed(gChangeLog, ea_req, ea_req.Difficulty, Constants.CHG_LOG_DIFFICULTY, rq_obj.difficulty, ref statusMayHaveChanged);
2151 ghuddy 438
 
2173 ghuddy 439
                        ea_req.Priority   = updated_property_value_if_changed(gChangeLog, ea_req, ea_req.Priority, Constants.CHG_LOG_PRIORITY, rq_obj.priority, ref statusMayHaveChanged);
2151 ghuddy 440
 
2173 ghuddy 441
                        ea_req.Status     = updated_property_value_if_changed(gChangeLog, ea_req, ea_req.Status, Constants.CHG_LOG_STATUS, rq_obj.status, ref statusMayHaveChanged);
2155 ghuddy 442
 
2173 ghuddy 443
                        if_tagged_value_changed_update_it(gChangeLog, ea_req, Constants.TAG_SOURCE, Constants.CHG_LOG_SOURCE, rq_obj.source, ref statusMayHaveChanged);
2155 ghuddy 444
 
2173 ghuddy 445
                        if_tagged_value_changed_update_it(gChangeLog, ea_req, Constants.TAG_SOURCE_VERSION, Constants.CHG_LOG_SOURCE_VERSION, rq_obj.sourceVersion, ref statusMayHaveChanged);
2155 ghuddy 446
 
2173 ghuddy 447
                        if_tagged_value_changed_update_it(gChangeLog, ea_req, Constants.TAG_SOURCE_SECTION, Constants.CHG_LOG_SOURCE_SECTION, rq_obj.sourceSection, ref statusMayHaveChanged);
2155 ghuddy 448
 
2173 ghuddy 449
                        if_tagged_value_changed_update_it(gChangeLog, ea_req, Constants.TAG_SUBSYSTEM, Constants.CHG_LOG_SUBSYSTEM_TYPE, rq_obj.subsystem, ref statusMayHaveChanged);
2155 ghuddy 450
 
2173 ghuddy 451
                        if_tagged_value_changed_update_it(gChangeLog, ea_req, Constants.TAG_STABILITY, Constants.CHG_LOG_STABILITY, rq_obj.stability, ref statusMayHaveChanged);
2155 ghuddy 452
 
453
                        // Requirement Types are actually implemented using ordinary EA element stereotypes.
2161 ghuddy 454
                        string[] sar = ea_req.StereotypeEx.Split(",".ToCharArray());
2167 ghuddy 455
 
456
                        // if we didnt get a requirement type from the ReqPro database, set it to an empty string so that it can
457
                        // be compared to the EA stereotype strings.
458
                        if (rq_obj.type == null)
459
                           rq_obj.type = "";
460
 
2161 ghuddy 461
                        if (sar.Length > 0)
2155 ghuddy 462
                        {
2161 ghuddy 463
                           // The first item in the stereotype list is the one on display in the EA element properties and so is the one the user
464
                           // thinks is assigned to the requirement element, so check against that for changes
465
                           string sar0 = sar[0].Trim();
466
 
467
                           if (!sar0.Equals(rq_obj.type))
468
                           {
2173 ghuddy 469
                              gChangeLog.Notes += ea_req.ElementGUID + ":" + Constants.CHG_LOG_REQ_TYPE + ":" + sar0 + ":" + rq_obj.type + "\r\n";
470
                              gChangeLog.Update();
2161 ghuddy 471
                              statusMayHaveChanged = true;
472
                              ea_req.StereotypeEx = rq_obj.type;
473
                              ea_req.Stereotype = rq_obj.type;
474
                           }
475
                        }
476
                        else if (!ea_req.Stereotype.Equals(rq_obj.type))
477
                        {
2173 ghuddy 478
                           gChangeLog.Notes += ea_req.ElementGUID + ":" + Constants.CHG_LOG_REQ_TYPE + ":" + ea_req.Stereotype + ":" + rq_obj.type + "\r\n";
479
                           gChangeLog.Update();
2155 ghuddy 480
                           statusMayHaveChanged = true;
2157 ghuddy 481
                           ea_req.StereotypeEx = rq_obj.type;
482
                           ea_req.Stereotype = rq_obj.type;
2155 ghuddy 483
                        }
484
 
485
                        ea_req.Update();
486
 
487
                        if (meaningMayHaveChanged)
488
                        {
2173 ghuddy 489
                           gModifiedRequirementCount++;
2155 ghuddy 490
                        }
2173 ghuddy 491
 
2155 ghuddy 492
                        if (statusMayHaveChanged)
493
                        {
2173 ghuddy 494
                           gStatusUpdatedRequirementCount++;
2155 ghuddy 495
                        }
496
 
497
                        totalRequirements++;
2151 ghuddy 498
                     }
499
                  }
500
                  else
501
                  {
2173 ghuddy 502
                     // update orphanage detection data
503
                     rq_obj.matched = true;
504
 
2151 ghuddy 505
                     totalRequirements++;
506
 
507
                     // This ReqPro requirement does not have a counterpart in EA, so we must create
508
                     // a new one.
2173 ghuddy 509
                     gNewRequirementCount++;
2151 ghuddy 510
 
511
                     // create the new EA requirement in the import package
2167 ghuddy 512
                     EA.Element ea_req = (EA.Element)gChangeHistoryPackage.Elements.AddNew( rq_obj.tag + " " + rq_obj.name, "Requirement");
2151 ghuddy 513
 
514
                     rq_obj.ea_element_ID = ea_req.ElementID;
515
 
2155 ghuddy 516
                     CopyReqProDatabase.copyReq(ea_req, rq_obj);
2151 ghuddy 517
 
2155 ghuddy 518
                     ea_req.Notes = rq_obj.text;
519
 
2151 ghuddy 520
                     ea_req.Update();
521
 
2167 ghuddy 522
                     // add the new requirement to our list for later processing
2173 ghuddy 523
                     gReq_lists.new_ea_reqs.Add(ea_req);
524
                     gReq_lists.new_ea_GUIDs.Add(rq_obj.guid);
2167 ghuddy 525
 
2173 ghuddy 526
                     gChangeLog.Notes += ea_req.ElementGUID + ":Created:" + ea_req.Name + "\r\n";
527
                     gChangeLog.Update();
2151 ghuddy 528
 
2155 ghuddy 529
                     Main.WriteOutput("Created: " + ea_req.Name, ea_req.ElementID);
2151 ghuddy 530
                  }
2173 ghuddy 531
 
2151 ghuddy 532
               }
533
               catch (Exception ex)
534
               {
2155 ghuddy 535
                  Main.WriteOutput("Exception (ImportFromReqPro), " + ex.Message + ", " + rq_obj.name, -1);
2151 ghuddy 536
               }
537
            }
538
 
539
            if (Main.mustAbort)
540
               return;
541
 
2155 ghuddy 542
            Main.WriteOutput("Checking for orphaned requirements", -1);
2167 ghuddy 543
 
2173 ghuddy 544
            // Now do initial check for orphaned EA requirements
545
            for (int i = 0; i < gReq_lists.ea_GUIDs.Count; i++)
2151 ghuddy 546
            {
547
               if (Main.mustAbort)
548
                  break;
549
 
2173 ghuddy 550
               string rq_GUID = (string)gReq_lists.ea_GUIDs[i];
2151 ghuddy 551
               if (rq_GUID != "")
552
               {
553
                  if ((bool)ea_req_matched[i] == false)
554
                  {
2173 ghuddy 555
                     EA.Element ea_req = (EA.Element)gReq_lists.ea_reqs[i];
2151 ghuddy 556
 
2173 ghuddy 557
                     add_to_orphan_list(ref ea_req);
2151 ghuddy 558
                  }
559
               }
560
            }
561
 
2173 ghuddy 562
            // Now we import the ReqPro database package structure and migrate all of our existing or
2167 ghuddy 563
            // new requirements into it. We only create the structure we need, ie. empty package structure
564
            // will not be created unecessarily.
565
            Main.WriteOutput("Importing latest ReqPro database package structure", -1);
566
            populate_latest_reqprodb_structure_package(rq_root_package);
567
            gNewReqProDBPackage.Packages.Refresh();
568
            gNewReqProDBPackage.Elements.Refresh();
569
            gNewReqProDBPackage.Diagrams.Refresh();
2151 ghuddy 570
            Main.EA_Repository.RefreshModelView(parentPackage.PackageID);
571
 
2167 ghuddy 572
            if (Main.mustAbort)
573
               return;
574
 
2173 ghuddy 575
            // If there is any change to report, ask user if they want to see it now, and if so, display it
576
            if (gChangeLog.Notes != null && gChangeLog.Notes.Length > 0)
577
            {
578
               dlgres = MessageBoxEx.Show("Display Change Log?", "Change Log", MessageBoxButtons.YesNo);
579
               if (dlgres == DialogResult.Yes)
580
                  displayChangeLog(gChangeLog);
581
            }
582
 
583
            if (Main.mustAbort)
584
               return;
585
 
586
 
587
            // Take care of orphaned packages that have been orphaned due to a reduction in the scope of import.
588
            //Main.WriteOutput("Re-locating orphaned requirements (if any)", -1);
589
            //foreach (EA.Element ea_req_orphaned in ea_reqs_orphaned)
590
            //{
591
            //   ea_req_orphaned.PackageID = gOrphansPackage.PackageID;
592
            //   ea_req_orphaned.Update();
593
            //}
594
 
2167 ghuddy 595
            // Remove the old superseded facsimile of the ReqPro database package structure. At this point,
596
            // orphaned requirements left in these will be moved to the Orphaned package, before the old
597
            // structure package is removed.
598
            Main.WriteOutput("Removing old ReqPro database package structures", -1);
599
            remove_old_empty_structures(parentPackage, gNewReqProDBPackage);
600
 
601
            if (Main.mustAbort)
602
               return;
603
 
604
            // Remove other empty packages - this tidies up the ReqPro import area so that at the top level
605
            // all a user should see is the Change History package, ReqProDB package, and possibly an Orphans package.
606
            Main.WriteOutput("Pruning empty packages", -1);
607
 
608
            prune_empty_packages(parentPackage);
609
 
610
            // Refresh the project browser
611
            Main.EA_Repository.RefreshModelView(parentPackage.PackageID);
612
 
2149 ghuddy 613
            // Setup the internal requirement to requirement connectivity. This is seperate from the browser
614
            // organisation of elements in EA, but since in ReqPro, that organisation tells part of the story
615
            // of requirement to requirement connectivity, it is mirrored in the internal connectivity, along
616
            // with explicit trace relationships setup in ReqPro.
617
            // The purpose of this internal connectivity is to support relationship matrix tables in documentation
618
            // generated by EA_DocGen, or to support diagrammatic representations of the requirements in EA,
619
            // where the connectivity will become apparent through links ajoining the requirement elements in the
620
            // diagram.
2151 ghuddy 621
            write_traces(totalRequirements);
2141 ghuddy 622
 
2151 ghuddy 623
            if (Main.mustAbort)
624
               return;
2141 ghuddy 625
 
2167 ghuddy 626
            // Output any messages the underlying parser may have collected as a result of observations it has made
627
            // regarding the data it has read from the ReqPro database.
2155 ghuddy 628
            writeDelayedMessages();
2173 ghuddy 629
 
2151 ghuddy 630
            // display summary stats
2173 ghuddy 631
            Main.WriteOutput(gNewRequirementCount.ToString() + " new requirements", -1);
632
            Main.WriteOutput(gModifiedRequirementCount.ToString() + " requirements modified", -1);
633
            Main.WriteOutput(gStatusUpdatedRequirementCount.ToString() + " requirements had status changes", -1);
634
            Main.WriteOutput(gOrphanedCount.ToString() + " requirements were orphaned", -1);
2151 ghuddy 635
 
2155 ghuddy 636
            Main.WriteOutput("Import Completed", -1);
637
            MessageBoxEx.Show("Import Completed");
2173 ghuddy 638
 
2151 ghuddy 639
         }
640
         catch (Exception ex)
641
         {
2153 ghuddy 642
            Main.MessageBoxException(ex, "Exception (ImportFromReqPro)");
2151 ghuddy 643
         }
644
      }
645
 
2173 ghuddy 646
      private string updated_property_value_if_changed(EA.Element changeLog,
647
         EA.Element ea_req,
648
         string dest_value,
649
         string changeLogName,
2155 ghuddy 650
         string source_value,
651
         ref bool mayHaveChanged)
652
      {
653
         if (dest_value.CompareTo(source_value) != 0 )
654
         {
655
            changeLog.Notes += ea_req.ElementGUID + ":" + changeLogName+ ":" + NO_COLONS(dest_value) + ":" + NO_COLONS(source_value) + "\r\n";
656
            changeLog.Update();
657
            mayHaveChanged = true;
658
            return source_value;
659
         }
660
         return dest_value;
661
      }
2151 ghuddy 662
 
2167 ghuddy 663
 
2173 ghuddy 664
      private void if_tagged_value_changed_update_it(EA.Element changeLog,
665
         EA.Element ea_req,
666
         string tagname,
667
         string changeLogName,
2155 ghuddy 668
         string source_value,
669
         ref bool statusMayHaveChanged)
670
      {
671
         string value = EA_TaggedValues.Read(ea_req, tagname, "");
672
         if ((source_value != null) && (false == source_value.Equals(value)))
673
         {
674
            changeLog.Notes += ea_req.ElementGUID + ":" + changeLogName + ":" + value + ":" + source_value + "\r\n";
675
            changeLog.Update();
676
            EA_TaggedValues.Write(ea_req, tagname, source_value);
677
            statusMayHaveChanged = true;
678
         }
679
      }
2151 ghuddy 680
 
681
 
2155 ghuddy 682
 
2141 ghuddy 683
      /// <summary>
2173 ghuddy 684
      /// This method (along with its sibling overload) obtains a flattened view of the
2141 ghuddy 685
      /// hierarchical requirements obtained from the ReqPro database. This accumulation
686
      /// takes account of the users filtering requests.
687
      /// </summary>
688
      /// <param name="ea_repository"></param>
2151 ghuddy 689
      private void get_rq_req_collection(ref ArrayList rq_req_collection)
2141 ghuddy 690
      {
691
         foreach( ReqPro_object sub_obj in rq_root_package.ReqPro_objects )
692
         {
2151 ghuddy 693
            get_rq_req_collection(ref rq_req_collection, sub_obj);
2141 ghuddy 694
         }
695
      }
696
 
2167 ghuddy 697
 
2151 ghuddy 698
      private void get_rq_req_collection(ref ArrayList rq_req_collection,
2141 ghuddy 699
                                         ReqPro_object rq_obj )
700
      {
701
         if (rq_obj.isPackage)
702
         {
2147 ghuddy 703
            // if the package is not filtered, or if we are allowed to dig beneath filtered
704
            // packages...
705
            if (rq_obj.filtered == false || base.allowPackageStructureFragments)
2141 ghuddy 706
            {
707
               // Using recursion, scan this objects sub-objects
708
               foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
709
               {
2147 ghuddy 710
                  // if the sub-object is a package, always recurse to process it, else
711
                  // if the sub-object is a requirement, only recurse if the containing package
712
                  // is not filtered, so that requirements of filtered packages are themselves
713
                  // filtered out by virtue of their parent packages filtering state.
714
                  if (  sub_obj.isPackage
715
                     || (sub_obj.isRequirement && rq_obj.filtered == false))
716
                  {
2151 ghuddy 717
                     get_rq_req_collection(ref rq_req_collection, sub_obj);
2147 ghuddy 718
                  }
2141 ghuddy 719
               }
720
            }
721
         }
722
         else if (rq_obj.isRequirement)
723
         {
724
            if ( ! (reqTypeIsFiltered(rq_obj) || reqStatusTypeIsFiltered(rq_obj)) )
725
            {
726
               // Add this requirement to the flattened list we are accumulating
727
               rq_req_collection.Add(rq_obj);
728
 
2149 ghuddy 729
               // In ReqPro, a requirement can be related to another requirement in several ways:
2173 ghuddy 730
               // 1. By virtue of its position relative to another in the browser display. That is,
731
               //    if you place a requirement beneath a parent requirement, you are establishing a
2149 ghuddy 732
               //    parent-child relationship.
733
               // 2. By virtue of a specific TraceTo relationship being made via the Traceability menu
2173 ghuddy 734
               //    option.
2149 ghuddy 735
               // Interestingly, ReqPro prevents you creating a relationship of one of the above types,
736
               // if a relationship of the other type already exists. This implies that the relationship
737
               // between a parent and child requirement must be singular and is important regardless
738
               // of the manner in which it was created or represented.
739
               // The CopyReqProDatabaseToMemory base class will already have taken care of recording
740
               // relationships detected from ReqPro made using method 2 above. What we need to do here is
741
               // take care of those apparent from the browser based hierarchical organisation (ie. made
742
               // in ReqPro using method 1).
2173 ghuddy 743
               // All we need to do is grab the parent object (if any) and add the GUID of the child to
2149 ghuddy 744
               // its list of trace-to's. Later on, the write_traces() class method will turn these into
745
               // EA based connection objects that belong to the parent requirement elements.
746
               if (rq_obj.parent != null)
747
               {
748
                  rq_obj.parent.ReqPro_traces.Add(rq_obj.guid);
749
               }
750
 
2147 ghuddy 751
               // Using recursion, scan this objects sub-objects, which in practise will all
2173 ghuddy 752
               // be requirement objects. At this time requirement objects cannot have packages
2147 ghuddy 753
               // as children.
2141 ghuddy 754
               foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
755
               {
2151 ghuddy 756
                  get_rq_req_collection(ref rq_req_collection, sub_obj);
2141 ghuddy 757
               }
758
            }
759
         }
760
      }
761
 
762
 
2167 ghuddy 763
 
764
 
765
 
766
 
767
      /// <summary>
2173 ghuddy 768
      /// Populates a ReqProDB structure package to be used as a home for the requirements within the
2167 ghuddy 769
      /// overall import container, and re-locate requirements into it from wherever they may be elsewhere
770
      /// within and under the import container.
771
      /// </summary>
772
      /// <param name="rq_obj"></param>
773
      private void populate_latest_reqprodb_structure_package(ReqPro_object rq_obj)
774
      {
775
         foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
776
         {
777
            if (Main.mustAbort)
778
               return;
779
 
780
            if (sub_obj.isPackage)
781
            {
782
               populate_latest_reqprodb_structure_package(sub_obj);   // recurse
783
            }
784
            else if (sub_obj.isRequirement)
785
            {
786
               EA.Element ea_req = null;
787
 
788
               // Examine all of our requirement lists to try and re-locate the requirements from
789
               // the old structure(s) to the new one.
790
 
791
               // re-locate existing requirements updated during this import
792
               int i_ea_req;
2173 ghuddy 793
               i_ea_req = gReq_lists.ea_GUIDs.IndexOf( sub_obj.guid );
2167 ghuddy 794
               if (0 <= i_ea_req)
795
               {
2173 ghuddy 796
                  ea_req = ((EA.Element)gReq_lists.ea_reqs[i_ea_req]);
2167 ghuddy 797
 
798
                  EA.Package pkg = get_or_create_latest_structure(sub_obj);
799
 
2173 ghuddy 800
                  if (sub_obj.matched == false)
801
                  {
802
                     add_to_orphan_list(ref ea_req);
803
 
804
                     ea_req.PackageID = gOrphansPackage.PackageID;   // re-locate
805
                     ea_req.Update();
806
                  }
807
                  else if (sub_obj.filtered == false)
808
                  {
809
                     ea_req.PackageID = pkg.PackageID;   // re-locate
810
                     ea_req.TreePos = sub_obj.treePos;
811
                     ea_req.Update();
812
                  }
813
                  else
814
                  {
815
                     // QUESTION: So what if it is filtered? What happens to it then?
816
                     // Will it stay in the same place or be relocated as an orphan?
817
                     // ANSWER: relocate_elements_to_orphans_package() does this, called later
818
                     // in the import sequence.
819
                  }
2167 ghuddy 820
               }
821
               else
822
               {
823
                  // re-locate new requirements that have come in for the first time on this import.
2173 ghuddy 824
                  i_ea_req = gReq_lists.new_ea_GUIDs.IndexOf( sub_obj.guid );
2167 ghuddy 825
                  if (0 <= i_ea_req)
826
                  {
2173 ghuddy 827
                     ea_req = ((EA.Element)gReq_lists.new_ea_reqs[i_ea_req]);
2167 ghuddy 828
 
829
                     EA.Package pkg = get_or_create_latest_structure(sub_obj);
2173 ghuddy 830
 
2167 ghuddy 831
                     ea_req.PackageID = pkg.PackageID;   // re-locate
832
                     ea_req.TreePos = sub_obj.treePos;
833
                     ea_req.Update();
834
                  }
835
               }
836
 
837
               // Re-locate requirement under its parent requirement, if such a relationship exists.
838
               if (ea_req != null && sub_obj.parent.isRequirement)
839
               {
2173 ghuddy 840
                  // Only do this if the parent requirement has not been orphaned or filtered out of the import
2171 ghuddy 841
                  if (sub_obj.parent.ea_element_ID != -1)
2167 ghuddy 842
                  {
2171 ghuddy 843
                     EA.Element parent_ea_req = Main.EA_Repository.GetElementByID(sub_obj.parent.ea_element_ID);
844
                     if (parent_ea_req != null)
845
                     {
2173 ghuddy 846
                        // make sure we only assign ele-to-ele relationship if both elements are in the same
847
                        // package
848
                        if (ea_req.PackageID == parent_ea_req.PackageID)
849
                        {
850
                           ea_req.ParentID = parent_ea_req.ElementID;   // re-locate
851
                           ea_req.TreePos = sub_obj.treePos;
852
                           ea_req.Update();
853
                        }
2171 ghuddy 854
                     }
2167 ghuddy 855
                  }
2171 ghuddy 856
                  else
857
                  {
858
                     // TODO: what if the parent requirement has been orphaned, but the child as represented by
859
                     // the current value of sub_obj has not been? Will that have already been taken care of by
860
                     // the code earlier in this function that re-locates existing requirements to the correct
861
                     // parent package?
862
                  }
2167 ghuddy 863
               }
864
 
865
               populate_latest_reqprodb_structure_package(sub_obj);   // recurse
866
            }
867
         }
868
      }
869
 
870
 
871
      /// <summary>
872
      /// This is a helper for the populate_latest_reqprodb_structure_package() function. It allows on-the-fly
2173 ghuddy 873
      /// EA package path construction, triggered whenever we find we have a requirement to
2167 ghuddy 874
      /// re-locate into the latest facsimile of the ReqPro database structure.
875
      /// </summary>
876
      /// <param name="rq_obj"></param>
877
      /// <returns></returns>
878
      private EA.Package get_or_create_latest_structure(ReqPro_object rq_obj)
879
      {
880
         // go up the tree to find the immediate enclosing package of the requirement represented
881
         // by the input parameter. We do this because it is certain that this function will be called
882
         // initially passing a ReqPro_object that has "isRequirement" set to true. The requirement object
883
         // may also be nested within another requirement object, as a result of its parent-child hierarchy
884
         // in ReqPro.
885
         while(rq_obj.isRequirement && rq_obj.parent != null)
886
         {
887
            rq_obj = rq_obj.parent;
888
         }
889
 
890
         // Now that we have reached a package, we can figure out if we need to create its facsimile in EA
891
         // or detect if that has already been done on a previous invocation.
892
         if (rq_obj.isPackage)
893
         {
894
            // if this package has already been related to an EA package, then simply return it. The EA package
895
            // must have been created ona  previous invocation of this function.
896
            if (rq_obj.ea_element_ID != -1)
897
            {
898
               return Main.EA_Repository.GetPackageByID(rq_obj.ea_element_ID);
899
            }
900
            else // need to create this package, and if necessary, its parental line right up to the root package
901
            {
902
               // use recursion to work our way up the package ancestral line until we hit a point where
903
               // we find an EA package, then unwind, creating the sub-packages down to where our requirement
904
               // is to be held.
905
               EA.Package pkg = get_or_create_latest_structure(rq_obj.parent);   // recurse
906
               if (pkg != null)
907
               {
908
                  if (rq_obj.filtered)
909
                  {
910
                     return pkg;
911
                  }
912
                  else
913
                  {
2169 ghuddy 914
                     EA.Package sub_pkg = EA_Package.create(pkg, rq_obj.name, rq_obj.treePos);
2167 ghuddy 915
 
916
                     // attach the EA package to the ReqPro_object so that we do not attempt to create this
917
                     // package again on another call into this function.
918
                     rq_obj.ea_element_ID = sub_pkg.PackageID;
919
 
920
                     return sub_pkg;
921
                  }
922
               }
923
            }
924
         }
925
 
926
         // default to returning the root level package in EA where the requirement structure begins.
927
         // This will always be valid and available, but hopefully, the execution path wont drop down
928
         // to here.
929
         return Main.EA_Repository.GetPackageByID(rq_root_package.ea_element_ID);
930
      }
931
 
932
      /// <summary>
2173 ghuddy 933
      /// Remove the old ReqProDB structure packages if they are now empty of requirements. IF some
2167 ghuddy 934
      /// requirements remain in them, they are moved to the orphaned package so that the old ReqProDB
935
      /// packages can be removed.
936
      /// </summary>
937
      /// <param name="parentPackage"></param>
938
      /// <param name="new_structure_pkg"></param>
939
      private void remove_old_empty_structures(EA.Package parentPackage, EA.Package new_structure_pkg)
940
      {
941
         // NOTE: The parentPackage is the container of the ReqProDB element
942
         short i;
943
         for(i=0; i<parentPackage.Packages.Count; i++)
944
         {
945
            gCurrentPackage = (EA.Package)parentPackage.Packages.GetAt(i);
946
 
947
            // dont do anything to the new structure package that has been created on the current import cycle.
948
            if (new_structure_pkg != null && gCurrentPackage.PackageID == new_structure_pkg.PackageID)
949
            {
950
               continue;
951
            }
952
 
953
            // skip any packages that are not ReqProDB structure packages
954
            if (!gCurrentPackage.Name.StartsWith("ReqProDB"))
955
            {
956
               continue;
957
            }
958
 
959
            // re-locate all elements to the orphans package
960
            relocate_elements_to_orphans_package(gCurrentPackage);
961
 
962
            // Now delete the old ReqProDB structure package
963
            parentPackage.Packages.DeleteAt(i, false);
964
         }
2173 ghuddy 965
 
2167 ghuddy 966
         parentPackage.Packages.Refresh();
967
         Main.EA_Repository.RefreshModelView(parentPackage.PackageID);
968
      }
969
 
970
 
971
      /// <summary>
2173 ghuddy 972
      /// Re-locate all requirements that remain under a ReqProDB structure package, to its
2167 ghuddy 973
      /// top level, so that later on, the package hierarchy within it can be removed.
974
      /// </summary>
975
      /// <param name="parentPackage"></param>
976
      private void relocate_elements_to_orphans_package(EA.Package parentPackage)
977
      {
978
         if (parentPackage.PackageID != gOrphansPackage.PackageID)
979
         {
980
            // relocate elements and diagrams to the top level of the orphans package
981
            foreach(EA.Element ele in parentPackage.Elements)
982
            {
983
               ele.PackageID = gOrphansPackage.PackageID;
984
               ele.Update();
985
            }
986
            foreach(EA.Diagram diag in parentPackage.Diagrams)
987
            {
988
               diag.PackageID = gOrphansPackage.PackageID;
989
               diag.Update();
990
            }
991
 
992
            // now parse lower level packages in the tree
993
            foreach(EA.Package sub_pkg in parentPackage.Packages)
994
            {
995
               relocate_elements_to_orphans_package(sub_pkg);  // recurse
996
            }
997
         }
998
      }
999
 
1000
 
1001
      /// <summary>
1002
      /// This function migrates the older form of import package and its change log file into the newer
1003
      /// Change History package, and deletes the old import package. In doing this, it will move any
1004
      /// requirements still remaining in the import package to the top level of the new ReqProDB structure
1005
      /// package.
1006
      /// </summary>
1007
      /// <param name="parentPackage"></param>
1008
      private void migrate_old_import_packages_to_change_history_package(EA.Package parentPackage)
1009
      {
1010
         if (gNewReqProDBPackage != null && gChangeHistoryPackage != null)
1011
         {
1012
            bool found = false;
1013
            short i;
1014
            for(i=0; i<parentPackage.Packages.Count; i++)
1015
            {
1016
               EA.Package sub_pkg = (EA.Package)parentPackage.Packages.GetAt(i);
1017
 
1018
               if (sub_pkg.Name.StartsWith("import"))
1019
               {
1020
                  if (!found)
1021
                  {
1022
                     found = true;
1023
                     Main.WriteOutput("Migrating old import package contents to Change History and ReqProDB packages", -1);
1024
                  }
1025
 
1026
                  // re-locate all elements from the old import package to the new ReqProDB structure package.
1027
                  migrate_old_import_packages_to_change_history_package_recurser(sub_pkg);
1028
 
1029
                  // delete the old import package
1030
                  parentPackage.Packages.DeleteAt(i, false);
1031
               }
1032
            }
1033
            parentPackage.Packages.Refresh();
1034
            Main.EA_Repository.RefreshModelView(parentPackage.PackageID);
1035
         }
1036
      }
1037
 
1038
      /// <summary>
1039
      /// Moves all elements out of an old-style import package, and into the new ReqProDB structure package.
2173 ghuddy 1040
      /// Change Log elements are handled in a special way such that they are renamed from plain "Change Log"
2167 ghuddy 1041
      /// to the new style "Change Log - import <date> <time>" format, and are moved into the new "Change History"
1042
      /// package.
1043
      /// </summary>
1044
      /// <param name="parentPackage"></param>
1045
      private void migrate_old_import_packages_to_change_history_package_recurser(EA.Package parentPackage)
1046
      {
1047
         foreach(EA.Element ele in parentPackage.Elements)
1048
         {
1049
            if (ele.Name.StartsWith("Change Log"))
1050
            {
1051
               ele.Name = ele.Name + " - " + parentPackage.Name;
1052
               ele.PackageID = gChangeHistoryPackage.PackageID;
1053
               ele.Update();
1054
               gChangeHistoryPackage.Elements.Refresh();
1055
            }
1056
            else
1057
            {
1058
               ele.PackageID = gNewReqProDBPackage.PackageID;
1059
               ele.Update();
1060
            }
1061
         }
1062
 
1063
         foreach(EA.Diagram diag in parentPackage.Diagrams)
1064
         {
1065
            diag.PackageID = gNewReqProDBPackage.PackageID;
1066
            diag.Update();
1067
         }
1068
 
1069
         foreach(EA.Package sub_pkg in parentPackage.Packages)
1070
         {
1071
            migrate_old_import_packages_to_change_history_package_recurser(sub_pkg);   // recurse
1072
         }
1073
      }
1074
 
1075
 
1076
      private EA.Package find_or_create_change_history_package(EA.Package parentPackage)
1077
      {
1078
         foreach(EA.Package sub_pkg in parentPackage.Packages)
1079
         {
1080
            if (sub_pkg.Name.StartsWith("Change History"))
1081
            {
1082
               return sub_pkg;
1083
            }
1084
         }
2169 ghuddy 1085
         EA.Package pkg = EA_Package.create(parentPackage, "Change History", 1);
2167 ghuddy 1086
         return pkg;
1087
      }
1088
 
1089
      private EA.Package find_or_create_orphans_package(EA.Package parentPackage)
1090
      {
1091
         foreach(EA.Package sub_pkg in parentPackage.Packages)
1092
         {
1093
            if (sub_pkg.Name.StartsWith("Orphaned Requirements"))
1094
            {
1095
               return sub_pkg;
1096
            }
1097
         }
2169 ghuddy 1098
         EA.Package pkg = EA_Package.create(parentPackage, "Orphaned Requirements", 1);
2167 ghuddy 1099
         return pkg;
1100
      }
1101
 
1102
 
1103
      /// <summary>
2173 ghuddy 1104
      /// This function removes any empty packages it can find in the ReqPro import area. This is
2167 ghuddy 1105
      /// a tidying up operation.
1106
      /// </summary>
1107
      /// <param name="parentPackage"></param>
1108
      /// <returns></returns>
1109
      private bool prune_empty_packages(EA.Package parentPackage)
1110
      {
1111
         bool retVal = false;
1112
         bool needRefresh = false;
1113
         short i;
1114
         for(i=0; i<parentPackage.Packages.Count; i++)
1115
         {
1116
            EA.Package sub_pkg = (EA.Package)parentPackage.Packages.GetAt(i);
1117
 
1118
            if (true == prune_empty_packages(sub_pkg))   // recurse
1119
            {
1120
               parentPackage.Packages.DeleteAt(i, false);
1121
               needRefresh = true;
1122
            }
1123
         }
1124
 
1125
         if (needRefresh)
1126
         {
1127
            parentPackage.Packages.Refresh();
1128
         }
1129
 
2173 ghuddy 1130
         if (parentPackage.Packages.Count == 0
2167 ghuddy 1131
            && parentPackage.Elements.Count == 0
1132
            && parentPackage.Diagrams.Count == 0)
1133
         {
1134
            retVal = true;
1135
         }
1136
 
1137
         return retVal;
1138
      }
2173 ghuddy 1139
 
1140
      private void add_to_orphan_list(ref EA.Element ea_req)
1141
      {
1142
         if (!gReq_lists.orphaned_ea_reqs.Contains(ea_req.ElementID))
1143
         {
1144
            gReq_lists.orphaned_ea_reqs.Add(ea_req.ElementID);
1145
 
1146
            gOrphanedCount++;
1147
            gChangeLog.Notes += ea_req.ElementGUID + ":Orphaned:" + ea_req.Name + "\r\n";
1148
            gChangeLog.Update();
1149
         }
1150
      }
1151
 
2141 ghuddy 1152
	}
2173 ghuddy 1153
 
1154
 
2141 ghuddy 1155
}