Subversion Repositories DevTools

Rev

Rev 2145 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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