Subversion Repositories DevTools

Rev

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