Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
2141 ghuddy 1
using System;
2
using System.Text;
3
using System.Globalization;
4
using System.Collections;
5
using System.Windows.Forms;
6
using ReqPro40;
7
 
8
 
9
namespace EA_ReqPro
10
{
11
	/// <summary>
12
	/// The ReqProParser class encapsulates a parsing algorithm for a ReqPro database
13
	/// designed to pick out packages and requirement elements and to provide that information
14
	/// to a client with sufficient information to allow it to build a model of that ReqPro
15
	/// database content in memory, maintaining the hierarchy and ordering of objects found.
16
	/// </summary>
17
	public class ReqProParser
18
	{
19
		public ReqProParser()
20
		{
21
		}
22
 
23
      /// <summary>
24
      /// The parser will call this virtual method when it has opened a ReqPro project
25
      /// </summary>
26
      /// <param name="rq_project"></param>
2145 ghuddy 27
      protected virtual void provideReqProDatabaseInfo(ReqPro40.Application rq_app, 
28
         ReqPro40.Project rq_project, 
29
         ReqProDB_Artifact rq_artifact,
30
         EA.Element rq_element)
2141 ghuddy 31
      {
32
      }
33
 
34
      /// <summary>
35
      /// The parser will call this virtual method for every package it finds
36
      /// in the ReqPro database.
37
      /// </summary>
38
      /// <param name="level"></param>
39
      /// <param name="ea_repository"></param>
40
      /// <param name="rq_project"></param>
41
      /// <param name="rq_Package"></param>
42
      protected virtual void processPackage(int level,
43
                                            EA.Repository ea_repository, 
44
                                            ReqPro40.Project rq_project, 
45
                                            ReqPro40.Package rq_package)
46
      {
47
      }
48
 
49
      /// <summary>
50
      /// The parser will call this virtual method for every requirement it
51
      /// finds in the ReqPro database.
52
      /// </summary>
53
      /// <param name="level"></param>
54
      /// <param name="ea_repository"></param>
55
      /// <param name="rq_project"></param>
56
      /// <param name="rq_Package"></param>
57
      /// <param name="rq_Requirement"></param>
58
      protected virtual void processRequirement(int level,
59
                                                EA.Repository ea_repository, 
60
                                                ReqPro40.Project rq_project, 
61
                                                ReqPro40.Package rq_package,
62
                                                ReqPro40.Requirement rq_requirement)
63
      {
64
      }
65
 
66
      /// <summary>
67
      /// The parser will call this virtual method for every package or requirement it
68
      /// finds in the ReqPro database.
69
      /// </summary>
70
      /// <param name="level"></param>
71
      /// <param name="ea_repository"></param>
72
      /// <param name="rq_project"></param>
73
      /// <param name="rq_Package"></param>
74
      /// <param name="rq_Requirement"></param>
75
      protected virtual void processObject(int level,
76
                                           EA.Repository ea_repository, 
77
                                           ReqPro40.Project rq_project, 
78
                                           ReqPro40.Package rq_package,
79
                                           ReqPro40.Requirement rq_requirement)
80
      {
81
      }
82
 
83
 
84
 
85
 
86
      /// <summary>
87
      /// Initiates a ReqPro database parsing operation using a prompted reqpro database open operation
88
      /// </summary>
89
      /// <param name="ea_repository"></param>
90
      /// <returns></returns>
2145 ghuddy 91
      public virtual bool prompt_and_parse(EA.Repository ea_repository, ReqProDB_Artifact.MODE mode)
2141 ghuddy 92
      {
2145 ghuddy 93
         ReqPro40.Application rq_app = null;
2141 ghuddy 94
         ReqPro40.Project rq_project = null;
95
 
96
         try
97
         {
2145 ghuddy 98
            // If we can find a ReqProDB artifact in the package, use it to logon to the ReqPro database
99
            ReqProDB_Artifact RQ_Artifact = new ReqProDB_Artifact();
100
            EA.Element RQ_Element = RQ_Artifact.get_rq_artifact(ea_repository);
101
            if (RQ_Element != null)
102
            {
103
               // check to see if the ReqProDB element has the same mode as that specified by parameter
104
               ReqProDB_Artifact.MODE rq_art_mode = RQ_Artifact.get_mode(ea_repository, RQ_Element);
105
               if (rq_art_mode != ReqProDB_Artifact.MODE.UNDEFINED)
106
               {
107
                  if (rq_art_mode != mode)
108
                  {
109
                     DialogResult dlgRes = MessageBox.Show("You are attempting to use a ReqProDB element\n" +
110
                        "for a different purpose than that which was\n" +
111
                        "specified when the element was first created.\n" +
112
                        "Continue Anyway?", "Confirm", MessageBoxButtons.YesNo);
113
                     if (dlgRes != DialogResult.Yes)
114
                     {
115
                        return false;
116
                     }
117
                  }
118
               }
2141 ghuddy 119
 
2145 ghuddy 120
               rq_project = RQ_Artifact.OpenReqProProject(ea_repository, RQ_Element);
121
               if (rq_project != null)
122
                  rq_app = RQ_Artifact.RQ_app;
123
            }
124
 
125
            // If no ReqProDB artifact found, prompt user to logon to the ReqPro database
126
            if (rq_project == null)
2141 ghuddy 127
            {
2145 ghuddy 128
               // let user select the ReqPro database file name
129
               OpenFileDialog ofd = new OpenFileDialog();
130
               ofd.Title = "Select Requisite Pro project file";
131
               ofd.Filter = "ReqPro files (*.rqs)|*.rqs|All files (*.*)|*.*";
132
               DialogResult dlgRes = ofd.ShowDialog();
133
               if (dlgRes != DialogResult.OK)
134
                  return false;
135
 
2141 ghuddy 136
               // let user specifiy username/password
137
               Logon logon = new Logon("");
138
               dlgRes = logon.ShowDialog();
2145 ghuddy 139
               if (dlgRes != DialogResult.OK)
140
                  return false;
2141 ghuddy 141
 
2145 ghuddy 142
               string username = logon.ebUserName.Text;
143
               string password = logon.ebPassword.Text;
2141 ghuddy 144
 
2145 ghuddy 145
               // Connect to the ReqPro database using the ReqPro extensibility mechanism
146
               rq_app = new ReqPro40.ApplicationClass();
2141 ghuddy 147
 
2145 ghuddy 148
               rq_project = 
149
                  rq_app.OpenProject(ofd.FileName,
150
                  ReqPro40.enumOpenProjectOptions.eOpenProjOpt_RQSFile,
151
                  username,
152
                  password, 
153
                  enumProjectFlags.eProjFlag_Normal,
154
                  enumRelatedProjectOptions.eRelatedProjOption_ConnectAsSpecified);
2141 ghuddy 155
 
2145 ghuddy 156
               // if we do not currently have a ReqProDB artifact, create one
157
               if (RQ_Element == null)
158
               {
159
                  EA_Utilities EA_Utils = new EA_Utilities(ea_repository);
2141 ghuddy 160
 
2145 ghuddy 161
                  RQ_Element = RQ_Artifact.create_rq_artifact( ea_repository, 
162
                     EA_Utils.get_selected_package(), 
163
                     rq_project.Name, 
164
                     rq_project.Description, 
165
                     logon.ebUserName.Text, 
166
                     ofd.FileName, 
167
                     rq_project.GUID);
2141 ghuddy 168
               }
169
            }
2145 ghuddy 170
 
171
 
172
 
173
            // Now do the parsing of the ReqPro database
174
            if (rq_project != null)
175
            {
176
               // give req pro project object to user of this class
177
               provideReqProDatabaseInfo(rq_app, rq_project, RQ_Artifact, RQ_Element);
178
 
179
               // Get the ReqPro root package and parse it
180
               ReqPro40.RootPackage rq_rootPackage = rq_project.GetRootPackage(true);
181
 
182
               parseRootPackage(0, ea_repository, rq_project, rq_rootPackage);
183
               return true;
184
            }
2141 ghuddy 185
         }
186
         catch (Exception ex)
187
         {
188
            MessageBox.Show(ex.Message, "Error (ReqProParser::prompt_and_parse)", MessageBoxButtons.OK);
189
            if (rq_project != null)
190
               rq_project.CloseProject();
191
         }  
192
         return false;
193
      }
194
 
195
      /// <summary>
196
      /// This method handles the parsing of the root package in the ReqPro database.
197
      /// The method is almost identical to the parsePackage method, except that this
198
      /// deals with a ReqPro40.RootPackage object, whereas the latter deals with a
199
      /// ReqPro40.Package object. Perhaps the two functions could be combined into 
200
      /// one if we move to .NET 2 where c# has some support for generic (template)
201
      /// programming.
202
      /// </summary>
203
      /// <param name="repository"></param>
204
      /// <param name="rq_project"></param>
205
      /// <param name="thisPackage"></param>
206
      private void parseRootPackage(int level,
207
                                    EA.Repository ea_repository, 
208
                                    ReqPro40.Project rq_project, 
209
                                    ReqPro40.RootPackage thisPackage)
210
      {
211
         // Scan through the sub-packages of the root package
212
         int limit_packageCount = thisPackage.get_Count(ReqPro40.enumElementTypes.eElemType_Package);
213
         if (limit_packageCount > 0)
214
         {
215
            int i_packageCount;
216
            thisPackage.MoveFirst();
217
            for (i_packageCount = 0; i_packageCount < limit_packageCount; i_packageCount++)
218
            {
219
               // Read the sub-package and parse it
220
               ReqPro40.Package subPackage = (ReqPro40.Package)thisPackage.GetCurrentElement();
221
               parsePackage(level+1, ea_repository, rq_project, subPackage);
222
               thisPackage.MoveNext();
223
            }
224
         }
225
 
226
         // Scan through the requirements directly beneath the root package
227
         int limit_reqCount = thisPackage.get_Count(ReqPro40.enumElementTypes.eElemType_Requirement);
228
         if (limit_reqCount > 0)
229
         {
230
            // Obtain the requirement element key list from the root package and scan through each entry
231
            int i_reqCount;
232
            System.Object[,] keyList = (System.Object[,])thisPackage.KeyList(ReqPro40.enumElementTypes.eElemType_Requirement);
233
            for (i_reqCount = 0; i_reqCount < limit_reqCount; i_reqCount++)
234
            {
235
               // Obtain the ReqPro requirement from its key, and parse it
236
               ReqPro40.Requirement thisRequirement = 
237
                  rq_project.GetRequirement(keyList[0,i_reqCount],
238
                                            ReqPro40.enumRequirementLookups.eReqLookup_Key,
239
                                            ReqPro40.enumRequirementsWeights.eReqWeight_Heavy,
240
                                            ReqPro40.enumRequirementFlags.eReqFlag_RetainHierarchy);
241
 
242
               if (thisRequirement != null)
243
               {
244
                  parseRequirement(level+1, ea_repository, rq_project, null, thisRequirement);                  
245
               }
246
            }
247
         }
248
      }
249
 
250
      /// <summary>
251
      /// This method handles the parsing of each package beneath the root package
252
      /// in the ReqPro database.
253
      /// The method is almost identical to the parseRootPackage method, except that 
254
      /// this deals with a ReqPro40.Package object, whereas the latter deals with a
255
      /// ReqPro40.RootPackage object. Perhaps the two functions could be combined into 
256
      /// one if we move to .NET 2 where c# has some support for generic (template)
257
      /// programming.      
258
      /// </summary>
259
      /// <param name="repository"></param>
260
      /// <param name="rq_project"></param>
261
      /// <param name="thisPackage"></param>
262
      private void parsePackage(int level,
263
                                EA.Repository ea_repository, 
264
                                ReqPro40.Project rq_project, 
265
                                ReqPro40.Package thisPackage)
266
      {
267
         // call user defined functions
268
         processPackage(level, ea_repository, rq_project, thisPackage);
269
         processObject(level, ea_repository, rq_project, thisPackage, null);
270
 
271
         // Scan through the sub-packages of this package
272
         int limit_packageCount = thisPackage.get_Count(ReqPro40.enumElementTypes.eElemType_Package);
273
         if (limit_packageCount > 0)
274
         {
275
            int i_packageCount;
276
            thisPackage.MoveFirst();
277
            for (i_packageCount = 0; i_packageCount < limit_packageCount; i_packageCount++)
278
            {
279
               // Read the sub-package and parse it
280
               ReqPro40.Package subPackage = (ReqPro40.Package)thisPackage.GetCurrentElement();
281
               parsePackage(level+1, ea_repository, rq_project, subPackage);
282
               thisPackage.MoveNext();
283
            }
284
         }
285
 
286
         // Scan through the requirements directly beneath this package
287
         int limit_reqCount = thisPackage.get_Count(ReqPro40.enumElementTypes.eElemType_Requirement);
288
         if (limit_reqCount > 0)
289
         {
290
            // Obtain the requirement element key list from this package and scan through each entry
291
            int i_reqCount;
292
            System.Object[,] keyList = (System.Object[,])thisPackage.KeyList(ReqPro40.enumElementTypes.eElemType_Requirement);
293
            for (i_reqCount = 0; i_reqCount < limit_reqCount; i_reqCount++)
294
            {
295
               // Obtain the ReqPro requirement from its key, and parse it
296
               ReqPro40.Requirement thisRequirement = 
297
                  rq_project.GetRequirement(keyList[0,i_reqCount],
298
                                            ReqPro40.enumRequirementLookups.eReqLookup_Key,
299
                                            ReqPro40.enumRequirementsWeights.eReqWeight_Heavy,
300
                                            ReqPro40.enumRequirementFlags.eReqFlag_RetainHierarchy);
301
               if (thisRequirement != null)
302
               {
303
                  parseRequirement(level+1, ea_repository, rq_project, thisPackage, thisRequirement);                  
304
               }
305
            }
306
         }
307
      }
308
 
309
 
310
 
311
      /// <summary>
312
      /// This method parses a requirement and any sub-requirements found in the 
313
      /// ReqPro database by the package/root package parsers.
314
      /// NOTE that when called from the parseRootPackage method, the thisPackage
315
      /// parameter will be null.
316
      /// </summary>
317
      /// <param name="repository"></param>
318
      /// <param name="rq_project"></param>
319
      /// <param name="thisPackage"></param>
320
      /// <param name="thisRequirement"></param>
321
      private void parseRequirement(int level,
322
                                    EA.Repository ea_repository, 
323
                                    ReqPro40.Project rq_project, 
324
                                    ReqPro40.Package thisPackage, 
325
                                    ReqPro40.Requirement thisRequirement)
326
      {
327
         // call user defined functions
328
         processRequirement(level, ea_repository, rq_project, thisPackage, thisRequirement);
329
         processObject(level, ea_repository, rq_project, thisPackage, thisRequirement);
330
 
331
         // requirements can have children that are requirements, so we have to find those
332
         int limit_numberOfChildren = 0;
333
         if (true == thisRequirement.get_HasChildren(ref limit_numberOfChildren))
334
         {
335
            // scan through the child relationships
336
            ReqPro40.Relationships theseRelationships = (ReqPro40.Relationships)thisRequirement.Children;
337
 
338
            int i_numberOfChildren;
339
            theseRelationships.MoveFirst();
340
            for (i_numberOfChildren = 0; i_numberOfChildren < limit_numberOfChildren; i_numberOfChildren++)
341
            {
342
               // Obtain the sub-requirement from the relationship, and parse it
343
               ReqPro40.Relationship thisRelationship = theseRelationships.GetCurrentRelationship();
344
 
345
               ReqPro40.Requirement subRequirement = 
346
                  thisRelationship.get_DestinationRequirement(ReqPro40.enumRequirementsWeights.eReqWeight_Heavy);
347
 
348
               if (subRequirement != null)
349
               {
350
                  parseRequirement(level+1, ea_repository, rq_project, thisPackage, subRequirement);
351
               }
352
 
353
               theseRelationships.MoveNext();
354
            }
355
         }
356
      }
357
 
358
	}
359
}