Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
2155 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
namespace EA_ReqPro
9
{
10
	/// <summary>
11
   /// ExportToReqProDatabase is a specialisation of CopyReqProDatabaseToMemory, designed to copy the 
12
   /// ReqPro database content into memory, and allow a user to select certain aspects to control a
13
   /// subsequent export operation.
14
	/// </summary>
15
	public class ExportToReqProDatabase : CopyReqProDatabaseToMemory
16
	{
17
      private ReqPro_object m_SelectedObject;
18
      private bool m_CreateFolder;
19
      private string m_FolderName;
20
      private string m_ReqType;
21
      private ExportForm.ExportExtent m_ExportExtent;
22
 
23
      private static char [] numbers = "0123456789".ToCharArray();
24
      private static char [] letters = "abcdefghijklmnopqrstuvwxyABCDEFGHIJKLMNOPQRSTUVWXY".ToCharArray();
25
 
26
		public ExportToReqProDatabase()
27
		{
28
		}
29
 
30
 
31
      /// <summary>
32
      /// Method to parse a ReqPro database using the information in a ReqProDB artifact,
33
      /// assumed to be selected in EA's project browser prior to the method call.
34
      /// </summary>
35
      /// <param name="ea_repository"></param>
36
      /// <returns></returns>
37
      public override bool prompt_and_parse(ReqProDB_Artifact.MODE mode, out bool cancelled)
38
      {
39
         cancelled = false;
40
 
41
         try
42
         {
43
            base.structure_only = true;
44
 
45
            string exportDateTime = System.DateTime.Now.ToString();
46
 
47
            Main.WriteOutput("EA Requirement export at " + exportDateTime, -1 );
48
            Main.WriteOutput("", -1);
49
 
50
            if (true == base.prompt_and_parse(mode, out cancelled))
51
            {
52
               if (Main.mustAbort)
53
                  return false;
54
 
55
               Main.EA_Repository.EnsureOutputVisible(Main.GUI_OUTPUT_TAB_NAME);
56
 
57
               // Configure the ReqProDB artifact as a traceability artifact, but only if it appeared
58
               // as though it were created for the first time during the export, otherwise leave
59
               // it alone with its existing setting.
60
               if (RQ_Artifact.get_mode(RQ_Element) == ReqProDB_Artifact.MODE.UNDEFINED)
61
                  RQ_Artifact.set_traceability_mode(RQ_Element);
62
 
63
               ExportToReqPro(exportDateTime, out cancelled);
64
 
65
               return true;
66
            }
67
         }
68
         catch (Exception ex)
69
         {
70
            Main.MessageBoxException(ex, "Exception (parse)");
71
         }      
72
 
73
         return false;
74
      }
75
 
76
 
77
      /// <summary>
78
      /// Method called by the base class to convey the user selections made controlling the export
79
      /// operation.
80
      /// </summary>
81
      /// <param name="selectedObject"></param>
82
      /// <param name="createFolder"></param>
83
      /// <param name="folderName"></param>
84
      /// <param name="requirementType"></param>
85
      /// <param name="requirementStatus"></param>
86
      protected override void provideExportDecisionsToClient(ReqPro_object selectedObject,
87
         bool createFolder,
88
         string folderName,
89
         string requirementType,
90
         ExportForm.ExportExtent exportExtent)
91
      {
92
         m_SelectedObject = selectedObject;
93
         m_CreateFolder = createFolder;
94
         m_FolderName = folderName;
95
 
96
         // The requirement type display string in the export form is like "some requirement type(abbrev)"
97
         // We want just the abbrev so use string splitting to extract it.
98
         char [] delim = {'('};
99
         string [] tokens = requirementType.Split(delim, 2);
100
         delim[0] = ')';
101
         m_ReqType = tokens[1].Split(delim,2)[0];
102
 
103
         m_ExportExtent = exportExtent;
104
      }
105
 
106
 
107
      private void ExportToReqPro(string exportDateTime, out bool cancelled)
108
      {
109
         cancelled = false;
110
 
111
         try
112
         {
113
            ArrayList ea_reqs;   // list of new requirements for export - assigned later from element accumulator
114
            ArrayList ea_mastered_reqs = new ArrayList();
115
            ArrayList ea_mastered_reqs_rp_guids = new ArrayList();
116
 
117
            // Read tag from ReqProDB element that enables/disables the capability to use EA as a master
118
            // repository for requirements originally created in EA. If the tag does not exist, EA mastering
119
            // will be allowed by default.
120
            bool EA_MasteringAllowed = EA_TaggedValues.Read(base.RQ_Element, Constants.TAG_EA_MASTERING_ALLOWED, Constants.DEFAULT_EA_MASTERING_ALLOWED);
121
 
122
            #region DETERMINE PARENT PACKAGE
123
            // Obtain the EA parent package so that we can scan it for existing requirement elements.
124
            EA.Package parentPackage;
125
            if (m_ExportExtent == ExportForm.ExportExtent.PACKAGE_REQS)
126
            {
127
               parentPackage = EA_Utilities.get_selected_package();
128
            }
129
            else 
130
            {
131
               // default to the ReqProDB container package. This is probably what most exports
132
               // will use.
133
               parentPackage = Main.EA_Repository.GetPackageByID( base.RQ_Element.PackageID );
134
            }
135
            #endregion
136
 
137
            #region GET_EXPORT_LIST
2157 ghuddy 138
            Main.WriteOutput("Acquiring list of requirement elements in EA", -1);
2155 ghuddy 139
 
140
            // setup the element types list to control the element accumulation
141
            ArrayList allowedElementTypes = new ArrayList();
142
            allowedElementTypes.Add("Requirement");
143
            //allowedElementTypes.Add("UseCase");
144
 
145
            if (m_ExportExtent != ExportForm.ExportExtent.SINGLE_REQ)
146
            {
147
               // create the element accumulator, and use it to find all the requirement
148
               // elements in the container package
149
               ElementAccumulator reqLister = new ElementAccumulator(allowedElementTypes);
150
               EA_Utilities.findAndProcessPackageElements( parentPackage, reqLister, true );
151
 
152
               if (Main.mustAbort)
153
                  return;
154
 
155
               // Remove requirements from the accumulated list if they have already been linked
156
               // to ReqPro requirement elements, by virtue of them seeming to have a valid GUID
157
               // We dont actually validate the GUID, just check that one is present or not.
158
               ea_reqs = reqLister.Elements; 
159
               int i_ea_reqs;
160
               for (i_ea_reqs = 0; i_ea_reqs < ea_reqs.Count; ) // No index increment here
161
               {
162
                  EA.Element ea_req = (EA.Element)ea_reqs[i_ea_reqs];
163
 
164
                  string GUID = EA_TaggedValues.Read(ea_req, Constants.TAG_GUID);
165
                  if (GUID != null && GUID.Length > 0 && GUID.StartsWith("{"))
166
                  {
167
                     // found an EA requirement element that seems to already be linked to a 
168
                     // ReqPro requirement element
169
 
170
                     // if the element seems to be one that was mastered (created) in EA and exported
171
                     // to ReqPro on a previous export cycle, then collect it in a seperate list in case
172
                     // we need to do an update on ReqPro later on.
173
                     if (true == EA_TaggedValues.Read(ea_req, Constants.TAG_CREATED_IN_EA, Constants.DEFAULT_CREATED_IN_EA))
174
                     {
175
                        ea_mastered_reqs.Add(ea_req);
176
                        ea_mastered_reqs_rp_guids.Add(GUID);
177
                     }
178
 
179
                     // discard from the export list.
180
                     ea_reqs.RemoveAt(i_ea_reqs);
181
                     continue;
182
                  }
183
                  i_ea_reqs++;   // index increment here
184
               }
185
 
186
               if (Main.mustAbort)
187
                  return;
188
            }
189
            else // user wants to export a single selected requirement
190
            {
191
               EA.Element ea_ele = EA_Utilities.get_selected_element(allowedElementTypes);
192
               if (ea_ele == null)
193
               {
194
                  MessageBoxEx.Show(
195
                     "The export extent chosen (single requirement export)\n" +
196
                     "is not compatible with the item selected in the EA\n" +
197
                     "project browser. You must select a requirement object\n" +
198
                     "to use this export extent.",
199
                     "Error");
200
                  cancelled = true;
201
                  return;
202
               }
203
 
204
               string GUID = EA_TaggedValues.Read(ea_ele, Constants.TAG_GUID);
205
               if (GUID != null && GUID.Length > 0 && GUID.StartsWith("{"))
206
               {
207
                  MessageBoxEx.Show(
208
                     "The requirement object selected in the EA project browser,\n" +
209
                     "already appears to be associated with a ReqPro object.",
210
                     "Error");
211
                  cancelled = true;
212
                  return;
213
               }
214
 
215
               ea_reqs = new ArrayList();
216
               ea_reqs.Add(ea_ele);
217
            }
218
            #endregion
219
 
220
            // Export newly mastered EA requirements to ReqPro
221
            if (false == export_new_EA_mastered_requirements(ref ea_reqs, ref ea_mastered_reqs, ref ea_mastered_reqs_rp_guids, out cancelled))
222
               return;
223
 
224
            // If the ReqProDB element informs us that EA mastering of requirements is allowed,
225
            // then we can process the update of any requirements in ReqPro that are linked to
226
            // requirements in EA, that seem to have originally been created in EA.
227
            if (EA_MasteringAllowed)
228
            {
229
               if (false == update_old_EA_mastered_requirements(ref ea_mastered_reqs, out cancelled))
230
                  return;
231
            }
232
 
233
            // Export/Update Requirement relationships
234
            export_new_EA_mastered_requirement_relationships(ref ea_reqs);
235
 
236
            if (EA_MasteringAllowed)
237
            {
238
               update_old_EA_mastered_requirement_relationships(ref ea_mastered_reqs);
239
            }
240
 
241
            Main.EA_Repository.RefreshModelView(parentPackage.PackageID);
242
 
243
            // Use historical data stored in the ReqProDB element to determine if any EA mastered requirements
244
            // have been deleted, leaving orphans in the ReqPro database that might need to be cleaned up
245
            report_orphaned_ReqPro_requirements(ref ea_mastered_reqs_rp_guids);
246
 
247
            Main.WriteOutput("Export Completed",-1);
248
            MessageBoxEx.Show("Export Completed");
249
         }
250
         catch (Exception ex)
251
         {
252
            Main.MessageBoxException(ex, "Exception (ExportToReqPro)");
253
         }
254
      }
255
 
256
 
257
      /// <summary>
258
      /// Exports newly EA mastered requirements to ReqPro
259
      /// </summary>
260
      /// <param name="ea_reqs"></param>
261
      /// <param name="ea_mastered_reqs"></param>
262
      /// <param name="ea_mastered_reqs_rp_guids"></param>
263
      /// <param name="cancelled"></param>
264
      /// <returns></returns>
265
      private bool export_new_EA_mastered_requirements(ref ArrayList ea_reqs, 
266
         ref ArrayList ea_mastered_reqs, 
267
         ref ArrayList ea_mastered_reqs_rp_guids, 
268
         out bool cancelled)
269
      {
270
         cancelled = false;
271
 
272
         // if there are any new requirements to export
273
         if (ea_reqs.Count > 0)
274
         {
275
            Main.WriteOutput(string.Format("Found {0} Requirements for export.", ea_reqs.Count), -1);
276
 
277
            ReqPro40.Requirements req_collection = ReqProDatabase.get_requirements();
278
            if (req_collection == null)
279
            {
280
               MessageBoxEx.Show("Could not acquire Requirement Collection\n" +
281
                  "from ReqPro database.\n", "Error");
282
               cancelled = true;
283
               return false;
284
            }
285
 
286
            ReqPro40.Package rp_pkg = null;
287
 
288
            // Obtain the ReqPro package selected by the user (if any)
289
            if (this.m_SelectedObject != null)
290
            {
291
               rp_pkg = ReqProDatabase.get_package(this.m_SelectedObject.iKey);
292
 
293
               if (this.m_CreateFolder)
294
               {
295
                  ReqPro40.Package rp_sub_pkg = ReqProDatabase.create_sub_package(rp_pkg, this.m_FolderName, "");
296
                  if (rp_sub_pkg != null)
297
                  {
298
                     rp_pkg = rp_sub_pkg;
299
                  }
300
               }
301
            }
302
 
303
            // process each requirement found in EA that needs exporting
304
            foreach(EA.Element ea_req in ea_reqs)
305
            {
306
               // get EA requirement without any temporary tag that the modeller may have given it
2157 ghuddy 307
               string tag = null;
308
               string ea_req_untagged_name = untaggedReqName(ea_req.Name, ref tag, false);
2155 ghuddy 309
 
310
               Main.WriteOutput("Exporting : " + ea_req.Name, ea_req.ElementID);
311
 
312
               // Add the requirement to ReqPro requirement collection
313
               ReqPro40.Requirement rp_req = ReqProDatabase.add_requirement(req_collection, ea_req_untagged_name, ea_req.Notes, this.m_ReqType);
314
               if (rp_req != null)
315
               {
316
                  // Get the tag for the new requirement from ReqPro and use it to form a new name for 
317
                  // the EA requirement. Note that at this point in time the tag has a pending form. It
318
                  // only becomes correct once we do a rq_req.Save() later on, so this update has to be
319
                  // repeated later. This first update is just to confirm that we can actually do an 
320
                  // update in EA, before we commit the changes to the ReqPro database.
321
                  string rp_req_tag = rp_req.get_Tag(ReqPro40.enumTagFormat.eTagFormat_FullTag);
322
 
323
                  ea_req.Name = rp_req_tag + " " + ea_req_untagged_name;
324
 
325
                  // Test that the EA requirement can be updated.
326
                  if (false == ea_req.Update())
327
                  {
328
                     MessageBoxEx.Show(
329
                        "Failed to update EA requirement element.\n" +
330
                        "Check that the EA model is writeable.\n" +
331
                        "Check that the EA model is not locked by another user.\n" +
332
                        "Check that the EA requirement element is not currently being edited.\n\n" +
333
                        "Cancelling export - please retry once checks have been performed.", "Error");
334
 
335
                     cancelled = true;
336
                     return false;
337
                  }
338
 
339
 
340
                  // Commit changes to ReqPro database
341
                  rp_req.Save();
342
 
343
                  // Now locate the new requirement under the selected package in ReqPro
344
                  if (rp_pkg != null)
345
                  {
346
                     rp_pkg.AddElement(rp_req, ReqPro40.enumPackageLookups.ePackageLookup_Object, ReqPro40.enumElementTypes.eElemType_Requirement);
347
                  }
348
 
349
                  // If the EA requirement has a parent requirement, then in ReqPro we must organise it such 
350
                  // that it has a parent-child hierarchical relationship
351
                  if (ea_req.ParentID != 0)
352
                  {
353
                     EA.Element parent_ea_req = Main.EA_Repository.GetElementByID(ea_req.ParentID);
354
                     if (parent_ea_req != null)
355
                     {
356
                        // get GUID of ReqPro parent requirement
357
                        string parent_guid = EA_TaggedValues.Read(parent_ea_req, Constants.TAG_GUID);
358
                        if (parent_guid != null && parent_guid.Length > 0 && parent_guid.StartsWith("{"))
359
                        {
360
                           // Get the parent ReqPro requirement
361
                           ReqPro40.Requirement parent_rp_req = ReqProDatabase.get_requirement_by_guid(parent_guid);
362
                           if (parent_rp_req != null)
363
                           {
364
                              // Establish relationship in ReqPro
365
                              rp_req.AssignParent(parent_rp_req, ReqPro40.enumRequirementLookups.eReqLookup_Object);
366
 
367
                              // Even though in EA, a parent-child relationship exists, we want to re-enforce that
368
                              // with a connection relationship too, so that when the parent and child exists on
369
                              // a diagram, they are shown linked together.
370
                              EA_Utilities.add_connection(parent_ea_req, ea_req);
371
                           }
372
                        }
373
                     }
374
                  }
375
 
376
                  // Now re-acquire the tag, which should no longer be in a pending form but have a real number
377
                  // assigned to it as a result of the commit we just did above.
378
                  rp_req_tag = rp_req.get_Tag(ReqPro40.enumTagFormat.eTagFormat_FullTag);
379
 
2157 ghuddy 380
                  // Attempt to set any attributes in the new ReqPro requirement. 
381
                  exportAttributes(rp_req, ea_req, rp_req_tag);
382
                  rp_req.Save();
383
 
2155 ghuddy 384
                  // Update the EA requirement for the second time, now with the correct and final tag
385
                  ea_req.Name = rp_req_tag + " " + ea_req_untagged_name;
386
                  ea_req.Update();
387
                  Main.WriteOutput("   (Re)Assigned Tag : " + ea_req.Name, ea_req.ElementID);
388
 
389
                  // Record the GUID and tag in EA tagged values. This will effectively bind the EA requirement
390
                  // to its new ReqPro requirement counterpart.
391
                  EA_TaggedValues.Write(ea_req, Constants.TAG_GUID, rp_req.GUID);
392
                  EA_TaggedValues.Write(ea_req, Constants.TAG_TAG, rp_req_tag);
393
 
394
                  // Save in the list of ReqPro GUIDs to support ReqPro orphaned requirement detection later on
395
                  ea_mastered_reqs_rp_guids.Add(rp_req.GUID);
396
 
397
                  // mark the requirement as having been created in EA.
398
                  EA_TaggedValues.Write(ea_req, Constants.TAG_CREATED_IN_EA, true);
399
 
400
                  // Update the ReqPro collection.
401
                  req_collection.Save();
402
               }
403
            }
404
 
405
            // Save details of the ReqPro package where the requirements were exported to. This info can be
406
            // used on the next export to auto-select the ReqPro destination package for the export, etc.
407
            if (rp_pkg != null)
408
            {
409
               EA_TaggedValues.Write(base.RQ_Element, Constants.TAG_LAST_EXPORT_GUID, rp_pkg.GUID);
410
               EA_TaggedValues.Write(base.RQ_Element, Constants.TAG_LAST_EXPORT_NAME, rp_pkg.Name);
411
            }
412
            else
413
            {
414
               // export occurred to the root package.
415
               EA_TaggedValues.Delete(base.RQ_Element, Constants.TAG_LAST_EXPORT_GUID);
416
               EA_TaggedValues.Delete(base.RQ_Element, Constants.TAG_LAST_EXPORT_NAME);
417
            }
418
         }
419
         else
420
         {
421
            Main.WriteOutput("Found no new requirements to add to ReqPro",-1);
422
         }
423
 
424
         Main.WriteSeperator();
425
         return true;
426
      }
427
 
428
 
429
      /// <summary>
430
      /// Updates ReqPro requirements that have masters in EA
431
      /// </summary>
432
      /// <param name="ea_mastered_reqs"></param>
433
      /// <param name="cancelled"></param>
434
      /// <returns></returns>
435
      private bool update_old_EA_mastered_requirements(ref ArrayList ea_mastered_reqs, 
436
         out bool cancelled)
437
      {
438
         cancelled = false;
439
 
440
         // if there are any EA mastered requirements...
441
         if (ea_mastered_reqs.Count > 0)
442
         {
443
            bool possibleOrphans = false;
444
 
445
            Main.WriteOutput(string.Format("Found {0} Requirements to update.", ea_mastered_reqs.Count), -1);
446
 
447
            ReqPro40.Requirements req_collection = ReqProDatabase.get_requirements();
448
 
449
            // process each EA mastered requirement
450
            int i_ea_mastered_reqs = 0;
451
            for (i_ea_mastered_reqs = 0; i_ea_mastered_reqs < ea_mastered_reqs.Count; ) // NOTE: no count increment done here
452
            {
453
               EA.Element ea_req = (EA.Element)ea_mastered_reqs[i_ea_mastered_reqs];
454
 
455
               // make sure there is a GUID
456
               string GUID = EA_TaggedValues.Read(ea_req, Constants.TAG_GUID);
457
               if (GUID != null && GUID.Length > 0 && GUID.StartsWith("{"))
458
               {
459
                  ReqPro40.Requirement rp_req;
460
 
461
                  // Try and find the requirement in ReqPro
462
                  rp_req = ReqProDatabase.get_requirement_by_guid(GUID);
463
                  if (rp_req != null)
464
                  {
465
                     // copy name and notes from EA to ReqPro
2157 ghuddy 466
                     string tag = null;
467
                     string ea_req_untagged_name = untaggedReqName(ea_req.Name, ref tag, true);
2155 ghuddy 468
 
469
                     // Test that the EA requirement can be updated.
470
                     ea_req.Name = ea_req_untagged_name;
471
                     ea_req.Update();
472
                     if (false == ea_req.Update())
473
                     {
474
                        MessageBoxEx.Show(
475
                           "Failed to update EA requirement element.\n" +
476
                           "Check that the EA model is writeable.\n" +
477
                           "Check that the EA model is not locked by another user.\n" +
478
                           "Check that the EA requirement element is not currently being edited.\n\n" +
479
                           "Cancelling export - please retry once checks have been performed.", "Error");
480
 
481
                        cancelled = true;
482
                        return false;
483
                     }
484
 
485
                     // copy content to the existing ReqPro requirement
486
                     rp_req.Name = ea_req_untagged_name;
487
                     rp_req.Text = ea_req.Notes;
488
 
2157 ghuddy 489
                     string rp_req_tag = rp_req.get_Tag(ReqPro40.enumTagFormat.eTagFormat_FullTag);
490
 
2155 ghuddy 491
                     // Attempt to set any attributes in the existing ReqPro requirement. 
2157 ghuddy 492
                     exportAttributes(rp_req, ea_req, rp_req_tag);
2155 ghuddy 493
 
494
                     // Commit changes to ReqPro database
495
                     rp_req.Save();
496
 
497
                     // Although we are allowing EA to be the master repository of requirements
498
                     // if they were originally created in EA, we still want to use ReqPro as the
499
                     // master for any numbering scheme (ie. tags), so update the EA requirements
500
                     // Tag as necessary.
501
                     ea_req.Name = rp_req_tag + " " + ea_req_untagged_name;
502
                     ea_req.Update();
503
                     EA_TaggedValues.Write(ea_req, Constants.TAG_TAG, rp_req_tag);
504
                     Main.WriteOutput("Updated : " + ea_req.Name, ea_req.ElementID);
505
                  }
506
                  else
507
                  {
508
                     possibleOrphans = true;
509
                     Main.WriteOutput("Warning, failed to find ReqPro requirement counterpart (possible orphan?)", ea_req.ElementID);
510
                  }
511
                  i_ea_mastered_reqs++;
512
               }
513
               else
514
               {
515
                  ea_mastered_reqs.RemoveAt(i_ea_mastered_reqs);
516
                  // do not increment i_ea_mastered_reqs after here
517
               }
518
            }
519
 
520
            Main.WriteSeperator();
521
 
522
            if (possibleOrphans == true)
523
            {
524
               Main.WriteOutput("", -1);
525
               Main.WriteOutput("One or more possible orphans have been found", -1);
526
               Main.WriteOutput("This could be the result of someone accidentally deleting the requirement", -1);
527
               Main.WriteOutput("in the ReqPro database. Or, it could be that someone modified the GUID tagged", -1);
528
               Main.WriteOutput("value in EA or ReqPro (very naughty).",-1);
529
               Main.WriteOutput("", -1);
530
               Main.WriteOutput("Going forward, if the requirement must be retained, delete all of its tagged values,", -1);
531
               Main.WriteOutput("in EA, remove the tag from its name, and attempt another export. The EA requirement will", -1);
532
               Main.WriteOutput("be given a new tag number, but at least it will re-appear in the ReqPro database.", -1);
533
               Main.WriteOutput("", -1);
534
               Main.WriteOutput("If the requirement is no longer needed, it can be deleted from EA once any design", -1);
535
               Main.WriteOutput("impacts are understood.", -1);
536
               Main.WriteSeperator();
537
            }
538
         }
539
         else
540
         {
541
            Main.WriteOutput("No ReqPro requirements need updating from their EA masters.",-1);
542
            Main.WriteSeperator();
543
         }
544
         return true;
545
      }
546
 
547
 
548
      /// <summary>
549
      /// Export relationships for the new requirements exported from EA
550
      /// </summary>
551
      /// <param name="ea_reqs"></param>
552
      private void export_new_EA_mastered_requirement_relationships(ref ArrayList ea_reqs)
553
      {
554
         // Algorithm design:
555
         //
556
         // for each new EA requirement (EA.Req) exported
557
         //   Get the ReqPro equivalent requirement (RP.Req)
558
         //   for each connector (EA.C) in EA.Req
559
         //      get referenced requirement (EA.RefReq) from EA.C
560
         //      find EA.RefReq's equivalent requirement (RP.RefReq) in ReqPro
561
         //      Establish a traces to relationship from RP.RefReq to RP.Req
562
 
563
         Main.WriteOutput("Creating Trace Relationships",-1);
564
 
565
         // for each new EA requirement (EA.Req) exported
566
         foreach (EA.Element ea_req in ea_reqs)
567
         {
568
            Main.WriteOutput("   " + ea_req.Name, ea_req.ElementID);
569
 
570
            string GUID = EA_TaggedValues.Read(ea_req, Constants.TAG_GUID, "");
571
            if (GUID != null && GUID.Length > 0 && GUID.StartsWith("{"))
572
            {
573
               // Get the ReqPro equivalent requirement (RP.Req)
574
               ReqPro40.Requirement rp_req = ReqProDatabase.get_requirement_by_guid(GUID);
575
               if (rp_req != null)
576
               {
577
                  // for each connector (EA.C) in EA.Req
578
                  foreach(EA.Connector ea_c in ea_req.Connectors)
579
                  {
580
                     int destId = -1;
581
 
582
                     // we dont care about direction of relationship, so test for both
583
                     if (ea_c.ClientID == ea_req.ElementID)
584
                        destId = ea_c.SupplierID;
585
                     else if (ea_c.SupplierID == ea_req.ElementID)
586
                        destId = ea_c.ClientID;
587
 
588
                     // and make sure we filter out self-referential connectors
589
                     if (destId != ea_req.ElementID)
590
                     {
591
                        // get referenced requirement (EA.RefReq) from EA.C
592
                        EA.Element ea_ref_req = Main.EA_Repository.GetElementByID(destId);
593
                        if (ea_ref_req != null && ea_ref_req.Type.Equals("Requirement"))
594
                        {
595
                           // Get the GUID from the referenced element
596
                           GUID = EA_TaggedValues.Read(ea_ref_req, Constants.TAG_GUID, "");
597
                           if (GUID != null && GUID.Length > 0 && GUID.StartsWith("{"))
598
                           {
599
                              // find EA.RefReq's equivalent requirement (RP.RefReq) in ReqPro
600
                              ReqPro40.Requirement rp_ref_req = ReqProDatabase.get_requirement_by_guid(GUID);
601
                              if (rp_ref_req != null)
602
                              {
603
                                 // Establish a traces to relationship from RP.RefReq to RP.Req
604
                                 ReqPro40.Relationships rp_ref_req_c = (ReqPro40.Relationships)rp_ref_req.TracesTo;
605
                                 if (rp_ref_req_c != null)
606
                                 {
607
                                    // wrap the relationship add in exception handling - In EA, a parent child relationship
608
                                    // can exist by virtue of the elements parentID values, and such does not prevent the
609
                                    // existence of a connection relationship either. But in ReqPro, it does. Once a requirement
610
                                    // has a "hierarchical" relationship, you cannot establish the same relationship in a 2nd
611
                                    // way, using for example a TracesTo relationship. Using exception handling here is probably
612
                                    // quicker than trying to examine what relationships already exist and act accordingly.
613
                                    try
614
                                    {
615
                                       ReqPro40.Relationship rp_ref_req_rel = 
616
                                          rp_ref_req_c.Add(rp_req,
617
                                          ReqPro40.enumRequirementLookups.eReqLookup_Object,
618
                                          null, ReqPro40.enumRelatedProjectLookups.eRelProjLookup_Empty,
619
                                          false);
620
                                       if (rp_ref_req_rel != null)
621
                                       {
622
                                          // commit
623
                                          rp_ref_req.Save();
624
                                       }
625
                                    }
626
                                    catch
627
                                    {
628
                                    }
629
                                 }
630
                              }
631
                           }
632
                        }
633
                     }
634
                  }
635
               }
636
            }
637
         }
638
         Main.WriteSeperator();
639
      }
640
 
641
 
642
      /// <summary>
643
      /// Update ReqPro relationships for requirements mastered in EA
644
      /// </summary>
645
      /// <param name="ea_mastered_reqs"></param>
646
      private void update_old_EA_mastered_requirement_relationships(ref ArrayList ea_mastered_reqs)
647
      {
648
         // Algorithm design:
649
         //
650
         //   for each EA requirement (EA.Req) updated
651
         //     Get the ReqPro equivalent requirement (RP.Req)
652
         //     for each connector (EA.C) in EA.Req
653
         //       get referenced requirement (EA.RefReq) from EA.C
654
         //       find EA.RefReq's equivalent requirement (RP.RefReq) in ReqPro
655
         //       Establish a traces to relationship from RP.RefReq to RP.Req (if it does not already exist)
656
         //       
657
         //     for each trace-to relationship (RP.C) in RP.Req
658
         //       if relationship does not exist in EA.Req
659
         //         delete RP.C
660
         //
661
         //     for each trace-from relationship (RP.C) in RP.Req
662
         //       if relationship does not exist in EA.Req
663
         //         delete RP.C
664
         //
665
 
666
         Main.WriteOutput("Updating Trace Relationships",-1);
667
 
668
         // for each EA requirement (EA.Req) updated
669
         foreach(EA.Element ea_req in ea_mastered_reqs)
670
         {
671
            Main.WriteOutput("   " + ea_req.Name, ea_req.ElementID);
672
 
673
            string GUID = EA_TaggedValues.Read(ea_req, Constants.TAG_GUID, "");
674
            if (GUID != null && GUID.Length > 0 && GUID.StartsWith("{"))
675
            {
676
               // Get the ReqPro equivalent requirement (RP.Req)
677
               ReqPro40.Requirement rp_req = ReqProDatabase.get_requirement_by_guid(GUID);
678
               if (rp_req != null)
679
               {
680
                  // for each connector (EA.C) in EA.Req
681
                  foreach(EA.Connector ea_c in ea_req.Connectors)
682
                  {
683
                     int destId = -1;
684
 
685
                     // we dont care about direction of relationship, so test for both
686
                     if (ea_c.ClientID == ea_req.ElementID)
687
                        destId = ea_c.SupplierID;
688
                     else if (ea_c.SupplierID == ea_req.ElementID)
689
                        destId = ea_c.ClientID;
690
 
691
                     // and make sure we filter out self-referential connectors
692
                     if (destId != ea_req.ElementID)
693
                     {
694
                        // get referenced requirement (EA.RefReq) from EA.C
695
                        EA.Element ea_ref_req = Main.EA_Repository.GetElementByID(destId);
696
                        if (ea_ref_req != null && ea_ref_req.Type.Equals("Requirement"))
697
                        {
698
                           // Get the GUID from the referenced element
699
                           GUID = EA_TaggedValues.Read(ea_ref_req, Constants.TAG_GUID, "");
700
                           if (GUID != null && GUID.Length > 0 && GUID.StartsWith("{"))
701
                           {
702
                              // find EA.RefReq's equivalent requirement (RP.RefReq) in ReqPro
703
                              ReqPro40.Requirement rp_ref_req = ReqProDatabase.get_requirement_by_guid(GUID);
704
                              if (rp_ref_req != null)
705
                              {
706
                                 // Establish a traces to relationship from RP.RefReq to RP.Req (if it does not already exist)
707
                                 ReqPro40.Relationships rp_ref_req_c = (ReqPro40.Relationships)rp_ref_req.TracesTo;
708
                                 if (rp_ref_req_c != null)
709
                                 {
710
                                    // ReqPro throws an exception if you try to create a relationship that already exists.
711
                                    // ReqPro doesn't seem to give any easy way to ask the question, "does a relationship
712
                                    // exist between A and B". It is debatable whether running a hand written function to 
713
                                    // answer the question is going to be any quicker than just catching the exceptions 
714
                                    // and ignoring them. For now though, use exception handling in this very bad way.
715
                                    try
716
                                    {
717
                                       ReqPro40.Relationship rp_ref_req_rel = 
718
                                          rp_ref_req_c.Add(rp_req,
719
                                          ReqPro40.enumRequirementLookups.eReqLookup_Object,
720
                                          null, ReqPro40.enumRelatedProjectLookups.eRelProjLookup_Empty,
721
                                          false);
722
                                       if (rp_ref_req_rel != null)
723
                                       {
724
 
725
                                          // commit
726
                                          rp_ref_req.Save();
727
 
728
                                          Main.WriteOutput("      Created Trace Relationship to " + rp_ref_req.get_Tag(ReqPro40.enumTagFormat.eTagFormat_FullTag), -1);
729
                                       }
730
                                    }
731
                                    catch
732
                                    {
733
                                       // do nothing
734
                                    }
735
                                 }
736
                              }
737
                           }
738
                        }
739
                     }
740
                  }
741
 
742
                  // Examine the Traces-To relationships in ReqPro
743
                  int limit_numberOfTraceTo = 0;
744
                  if (true == rp_req.get_HasTracesTo(ref limit_numberOfTraceTo))
745
                  {
746
                     ReqPro40.Relationships rp_req_c = (ReqPro40.Relationships)rp_req.TracesTo;
747
                     if (rp_req_c != null)
748
                     {
749
                        // for each relationship (RP.C) in RP.Req
750
                        rp_req_c.MoveFirst();
751
                        int i_numberOfTraceTo;
752
                        for (i_numberOfTraceTo = 0; i_numberOfTraceTo < limit_numberOfTraceTo; i_numberOfTraceTo++)
753
                        {
754
                           // Obtain the sub-requirement from the relationship, and parse it
755
                           ReqPro40.Relationship rp_req_rel = rp_req_c.GetCurrentRelationship();
756
 
757
                           ReqPro40.Requirement rp_ref_req = 
758
                              rp_req_rel.get_DestinationRequirement(ReqPro40.enumRequirementsWeights.eReqWeight_Heavy);
759
 
760
                           if (rp_ref_req != null)
761
                           {
762
                              // if relationship does not exist in EA.Req
763
                              if (!ea_element_traces_to_or_from(ea_req, rp_ref_req.GUID))
764
                              {
765
                                 // delete RP.C
766
                                 rp_req_rel.Delete();
767
                                 Main.WriteOutput("      Deleted Trace-To Relationship to " + rp_ref_req.get_Tag(ReqPro40.enumTagFormat.eTagFormat_FullTag), -1);
768
                              }
769
                           }
770
 
771
                           rp_req_c.MoveNext();
772
                        }
773
                        // commit
774
                        rp_req.Save();
775
                     }
776
                  }
777
 
778
                  // Examine the Traces-From relationships in ReqPro
779
                  int limit_numberOfTraceFrom = 0;
780
                  if (true == rp_req.get_HasTracesFrom(ref limit_numberOfTraceFrom))
781
                  {
782
                     ReqPro40.Relationships rp_req_c = (ReqPro40.Relationships)rp_req.TracesFrom;
783
                     if (rp_req_c != null)
784
                     {
785
                        // for each relationship (RP.C) in RP.Req
786
                        rp_req_c.MoveFirst();
787
                        int i_numberOfTraceFrom;
788
                        for (i_numberOfTraceFrom = 0; i_numberOfTraceFrom < limit_numberOfTraceFrom; i_numberOfTraceFrom++)
789
                        {
790
                           // Obtain the sub-requirement from the relationship, and parse it
791
                           ReqPro40.Relationship rp_req_rel = rp_req_c.GetCurrentRelationship();
792
 
793
                           ReqPro40.Requirement rp_ref_req = 
794
                              rp_req_rel.get_SourceRequirement(ReqPro40.enumRequirementsWeights.eReqWeight_Heavy);
795
 
796
                           if (rp_ref_req != null)
797
                           {
798
                              // if relationship does not exist in EA.Req
799
                              if (!ea_element_traces_to_or_from(ea_req, rp_ref_req.GUID))
800
                              {
801
                                 // delete RP.C
802
                                 rp_req_rel.Delete();
803
                                 Main.WriteOutput("      Deleted Trace-From Relationship to " + rp_ref_req.get_Tag(ReqPro40.enumTagFormat.eTagFormat_FullTag), -1);
804
                              }
805
                           }
806
 
807
                           rp_req_c.MoveNext();
808
                        }
809
                        // commit
810
                        rp_req.Save();
811
                     }
812
                  }
813
               }
814
            }
815
         }
816
         Main.WriteSeperator();
817
      }
818
 
819
 
820
      /// <summary>
821
      /// Use historical data stored in the ReqProDB element to 
822
      /// </summary>
823
      /// <param name="ea_mastered_reqs_rp_guids"></param>
824
      private void report_orphaned_ReqPro_requirements(ref ArrayList ea_mastered_reqs_rp_guids)
825
      {
826
         // we can only report on EA mastered requirements that have been deleted, if the extent of
827
         // the export is total, not partial
828
         if (m_ExportExtent == ExportForm.ExportExtent.REQPRODB_REQS)
829
         {
830
            // Get the last list of EA mastered requirements from the ReqProDB element
831
            if (base.RQ_Element.Notes != null && base.RQ_Element.Notes.Length > 0)
832
            {
833
               // split it into a string array
834
               char [] seperators = {'\r','\n'};
835
               string [] options = base.RQ_Element.Notes.Split(seperators);
836
 
837
               ArrayList rp_orphaned_reqs = new ArrayList();
838
               ArrayList rp_non_orphaned_reqs = new ArrayList();
839
 
840
               // process the string array to accumulate list of orphaned and non-orphaned requirements
841
               foreach (string s in options)
842
               {
843
                  string trimmed_s = s.Trim();
844
                  if (trimmed_s.Length > 0)
845
                  {
846
                     if (trimmed_s.StartsWith(Constants.KEY_EXPORTED_GUID))
847
                     {
848
                        string value = trimmed_s.Substring(Constants.KEY_EXPORTED_GUID.Length);
849
                        if (false == ea_mastered_reqs_rp_guids.Contains(value))
850
                        {
851
                           rp_orphaned_reqs.Add(value);
852
                        }
853
                        else
854
                        {
855
                           rp_non_orphaned_reqs.Add(value);
856
                        }
857
                     }
858
                  }
859
               }
860
 
861
               // default decision to use when constructing export options for ReqProDB element later on
862
               DialogResult dlgRes = DialogResult.No;
863
 
864
               // report on orphaned requirements
865
               if (rp_orphaned_reqs.Count > 0)
866
               {
867
                  ArrayList rp_orphaned_req_strings = new ArrayList();
868
 
869
                  foreach(string s in rp_orphaned_reqs)
870
                  {
871
                     ReqPro40.Requirement rp_req = ReqProDatabase.get_requirement_by_guid(s);
872
                     if (rp_req != null)
873
                     {
874
                        string rp_req_tag = rp_req.get_Tag(ReqPro40.enumTagFormat.eTagFormat_FullTag);
875
                        if (rp_req_tag != null)
876
                        {
877
                           rp_orphaned_req_strings.Add("   " + rp_req_tag + " " + rp_req.Name);
878
                        }
879
                     }
880
                  }
881
 
882
                  if (rp_orphaned_req_strings.Count > 0)
883
                  {
884
                     Main.WriteOutput("The following EA Mastered requirements in ReqPro, may no longer be needed.", -1);
885
                     Main.WriteOutput("i.e. they are orphaned requirements in ReqPro, because they have been deleted", -1);
886
                     Main.WriteOutput("in EA since the last export.", -1);
887
                     Main.WriteOutput("Please verify and if necessary, mark them as obsolete in ReqPro.", -1);
888
 
889
                     foreach(string s in rp_orphaned_req_strings)
890
                     {
891
                        Main.WriteOutput(s, -1);
892
                     }
893
 
894
                     Main.WriteSeperator();
895
 
896
                     // allow user to specifiy whether we should forget about the orphaned requirements
897
                     // the next time we do an export.
898
                     dlgRes = MessageBoxEx.Show(
899
                        "Some ReqPro requirements have been orphaned (see output\n" +
900
                        "tab display for more information).\n" + 
901
                        "Ignore these problems in future exports?", "Confirm", MessageBoxButtons.YesNo);
902
                  }
903
               }
904
 
905
               StringBuilder sb = new StringBuilder();
906
 
907
               // reconstruct non-export related options using the appropriate ReqProFilterForm static method
908
               // That method keeps knowledge of the import filter options localised in the right place.
909
               ReqProFilterForm.saveFilterSettings(options, ref sb);
910
 
911
               // If this export had nothing to work with from the ReqProDB options....
912
               if (rp_orphaned_reqs.Count == 0 && rp_non_orphaned_reqs.Count == 0)
913
               {
914
                  // The options did not contain any key values. That probably means that up till now,
915
                  // any export that has been performed previously, did not actually export anything.
916
                  // So, just add whatever we exported this time (if anything)
917
                  if (ea_mastered_reqs_rp_guids.Count > 0)
918
                  {
919
                     sb.Append(Constants.EXPORT_HEADING);
920
                     foreach (string s in ea_mastered_reqs_rp_guids)
921
                     {
922
                        sb.Append(Constants.KEY_EXPORTED_GUID);
923
                        sb.Append(s);
924
                        sb.Append("\r\n");
925
                     }
926
                  }
927
               }
928
               else
929
               {
930
                  sb.Append(Constants.EXPORT_HEADING);
931
 
932
                  // construct export-related options
933
                  if (dlgRes == DialogResult.No)
934
                  {
935
                     foreach (string s in rp_orphaned_reqs)
936
                     {
937
                        sb.Append(Constants.KEY_EXPORTED_GUID);
938
                        sb.Append(s);
939
                        sb.Append("\r\n");
940
                     }
941
                  }
942
                  foreach (string s in rp_non_orphaned_reqs)
943
                  {
944
                     sb.Append(Constants.KEY_EXPORTED_GUID);
945
                     sb.Append(s);
946
                     sb.Append("\r\n");
947
 
948
                     // if this item is in ea_mastered_reqs_rp_guids, then remove it from there so that we do not
949
                     // duplicate it in the options string when we process ea_mastered_reqs_rp_guids after this loop
950
                     // completes
951
                     if (ea_mastered_reqs_rp_guids.Contains(s))
952
                     {
953
                        ea_mastered_reqs_rp_guids.Remove(s);
954
                     }
955
                  }
956
 
957
                  // If there are any items left in ea_mastered_reqs_rp_guids, add them too
958
                  foreach (string s in ea_mastered_reqs_rp_guids)
959
                  {
960
                     sb.Append(Constants.KEY_EXPORTED_GUID);
961
                     sb.Append(s);
962
                     sb.Append("\r\n");
963
                  }
964
               }
965
 
966
               base.RQ_Element.Notes = sb.ToString();
967
               base.RQ_Element.Update();
968
            }
969
         }
970
      }
971
 
972
 
973
      private bool ea_element_traces_to_or_from(EA.Element ea_req, string rp_GUID)
974
      {
975
         foreach(EA.Connector ea_c in ea_req.Connectors)
976
         {
977
            int destId = -1;
978
 
979
            // we dont care about direction of relationship, so test for both
980
            if (ea_c.ClientID == ea_req.ElementID)
981
               destId = ea_c.SupplierID;
982
            else if (ea_c.SupplierID == ea_req.ElementID)
983
               destId = ea_c.ClientID;
984
 
985
            // and make sure we filter out self-referential connectors
986
            if (destId != ea_req.ElementID)
987
            {
988
               EA.Element ea_ref_req = Main.EA_Repository.GetElementByID(destId);
989
               if (ea_ref_req != null)
990
               {
991
                  string GUID = EA_TaggedValues.Read(ea_ref_req, Constants.TAG_GUID, "");
992
                  if (GUID != null && GUID.Length > 0 && GUID.StartsWith("{"))
993
                  {
994
                     if (rp_GUID.Equals(GUID))
995
                        return true;
996
                  }
997
               }
998
            }
999
         }
1000
 
1001
         return false;
1002
      }
1003
 
1004
 
1005
      /// <summary>
1006
      /// Look for and strip any temporary tag from the requirement name, returning a new
1007
      /// string to be used as the requirement name
1008
      /// </summary>
1009
      /// <param name="taggedReqName"></param>
1010
      /// <returns></returns>
2157 ghuddy 1011
      private string untaggedReqName(string taggedReqName, ref string tag, bool force)
2155 ghuddy 1012
      {
1013
         if (taggedReqName != null)
1014
         {
1015
            // Try and split the string into two tokens at the first space character
1016
            char [] delim = {' '};
1017
            string [] tokens = taggedReqName.Split(delim, 2);
1018
 
1019
            // if there are two tokens resulting from the split
1020
            if (tokens.GetLength(0) == 2)
1021
            {
2157 ghuddy 1022
               // return tag
1023
               tag = tokens[0];
1024
 
2155 ghuddy 1025
               // if the first token appears to be a tag
1026
               if (force == true
1027
                  || tokens[0].StartsWith("REQ")
1028
                  || tokens[0].StartsWith("TAG")
1029
                  || tokens[0].StartsWith("SPR")
2163 ghuddy 1030
                  || tokens[0].StartsWith("<")
2155 ghuddy 1031
                  || (tokens[0].IndexOfAny(numbers) > 0 && tokens[0].IndexOfAny(letters) == 0))
1032
               {
1033
                  // return the token after the tag.
1034
                  return tokens[1];
1035
               }
1036
            }
1037
         }
1038
         // default to the input string
1039
         return taggedReqName;
1040
      }
1041
 
2157 ghuddy 1042
      private string tagPrefix(string tag)
1043
      {
1044
         if (tag != null && tag.Length > 0)
1045
         {
1046
            string[] prefixes = tag.Split("0123456789.".ToCharArray());
1047
            if (prefixes.GetLength(0) > 0)
1048
            {
1049
               return prefixes[0];
1050
            }
1051
         }
1052
         return tag;
1053
      }
2155 ghuddy 1054
 
2157 ghuddy 1055
      private void exportAttributes(ReqPro40.Requirement rp_req, EA.Element ea_req, string rp_req_tag)
2155 ghuddy 1056
      {
1057
         // Update the attributes of a ReqPro requirement. We have to be very careful here.
1058
         // ReqPro does not like us trying to set the value of attributes that do not exist for the
1059
         // specified requirement type, and it also does not like us trying to set an attribute that is
1060
         // a list type, to a value that is not in the predefined set of values for the list type.
1061
         bool hasStatus = false;
1062
         bool hasDifficulty = false;
1063
         bool hasPriority = false;
1064
         bool hasSource = false;
1065
         bool hasSourceVersion = false;
1066
         bool hasSourceSection = false;
1067
         bool hasSubsystem = false;
1068
         bool hasStability = false;
1069
         bool hasType = false;
1070
 
2157 ghuddy 1071
         string reqType = tagPrefix(rp_req_tag);
1072
 
2155 ghuddy 1073
         // Use the ReqProParser's knowledge of requirement types and attribute type associations to tell
1074
         // us what attributes we can set, and then use the setListItemValue() function to do the setting.
1075
         // That function knows how to set List items correctly and safely so as to not cause exceptions
1076
         // to be raised in the ReqPro automation onject.
2157 ghuddy 1077
         if (reqTypeHasOneOrMoreAttrs(reqType,
2155 ghuddy 1078
            ref hasStatus, ref hasDifficulty, ref hasPriority,
1079
            ref hasSource, ref hasSourceVersion, ref hasSourceSection,
1080
            ref hasSubsystem, ref hasStability, ref hasType))
1081
         {
1082
            if (hasStatus)
1083
            {
2161 ghuddy 1084
               setListItemAttrValue(rp_req, ea_req, Constants.RP_ATTR_STATUS, ea_req.Status, rp_req_tag);
2155 ghuddy 1085
            }
1086
            if (hasDifficulty)
1087
            {
2161 ghuddy 1088
               setListItemAttrValue(rp_req, ea_req, Constants.RP_ATTR_DIFFICULTY, ea_req.Difficulty, rp_req_tag);
2155 ghuddy 1089
            }
1090
            if (hasPriority)
1091
            {
2161 ghuddy 1092
               setListItemAttrValue(rp_req, ea_req, Constants.RP_ATTR_PRIORITY, ea_req.Priority, rp_req_tag);
2155 ghuddy 1093
            }
2157 ghuddy 1094
            if (hasSource)
1095
            {
1096
               string s = EA_TaggedValues.Read(ea_req, Constants.TAG_SOURCE);
1097
               if (s != null && s.Length > 0)
1098
               {
2161 ghuddy 1099
                  setListItemAttrValue(rp_req, ea_req, Constants.RP_ATTR_SOURCE, s, rp_req_tag);
2157 ghuddy 1100
               }
1101
            }
1102
            if (hasSourceVersion)
1103
            {
1104
               string s = EA_TaggedValues.Read(ea_req, Constants.TAG_SOURCE_VERSION);
1105
               if (s != null && s.Length > 0)
1106
               {
2161 ghuddy 1107
                  setTextAttrValue(rp_req, ea_req, Constants.RP_ATTR_SOURCE_VERSION, s, rp_req_tag);
2157 ghuddy 1108
               }
1109
            }
1110
            if (hasSourceSection)
1111
            {
1112
               string s = EA_TaggedValues.Read(ea_req, Constants.TAG_SOURCE_SECTION);
1113
               if (s != null && s.Length > 0)
1114
               {
2161 ghuddy 1115
                  setTextAttrValue(rp_req, ea_req, Constants.RP_ATTR_SOURCE_SECTION, s, rp_req_tag);
2157 ghuddy 1116
               }
1117
            }
1118
            if (hasSubsystem)
1119
            {
1120
               string s = EA_TaggedValues.Read(ea_req, Constants.TAG_SUBSYSTEM);
1121
               if (s != null && s.Length > 0)
1122
               {
2159 ghuddy 1123
                  // The tagged value may be a comma seperated list of subsystem names so break it up
1124
                  // and process each one found
1125
                  string[] sa = s.Split(",".ToCharArray());
1126
                  foreach (string sas in sa)
1127
                  {
1128
                     string trimmed_sas = sas.Trim();
1129
                     if (trimmed_sas.Length > 0)
1130
                     {
2161 ghuddy 1131
                        setListItemAttrValue(rp_req, ea_req, Constants.RP_ATTR_SUBSYSTEM_TYPE, trimmed_sas, rp_req_tag);
2159 ghuddy 1132
                     }
1133
                  }
2157 ghuddy 1134
               }
1135
            }
1136
            if (hasStability)
1137
            {
1138
               string s = EA_TaggedValues.Read(ea_req, Constants.TAG_STABILITY);
1139
               if (s != null && s.Length > 0)
1140
               {
2161 ghuddy 1141
                  setListItemAttrValue(rp_req, ea_req, Constants.RP_ATTR_STABILITY, s, rp_req_tag);
2157 ghuddy 1142
               }
1143
            }
1144
            if (hasType)
1145
            {
2159 ghuddy 1146
               // The StereoTypeEx is a comma seperated list, and the first in the list is usually (always?)
1147
               // the one displayed in EA's project browser, so try and export the first item in the list
1148
               bool done = false;
1149
               if (ea_req.StereotypeEx != null && ea_req.StereotypeEx.Length > 0)
2157 ghuddy 1150
               {
1151
                  string[] s_arr = ea_req.StereotypeEx.Split(",".ToCharArray());
1152
                  if (s_arr[0] != null && s_arr[0].Length > 0)
1153
                  {
2161 ghuddy 1154
                     setListItemAttrValue(rp_req, ea_req, Constants.RP_ATTR_REQ_TYPE, s_arr[0], rp_req_tag);
2159 ghuddy 1155
                     done = true;
2157 ghuddy 1156
                  }
1157
               }
2159 ghuddy 1158
               // if we didnt get anything from StereoTypeEx, then try Stereotype
1159
               if (!done && ea_req.Stereotype != null && ea_req.Stereotype.Length > 0)
1160
               {
2161 ghuddy 1161
                  setListItemAttrValue(rp_req, ea_req, Constants.RP_ATTR_REQ_TYPE, ea_req.Stereotype, rp_req_tag);
2159 ghuddy 1162
               }
2157 ghuddy 1163
            }
2155 ghuddy 1164
         }
1165
      }
1166
 
1167
 
1168
      /// <summary>
1169
      /// Set a ReqPro requirement attribute value, for an attribute that is a list type.
1170
      /// This function only allows the setting of the value, if it is one of the values
1171
      /// allowed for the list item. This ensures we do not get an exception raised in the
1172
      /// ReqPro automation object.
1173
      /// </summary>
1174
      /// <param name="rp_req"></param>
1175
      /// <param name="label"></param>
1176
      /// <param name="value"></param>
2157 ghuddy 1177
      private void setListItemAttrValue(ReqPro40.Requirement rp_req, EA.Element ea_req, string label, string value, string rp_req_tag)
2155 ghuddy 1178
      {
2157 ghuddy 1179
         bool attribute_type_found = false;
1180
         bool attribute_value_found = false;
1181
 
2155 ghuddy 1182
         // look through each attribute value, for the one whose label matches the one specified
1183
         ReqPro40.AttrValues rp_attr_values = rp_req.AttrValues;
1184
 
1185
         foreach (ReqPro40.AttrValue rp_attr_value in rp_attr_values)
1186
         {
1187
            if (rp_attr_value != null && rp_attr_value.Label.Equals(label))
1188
            {
2157 ghuddy 1189
               attribute_type_found = true;
1190
 
2155 ghuddy 1191
               // Look through each list item value to make sure that one exists that matches
1192
               // the value specified
1193
               ReqPro40.ListItemValues rp_list_item_values = rp_attr_value.ListItemValues;
1194
               if (rp_list_item_values != null)
1195
               {
1196
                  foreach (ReqPro40.ListItemValue rp_list_item_value in rp_list_item_values)
1197
                  {
1198
                     if (rp_list_item_value.Text.Equals(value))
1199
                     {
1200
                        // We found that the list contains the value specified, so set the value of the attribute
1201
                        rp_list_item_value.Selected = true;
1202
 
2157 ghuddy 1203
                        attribute_value_found = true;
2155 ghuddy 1204
                        // exit inner loop
1205
                        break;
1206
                     }
1207
                  }
1208
               }
1209
               // exit outer loop
1210
               break;
1211
            }
1212
         }
2157 ghuddy 1213
 
1214
         if (!attribute_type_found)
1215
         {
1216
            Main.WriteOutput(string.Format("WARNING, Failed to export attribute type ({0}) for ({1})",
1217
               label, rp_req_tag), ea_req.ElementID);
1218
         }
1219
         if (!attribute_value_found)
1220
         {
1221
            Main.WriteOutput(string.Format("WARNING, Failed to export attribute type/value ({0}/{1}) for ({2})",
1222
               label, value, rp_req_tag), ea_req.ElementID);
1223
         }
2155 ghuddy 1224
      }
1225
 
1226
 
2157 ghuddy 1227
 
1228
      /// <summary>
1229
      /// Set a ReqPro requirement attribute value, for an attribute that is a text type.
1230
      /// </summary>
1231
      /// <param name="rp_req"></param>
1232
      /// <param name="label"></param>
1233
      /// <param name="value"></param>
1234
      private void setTextAttrValue(ReqPro40.Requirement rp_req, EA.Element ea_req, string label, string value, string rp_req_tag)
1235
      {
1236
         bool attribute_type_found = false;
1237
 
1238
         // look through each attribute value, for the one whose label matches the one specified
1239
         ReqPro40.AttrValues rp_attr_values = rp_req.AttrValues;
1240
 
1241
         foreach (ReqPro40.AttrValue rp_attr_value in rp_attr_values)
1242
         {
1243
            if (rp_attr_value != null && rp_attr_value.Label.Equals(label))
1244
            {
1245
               attribute_type_found = true;
1246
 
1247
               rp_attr_value.Text = value;
1248
 
1249
               // exit outer loop
1250
               break;
1251
            }
1252
         }
1253
 
1254
         if (!attribute_type_found)
1255
         {
1256
            Main.WriteOutput(string.Format("WARNING, Failed to export attribute type ({0}) for ({1})",
1257
               label, rp_req_tag), ea_req.ElementID);
1258
         }
1259
      }
1260
 
1261
 
2155 ghuddy 1262
	}
1263
}