Subversion Repositories DevTools

Rev

Rev 2161 | 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.Collections.Specialized;
6
using System.Windows.Forms;
2141 ghuddy 7
using ReqPro40;
8
 
9
 
10
namespace EA_ReqPro
11
{
12
	/// <summary>
13
	/// The ReqProParser class encapsulates a parsing algorithm for a ReqPro database
14
	/// designed to pick out packages and requirement elements and to provide that information
15
	/// to a client with sufficient information to allow it to build a model of that ReqPro
16
	/// database content in memory, maintaining the hierarchy and ordering of objects found.
17
	/// </summary>
18
	public class ReqProParser
19
	{
2151 ghuddy 20
      // lists of meta-data in the ReqPro database
21
      protected ArrayList rq_req_types;
22
      protected ArrayList rq_req_status_types;
23
      protected ArrayList delayedMessages;
24
 
2155 ghuddy 25
      // Flag to allow a client to configure this class to import structure only (no requirements -
26
      // just packages).
27
      protected bool structure_only = false;
28
 
29
 
2151 ghuddy 30
      // constructor
2141 ghuddy 31
		public ReqProParser()
32
		{
2151 ghuddy 33
         delayedMessages = new ArrayList();
2141 ghuddy 34
		}
35
 
36
      /// <summary>
37
      /// The parser will call this virtual method when it has opened a ReqPro project
38
      /// </summary>
39
      /// <param name="rq_project"></param>
2155 ghuddy 40
      protected virtual void provideReqProDatabaseInfo( 
2145 ghuddy 41
         ReqProDB_Artifact rq_artifact,
42
         EA.Element rq_element)
2141 ghuddy 43
      {
44
      }
45
 
46
      /// <summary>
47
      /// The parser will call this virtual method for every package it finds
48
      /// in the ReqPro database.
49
      /// </summary>
50
      /// <param name="level"></param>
51
      /// <param name="ea_repository"></param>
52
      /// <param name="rq_project"></param>
53
      /// <param name="rq_Package"></param>
2151 ghuddy 54
      protected virtual void processPackage(int level,
2141 ghuddy 55
                                            ReqPro40.Package rq_package)
56
      {
57
      }
58
 
59
      /// <summary>
60
      /// The parser will call this virtual method for every requirement it
61
      /// finds in the ReqPro database.
62
      /// </summary>
63
      /// <param name="level"></param>
64
      /// <param name="ea_repository"></param>
65
      /// <param name="rq_project"></param>
66
      /// <param name="rq_Package"></param>
67
      /// <param name="rq_Requirement"></param>
2151 ghuddy 68
      protected virtual void processRequirement(int level,
2141 ghuddy 69
                                                ReqPro40.Package rq_package,
70
                                                ReqPro40.Requirement rq_requirement)
71
      {
72
      }
73
 
74
      /// <summary>
75
      /// The parser will call this virtual method for every package or requirement it
76
      /// finds in the ReqPro database.
77
      /// </summary>
78
      /// <param name="level"></param>
79
      /// <param name="ea_repository"></param>
80
      /// <param name="rq_project"></param>
81
      /// <param name="rq_Package"></param>
82
      /// <param name="rq_Requirement"></param>
2151 ghuddy 83
      protected virtual void processObject(int level,
2141 ghuddy 84
                                           ReqPro40.Package rq_package,
85
                                           ReqPro40.Requirement rq_requirement)
86
      {
87
      }
88
 
2151 ghuddy 89
      protected void writeDelayedMessages()
90
      {
2155 ghuddy 91
         if (delayedMessages.Count > 0)
2151 ghuddy 92
         {
2155 ghuddy 93
            foreach(string s in delayedMessages)
94
            {
95
               Main.WriteOutput(s, -1);
96
            }
97
            Main.WriteSeperator();
2151 ghuddy 98
         }
99
      }
2141 ghuddy 100
 
2151 ghuddy 101
      #region Requirement Type methods
2141 ghuddy 102
 
103
      /// <summary>
2151 ghuddy 104
      /// Get the requirement types from the ReqPro database, into a simple list, where each element
105
      /// describes the requirement type and whether it is filtered or not. This list can be given to 
106
      /// the ReqProFilterForm to capture the users requirement type filtering decisions. 
107
      /// </summary>
2155 ghuddy 108
      protected void get_rq_req_types_from_database()
2151 ghuddy 109
      {
110
         rq_req_types = new ArrayList();
111
 
2155 ghuddy 112
         ReqPro40.ReqTypes rqtypes = ReqProDatabase.get_requirement_types();
113
         if (rqtypes != null)
2151 ghuddy 114
         {
2155 ghuddy 115
            foreach (ReqPro40.ReqType rq_type in rqtypes)
116
            {
117
               ReqPro_ReqType new_req_type = new ReqPro_ReqType(rq_type);
118
               new_req_type.name     = rq_type.Name;
119
               new_req_type.prefix   = rq_type.ReqPrefix;
120
               rq_req_types.Add(new_req_type);
121
            }
2151 ghuddy 122
         }
123
      }
124
 
2155 ghuddy 125
 
2151 ghuddy 126
      /// <summary>
127
      /// Examine the requirement type list to see if the requirement type of the specified object
128
      /// has been filtered or not.
129
      /// </summary>
130
      /// <param name="rq_obj"></param>
131
      /// <returns></returns>
132
      protected bool reqTypeIsFiltered(ReqPro_object rq_obj)
133
      {
134
         return ((ReqPro_ReqType)rq_req_types[rq_obj.tag_enum]).filtered;
135
      }
136
 
2155 ghuddy 137
 
2153 ghuddy 138
      protected bool reqTypeHasOneOrMoreAttrs(ReqPro_object rq_obj, 
139
         ref bool hasStatus, 
140
         ref bool hasDiff, 
141
         ref bool hasPrio,
142
         ref bool hasSource,
143
         ref bool hasSourceVersion,
2155 ghuddy 144
         ref bool hasSourceSection,
145
         ref bool hasSubsystem,
146
         ref bool hasStability,
147
         ref bool hasType)
2151 ghuddy 148
      {
149
         foreach (ReqPro_ReqType rp_rt in rq_req_types)
150
         {
151
            if (rq_obj.tag.StartsWith(rp_rt.prefix))
152
            {
153
               hasStatus = rp_rt.hasStatus;
154
               hasDiff = rp_rt.hasDifficulty;
155
               hasPrio = rp_rt.hasPriority;
2153 ghuddy 156
               hasSource = rp_rt.hasSource;
157
               hasSourceVersion = rp_rt.hasSourceVersion;
158
               hasSourceSection = rp_rt.hasSourceSection;
2155 ghuddy 159
               hasSubsystem = rp_rt.hasSubsystem;
160
               hasStability = rp_rt.hasStability;
161
               hasType = rp_rt.hasType;
2153 ghuddy 162
 
2155 ghuddy 163
               return hasStatus | hasDiff | hasPrio | hasSource | hasSourceVersion | hasSourceSection | hasSubsystem | hasStability | hasType;
2151 ghuddy 164
            }
165
         }
166
 
167
         return false;
168
      }
169
 
2155 ghuddy 170
 
171
      protected bool reqTypeHasOneOrMoreAttrs(string tag_prefix, 
172
         ref bool hasStatus, 
173
         ref bool hasDiff, 
174
         ref bool hasPrio,
175
         ref bool hasSource,
176
         ref bool hasSourceVersion,
177
         ref bool hasSourceSection,
178
         ref bool hasSubsystem,
179
         ref bool hasStability,
180
         ref bool hasType)
181
      {
182
         foreach (ReqPro_ReqType rp_rt in rq_req_types)
183
         {
184
            if (tag_prefix.StartsWith(rp_rt.prefix))
185
            {
186
               hasStatus = rp_rt.hasStatus;
187
               hasDiff = rp_rt.hasDifficulty;
188
               hasPrio = rp_rt.hasPriority;
189
               hasSource = rp_rt.hasSource;
190
               hasSourceVersion = rp_rt.hasSourceVersion;
191
               hasSourceSection = rp_rt.hasSourceSection;
192
               hasSubsystem = rp_rt.hasSubsystem;
193
               hasStability = rp_rt.hasStability;
194
               hasType = rp_rt.hasType;
195
 
196
               return hasStatus | hasDiff | hasPrio | hasSource | hasSourceVersion | hasSourceSection | hasSubsystem | hasStability | hasType;
197
            }
198
         }
199
 
200
         return false;
201
      }
2151 ghuddy 202
      #endregion
203
 
204
      #region Requirement Status Type methods
205
 
206
      /// <summary>
207
      /// Get the requirement status types from the ReqPro database, into a simple list, where each element
208
      /// describes the requirement status type and whether it is filtered or not. This list can be given to 
209
      /// the ReqProFilterForm to capture the users requirement status type filtering decisions. 
210
      /// </summary>
2155 ghuddy 211
      protected void get_rq_req_status_types_from_database()
2151 ghuddy 212
      {
213
         StringCollection status_values = new StringCollection();
214
 
215
         // Each requirement type can have its own unique list of status attribute values
216
         // so we have to go through each requirement type and find the set of status values
217
         // that each one has and add them to out string collection, if the collection does
218
         // not already have the strings ofcoarse. So, we are merging together all the status
219
         // values in the ReqPro database, into one set.
220
         foreach (ReqPro_ReqType rp_rt in rq_req_types)
221
         {
222
            try 
223
            {
2161 ghuddy 224
               ReqPro40.Attr attr = rp_rt.rq_type.get_Attr(Constants.RP_ATTR_STATUS, ReqPro40.enumAttrLookups.eAttrLookups_Label);
2151 ghuddy 225
               rp_rt.hasStatus = true;
226
 
227
               foreach (ReqPro40.ListItem listItem in attr.ListItems)
228
               {
229
                  if (!status_values.Contains(listItem.Text))
230
                  {
231
                     status_values.Add(listItem.Text);
232
                  }
233
               }
234
            }
235
            catch 
236
            {
237
               delayedMessages.Add( string.Format("WARNING, ReqPro requirement type ({0}) has no Status attribute", rp_rt.prefix) );
238
            }
2155 ghuddy 239
 
240
            //Main.WriteOutput("REQ_TYPE: " + rp_rt.name, -1);
241
            //foreach (ReqPro40.Attr a in rp_rt.rq_type.Attrs)
242
            //{
243
            //   Main.WriteOutput("   ATTR LABEL: " + a.Label, -1);
244
            //}
245
 
2151 ghuddy 246
            // Also check if this requirement type has any of the other attributes we might import. This is
247
            // a little off topic for this function but this is a convenient place to do this until another
248
            // function is written.
249
            try 
250
            {
2161 ghuddy 251
               ReqPro40.Attr attr = rp_rt.rq_type.get_Attr(Constants.RP_ATTR_DIFFICULTY, ReqPro40.enumAttrLookups.eAttrLookups_Label);
2151 ghuddy 252
               rp_rt.hasDifficulty = true;
253
            }
254
            catch 
255
            {
2161 ghuddy 256
               delayedMessages.Add( string.Format("WARNING, ReqPro requirement type ({0}) has no {1} attribute", rp_rt.prefix, Constants.RP_ATTR_DIFFICULTY) );
2151 ghuddy 257
            };
258
 
259
            try 
260
            {
2161 ghuddy 261
               ReqPro40.Attr attr = rp_rt.rq_type.get_Attr(Constants.RP_ATTR_PRIORITY, ReqPro40.enumAttrLookups.eAttrLookups_Label);
2151 ghuddy 262
               rp_rt.hasPriority = true;
263
            }
264
            catch 
265
            {
2161 ghuddy 266
               delayedMessages.Add( string.Format("WARNING, ReqPro requirement type ({0}) has no {1} attribute", rp_rt.prefix, Constants.RP_ATTR_PRIORITY) );
2151 ghuddy 267
            };
2153 ghuddy 268
 
269
            try 
270
            {
2161 ghuddy 271
               ReqPro40.Attr attr = rp_rt.rq_type.get_Attr(Constants.RP_ATTR_SOURCE, ReqPro40.enumAttrLookups.eAttrLookups_Label);
2153 ghuddy 272
               rp_rt.hasSource = true;
273
            }
274
            catch 
275
            {
2161 ghuddy 276
               delayedMessages.Add( string.Format("WARNING, ReqPro requirement type ({0}) has no {1} attribute", rp_rt.prefix, Constants.RP_ATTR_SOURCE) );
2153 ghuddy 277
            };
278
 
279
            try 
280
            {
2161 ghuddy 281
               ReqPro40.Attr attr = rp_rt.rq_type.get_Attr(Constants.RP_ATTR_SOURCE_VERSION, ReqPro40.enumAttrLookups.eAttrLookups_Label);
2153 ghuddy 282
               rp_rt.hasSourceVersion = true;
283
            }
284
            catch 
285
            {
2161 ghuddy 286
               delayedMessages.Add( string.Format("WARNING, ReqPro requirement type ({0}) has no {1} attribute", rp_rt.prefix, Constants.RP_ATTR_SOURCE_VERSION) );
2153 ghuddy 287
            };
288
 
289
            try 
290
            {
2161 ghuddy 291
               ReqPro40.Attr attr = rp_rt.rq_type.get_Attr(Constants.RP_ATTR_SOURCE_SECTION, ReqPro40.enumAttrLookups.eAttrLookups_Label);
2153 ghuddy 292
               rp_rt.hasSourceSection = true;
293
            }
294
            catch 
295
            {
2161 ghuddy 296
               delayedMessages.Add( string.Format("WARNING, ReqPro requirement type ({0}) has no {1} attribute", rp_rt.prefix, Constants.RP_ATTR_SOURCE_SECTION) );
2153 ghuddy 297
            };
2155 ghuddy 298
 
299
            try 
300
            {
2161 ghuddy 301
               ReqPro40.Attr attr = rp_rt.rq_type.get_Attr(Constants.RP_ATTR_SUBSYSTEM_TYPE, ReqPro40.enumAttrLookups.eAttrLookups_Label);
2155 ghuddy 302
               rp_rt.hasSubsystem = true;
303
            }
304
            catch 
305
            {
2161 ghuddy 306
               delayedMessages.Add( string.Format("WARNING, ReqPro requirement type ({0}) has no {1} attribute", rp_rt.prefix, Constants.RP_ATTR_SUBSYSTEM_TYPE) );
2155 ghuddy 307
            };
308
 
309
            try 
310
            {
2161 ghuddy 311
               ReqPro40.Attr attr = rp_rt.rq_type.get_Attr(Constants.RP_ATTR_STABILITY, ReqPro40.enumAttrLookups.eAttrLookups_Label);
2155 ghuddy 312
               rp_rt.hasStability = true;
313
            }
314
            catch 
315
            {
2161 ghuddy 316
               delayedMessages.Add( string.Format("WARNING, ReqPro requirement type ({0}) has no {1} attribute", rp_rt.prefix, Constants.RP_ATTR_STABILITY) );
2155 ghuddy 317
            };
318
 
319
            try 
320
            {
2161 ghuddy 321
               ReqPro40.Attr attr = rp_rt.rq_type.get_Attr(Constants.RP_ATTR_REQ_TYPE, ReqPro40.enumAttrLookups.eAttrLookups_Label);
2155 ghuddy 322
               rp_rt.hasType = true;
323
            }
324
            catch 
325
            {
2161 ghuddy 326
               delayedMessages.Add( string.Format("WARNING, ReqPro requirement type ({0}) has no {1} attribute", rp_rt.prefix, Constants.RP_ATTR_REQ_TYPE) );
2155 ghuddy 327
            };
2151 ghuddy 328
         }
329
 
330
         // if reqpro had no status values, then add a dummy one
331
         if (status_values.Count == 0)
332
         {
333
            status_values.Add("Approved");
334
         }
335
 
336
         // With our merged set of status values, create a list of ReqPro_ReqStatus objects.
337
         rq_req_status_types = new ArrayList();
338
         foreach (string s in status_values)
339
         {
340
            ReqPro_ReqStatus new_ReqPro_ReqStatus = new ReqPro_ReqStatus();
341
            new_ReqPro_ReqStatus.filtered = false;
342
            new_ReqPro_ReqStatus.status_value = s;
343
            rq_req_status_types.Add(new_ReqPro_ReqStatus);
344
         }
345
      }
346
 
347
      /// <summary>
348
      /// Examine the requirement status type list to see if the requirement status type of 
349
      /// the specified object has been filtered or not.
350
      /// </summary>
351
      /// <param name="rq_obj"></param>
352
      /// <returns></returns>
353
      protected bool reqStatusTypeIsFiltered(ReqPro_object rq_obj)
354
      {
355
         foreach (ReqPro_ReqStatus rqs in rq_req_status_types)
356
         {
357
            if (0 == rqs.status_value.CompareTo(rq_obj.status))
358
            {
359
               return rqs.filtered;
360
            }
361
         }
362
         return false;
363
      }
364
 
365
      #endregion
366
 
367
 
368
      /// <summary>
2141 ghuddy 369
      /// Initiates a ReqPro database parsing operation using a prompted reqpro database open operation
370
      /// </summary>
371
      /// <param name="ea_repository"></param>
2151 ghuddy 372
      /// <returns></returns>
2155 ghuddy 373
      public virtual bool prompt_and_parse(ReqProDB_Artifact.MODE mode, out bool cancelled)
2141 ghuddy 374
      {
2155 ghuddy 375
         cancelled = false;
2141 ghuddy 376
 
2151 ghuddy 377
         try
378
         {
379
            // If we can find a ReqProDB artifact in the package, use it to logon to the ReqPro database
380
            ReqProDB_Artifact RQ_Artifact = new ReqProDB_Artifact();
381
            EA.Element RQ_Element = RQ_Artifact.get_rq_artifact();
382
            if (RQ_Element != null)
383
            {
384
               // check to see if the ReqProDB element has the same mode as that specified by parameter
2155 ghuddy 385
               // however bypass the validation check if the mode of the artifact is undefined or the mode
386
               // of the current operation is "export".
2151 ghuddy 387
               ReqProDB_Artifact.MODE rq_art_mode = RQ_Artifact.get_mode(RQ_Element);
388
               if (rq_art_mode != ReqProDB_Artifact.MODE.UNDEFINED)
389
               {
2155 ghuddy 390
                  if (mode != ReqProDB_Artifact.MODE.EXPORT && rq_art_mode != mode)
2151 ghuddy 391
                  {
2155 ghuddy 392
                     MessageBoxEx.Show(
393
                        "You are attempting to use a ReqProDB element\n" +
394
                        "and associated EA model area for a different\n" +
395
                        "purpose than that which was specified when the\n" +
396
                        "element was first created.",
397
                        "Error");
398
                     cancelled = true;
399
                     return false;
2151 ghuddy 400
                  }
401
               }
402
 
403
               if (Main.mustAbort)
404
                  return false;
405
 
2155 ghuddy 406
               if (false == RQ_Artifact.OpenReqProProject(RQ_Element, out cancelled))
407
                  return false;
408
 
409
               if (cancelled == true)
410
                  return  false;
2151 ghuddy 411
            }
412
 
413
            if (Main.mustAbort)
414
               return false;
415
 
416
            // If no ReqProDB artifact found, prompt user to logon to the ReqPro database
2155 ghuddy 417
            if (false == ReqProDatabase.opened())
2151 ghuddy 418
            {
2155 ghuddy 419
               DialogResult dlgRes;
420
 
421
               // Confirm user wants to create a new reqpro import/export area.
422
               dlgRes = MessageBoxEx.Show(
423
                  "The area of EA model structure you have selected,\n" +
424
                  "does not appear to be part of an existing ReqPro\n" +
425
                  "import/export area.\n\n" +
426
                  "Do you wish to configure it for ReqPro import/export?\n\n" +
427
                  "If you choose YES, you will be asked to select a\n" +
428
                  "ReqPro database within the filesystem to associate\n" +
429
                  "with this EA model area.\n" +
430
                  "Choosing NO will cancel the operation.", 
431
                  "Confirm", MessageBoxButtons.YesNo);
432
               if (dlgRes == DialogResult.No)
433
               {
434
                  cancelled = true;
435
                  return false;
436
               }
437
 
2151 ghuddy 438
               // let user select the ReqPro database file name
439
               OpenFileDialog ofd = new OpenFileDialog();
440
               ofd.Title = "Select Requisite Pro project file";
441
               ofd.Filter = "ReqPro files (*.rqs)|*.rqs|All files (*.*)|*.*";
2155 ghuddy 442
               dlgRes = ofd.ShowDialog();
2151 ghuddy 443
               if (dlgRes != DialogResult.OK)
444
                  return false;
445
 
446
               if (Main.mustAbort)
447
                  return false;
448
 
449
               // let user specifiy username/password
450
               Logon logon = new Logon("");
451
               dlgRes = logon.ShowDialog();
452
               if (dlgRes != DialogResult.OK)
453
                  return false;
454
 
455
               if (Main.mustAbort)
456
                  return false;
457
 
458
               string username = logon.ebUserName.Text;
459
               string password = logon.ebPassword.Text;
460
 
461
               // Connect to the ReqPro database using the ReqPro extensibility mechanism
2155 ghuddy 462
               ReqProDatabase.open(ofd.FileName, username, password);
2151 ghuddy 463
 
464
               if (Main.mustAbort)
465
                  return false;
466
 
467
               // if we do not currently have a ReqProDB artifact, create one
468
               if (RQ_Element == null)
469
               {
470
                  RQ_Element = RQ_Artifact.create_rq_artifact(
2169 ghuddy 471
                     EA_ProjectBrowser.get_selected_package(), 
2155 ghuddy 472
                     ReqProDatabase.name(), 
473
                     ReqProDatabase.description(), 
2151 ghuddy 474
                     logon.ebUserName.Text, 
475
                     ofd.FileName, 
2155 ghuddy 476
                     ReqProDatabase.guid());
2151 ghuddy 477
               }
478
               if (Main.mustAbort)
479
                  return false;
480
            }
481
 
482
            if (Main.mustAbort)
483
               return false;
484
 
485
            // Now do the parsing of the ReqPro database
2155 ghuddy 486
            if (true == ReqProDatabase.opened())
2151 ghuddy 487
            {
2145 ghuddy 488
               // give req pro project object to user of this class
2155 ghuddy 489
               provideReqProDatabaseInfo(RQ_Artifact, RQ_Element);
2151 ghuddy 490
 
491
               // get the requirement types from the req pro project
2155 ghuddy 492
               get_rq_req_types_from_database();
2151 ghuddy 493
 
2155 ghuddy 494
               get_rq_req_status_types_from_database();
2151 ghuddy 495
 
496
               // Get the ReqPro root package and parse it
2155 ghuddy 497
               Main.WriteOutput("Acquiring ReqPro Database", -1);
2151 ghuddy 498
 
2155 ghuddy 499
               parseRootPackage(0, ReqProDatabase.get_root_package());
2151 ghuddy 500
 
2155 ghuddy 501
               Main.WriteSeperator();
502
 
2151 ghuddy 503
               if (Main.mustAbort)
504
                  return false;
505
 
506
               return true;
507
            }
508
         }
509
         catch (Exception ex)
510
         {
2153 ghuddy 511
            Main.MessageBoxException(ex, "Exception (prompt_and_parse)");
2155 ghuddy 512
            ReqProDatabase.close();
2141 ghuddy 513
         }  
514
         return false;
2151 ghuddy 515
      }
516
 
2141 ghuddy 517
      /// <summary>
518
      /// This method handles the parsing of the root package in the ReqPro database.
519
      /// The method is almost identical to the parsePackage method, except that this
520
      /// deals with a ReqPro40.RootPackage object, whereas the latter deals with a
521
      /// ReqPro40.Package object. Perhaps the two functions could be combined into 
522
      /// one if we move to .NET 2 where c# has some support for generic (template)
523
      /// programming.
524
      /// </summary>
525
      /// <param name="repository"></param>
526
      /// <param name="rq_project"></param>
2151 ghuddy 527
      /// <param name="thisPackage"></param>
528
      private void parseRootPackage(int level,
529
                                    ReqPro40.RootPackage thisPackage)
530
      {
531
         // Scan through the sub-packages of the root package
532
         int limit_packageCount = thisPackage.get_Count(ReqPro40.enumElementTypes.eElemType_Package);
533
         if (limit_packageCount > 0)
534
         {
535
            int i_packageCount;
536
            thisPackage.MoveFirst();
537
            for (i_packageCount = 0; i_packageCount < limit_packageCount; i_packageCount++)
538
            {
539
               if (Main.mustAbort)
540
                  break;
541
 
542
               // Read the sub-package and parse it
543
               ReqPro40.Package subPackage = (ReqPro40.Package)thisPackage.GetCurrentElement();
2155 ghuddy 544
               parsePackage(level+1, "", subPackage);
2151 ghuddy 545
               thisPackage.MoveNext();
546
            }
547
         }
548
 
549
         if (Main.mustAbort)
550
            return;
551
 
2155 ghuddy 552
         if (structure_only == false)
2151 ghuddy 553
         {
2155 ghuddy 554
            // Scan through the requirements directly beneath the root package
555
            int limit_reqCount = thisPackage.get_Count(ReqPro40.enumElementTypes.eElemType_Requirement);
556
            if (limit_reqCount > 0)
2151 ghuddy 557
            {
2155 ghuddy 558
               // Obtain the requirement element key list from the root package and scan through each entry
559
               int i_reqCount;
560
               System.Object[,] keyList = (System.Object[,])thisPackage.KeyList(ReqPro40.enumElementTypes.eElemType_Requirement);
561
               for (i_reqCount = 0; i_reqCount < limit_reqCount; i_reqCount++)
562
               {
563
                  if (Main.mustAbort)
564
                     break;
2151 ghuddy 565
 
2155 ghuddy 566
                  // Obtain the ReqPro requirement from its key, and parse it
567
                  ReqPro40.Requirement thisRequirement = ReqProDatabase.get_requirement_by_key(keyList[0,i_reqCount]);
568
                  if (thisRequirement != null)
569
                  {
570
                     parseRequirement(level+1, null, thisRequirement);                  
571
                  }
2151 ghuddy 572
               }
573
            }
574
         }
575
      }
576
 
2141 ghuddy 577
      /// <summary>
578
      /// This method handles the parsing of each package beneath the root package
579
      /// in the ReqPro database.
580
      /// The method is almost identical to the parseRootPackage method, except that 
581
      /// this deals with a ReqPro40.Package object, whereas the latter deals with a
582
      /// ReqPro40.RootPackage object. Perhaps the two functions could be combined into 
583
      /// one if we move to .NET 2 where c# has some support for generic (template)
584
      /// programming.      
585
      /// </summary>
586
      /// <param name="repository"></param>
587
      /// <param name="rq_project"></param>
2151 ghuddy 588
      /// <param name="thisPackage"></param>
589
      private void parsePackage(int level,
590
                                string prefix,
591
                                ReqPro40.Package thisPackage)
592
      {
593
         if (Main.mustAbort)
594
            return;
595
 
2155 ghuddy 596
         Main.WriteOutput(prefix + thisPackage.Name, -1);
2151 ghuddy 597
 
598
         // call user defined functions
2155 ghuddy 599
         processPackage(level, thisPackage);
600
         processObject(level, thisPackage, null);
2151 ghuddy 601
 
602
         // Scan through the sub-packages of this package
603
         int limit_packageCount = thisPackage.get_Count(ReqPro40.enumElementTypes.eElemType_Package);
604
         if (limit_packageCount > 0)
605
         {
606
            int i_packageCount;
607
            thisPackage.MoveFirst();
608
            for (i_packageCount = 0; i_packageCount < limit_packageCount; i_packageCount++)
609
            {
610
               if (Main.mustAbort)
611
                  break;
612
 
613
               // Read the sub-package and parse it
614
               ReqPro40.Package subPackage = (ReqPro40.Package)thisPackage.GetCurrentElement();
2155 ghuddy 615
               parsePackage(level+1, prefix + "    ", subPackage);
2151 ghuddy 616
               thisPackage.MoveNext();
617
            }
618
         }
619
 
620
         if (Main.mustAbort)
621
            return;
622
 
2155 ghuddy 623
         if (structure_only == false)
2151 ghuddy 624
         {
2155 ghuddy 625
            // Scan through the requirements directly beneath this package
626
            int limit_reqCount = thisPackage.get_Count(ReqPro40.enumElementTypes.eElemType_Requirement);
627
            if (limit_reqCount > 0)
2151 ghuddy 628
            {
2155 ghuddy 629
               // Obtain the requirement element key list from this package and scan through each entry
630
               int i_reqCount;
631
               System.Object[,] keyList = (System.Object[,])thisPackage.KeyList(ReqPro40.enumElementTypes.eElemType_Requirement);
632
               for (i_reqCount = 0; i_reqCount < limit_reqCount; i_reqCount++)
633
               {
634
                  if (Main.mustAbort)
635
                     break;
2151 ghuddy 636
 
2155 ghuddy 637
                  // Obtain the ReqPro requirement from its key, and parse it
638
                  ReqPro40.Requirement thisRequirement = ReqProDatabase.get_requirement_by_key(keyList[0,i_reqCount]);
639
                  if (thisRequirement != null)
640
                  {
641
                     parseRequirement(level+1, thisPackage, thisRequirement);                  
642
                  }
2151 ghuddy 643
               }
644
            }
645
         }
646
      }
647
 
648
 
649
 
2141 ghuddy 650
      /// <summary>
651
      /// This method parses a requirement and any sub-requirements found in the 
652
      /// ReqPro database by the package/root package parsers.
653
      /// NOTE that when called from the parseRootPackage method, the thisPackage
654
      /// parameter will be null.
655
      /// </summary>
656
      /// <param name="repository"></param>
657
      /// <param name="rq_project"></param>
658
      /// <param name="thisPackage"></param>
2151 ghuddy 659
      /// <param name="thisRequirement"></param>
660
      private void parseRequirement(int level,
661
                                    ReqPro40.Package thisPackage, 
662
                                    ReqPro40.Requirement thisRequirement)
663
      {
664
         if (Main.mustAbort)
665
            return;
2141 ghuddy 666
 
2151 ghuddy 667
         // call user defined functions
2155 ghuddy 668
         processRequirement(level, thisPackage, thisRequirement);
669
         processObject(level, thisPackage, thisRequirement);
2151 ghuddy 670
 
671
         // requirements can have children that are requirements, so we have to find those
672
         int limit_numberOfChildren = 0;
673
         if (true == thisRequirement.get_HasChildren(ref limit_numberOfChildren))
674
         {
675
            // scan through the child relationships
676
            ReqPro40.Relationships theseRelationships = (ReqPro40.Relationships)thisRequirement.Children;
677
 
678
            int i_numberOfChildren;
679
            theseRelationships.MoveFirst();
680
            for (i_numberOfChildren = 0; i_numberOfChildren < limit_numberOfChildren; i_numberOfChildren++)
681
            {
682
               if (Main.mustAbort)
683
                  break;
684
 
685
               // Obtain the sub-requirement from the relationship, and parse it
686
               ReqPro40.Relationship thisRelationship = theseRelationships.GetCurrentRelationship();
687
 
688
               ReqPro40.Requirement subRequirement = 
689
                  thisRelationship.get_DestinationRequirement(ReqPro40.enumRequirementsWeights.eReqWeight_Heavy);
690
 
691
               if (subRequirement != null)
692
               {
2155 ghuddy 693
                  parseRequirement(level+1, thisPackage, subRequirement);
2151 ghuddy 694
               }
695
 
696
               theseRelationships.MoveNext();
697
            }
698
         }
699
      }
700
 
2141 ghuddy 701
	}
2151 ghuddy 702
 
2155 ghuddy 703
 
704
 
705
 
2141 ghuddy 706
}