Subversion Repositories DevTools

Rev

Rev 2143 | Rev 2149 | 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
namespace EA_ReqPro
9
{
10
	/// <summary>
11
	/// CopyReqProDatabase is a specialisation of ReqProParser, designed to copy the 
12
	/// ReqPro database content into an EA database, maintaining the structure of 
13
	/// and hierarchy of packages and requirements found in the ReqPro database.
14
	/// </summary>
15
   public class CopyReqProDatabase : CopyReqProDatabaseToMemory
16
   {
17
      /// <summary>
18
      /// Construct the object
19
      /// </summary>
20
      /// <param name="ea_repository"></param>
21
      public CopyReqProDatabase(EA.Repository ea_repository): base(ea_repository)
22
      {
23
      }
24
 
25
 
26
      /// <summary>
27
      /// Method to parse a ReqPro database and copy it into an EA database.
28
      /// </summary>
29
      /// <param name="ea_repository"></param>
30
      /// <returns></returns>
2145 ghuddy 31
      public override bool prompt_and_parse(EA.Repository ea_repository, ReqProDB_Artifact.MODE mode)
2141 ghuddy 32
      {
33
         try
34
         {
35
            // use the base classes parser to read the ReqPro database content and allow the user to
36
            // filter it.
2145 ghuddy 37
            if (true == base.prompt_and_parse(ea_repository, mode))
2141 ghuddy 38
            {
2145 ghuddy 39
               try
40
               {
41
                  // Look for existing requirement elements
42
                  bool reqElementsFound = false;
43
                  for(short i=0; i < ea_rootPackage.Elements.Count; i++)
44
                  {
45
                     if ( ((EA.Element)ea_rootPackage.Elements.GetAt(i)).Type.StartsWith("Requirement") )
46
                     {
47
                        reqElementsFound = true;
48
                     }
49
                  }
50
 
51
                  // if there are existing requirement elements or sub-packages...
52
                  if (reqElementsFound == true
53
                     || ea_rootPackage.Packages.Count > 0)
54
                  {
55
                     DialogResult dlgRes = MessageBox.Show("Package is not empty, delete existing content first?", "Confirm", MessageBoxButtons.YesNo);
56
                     if (dlgRes == DialogResult.Yes)
57
                     {
58
                        // Delete packages and requirement elements
59
                        short i;
60
                        for(i=0; i < ea_rootPackage.Packages.Count; i++)
61
                        {
62
                           ea_rootPackage.Packages.Delete(i);
63
                        }
64
                        for(i=0; i < ea_rootPackage.Elements.Count; i++)
65
                        {
66
                           if ( ((EA.Element)ea_rootPackage.Elements.GetAt(i)).Type.StartsWith("Requirement") )
67
                           {
68
                              ea_rootPackage.Elements.Delete(i);
69
                           }
70
                        }
71
                        ea_rootPackage.Packages.Refresh();
72
                        // refresh project browser view
73
                        ea_repository.RefreshModelView(ea_rootPackage.PackageID);
74
                     }
75
                  }
76
               }
77
               catch (Exception ex)
78
               {
79
                  MessageBox.Show(ex.Message, "Error (CopyReqProDatabase::CopyReqProDatabase)", MessageBoxButtons.OK);
80
               }   
81
 
2141 ghuddy 82
               ea_repository.EnsureOutputVisible(Main.GUI_OUTPUT_TAB_NAME);
83
 
84
               // write the captured info from reqpro, into the ea database, obeying the filter
85
               // settings the user has specified.
86
               write_ea_database(ea_repository);
2145 ghuddy 87
 
88
               // Configure the ReqProDB artifact as a document model artifact
89
               RQ_Artifact.set_doc_model_mode(ea_repository, RQ_Element);
90
 
2143 ghuddy 91
               MessageBox.Show("Import Completed");
2141 ghuddy 92
               return true;
93
            }
94
         }
95
         catch (Exception ex)
96
         {
97
            MessageBox.Show(ex.Message, "Error (CopyReqProDatabase::parse)", MessageBoxButtons.OK);
98
         }      
99
         return false;
100
      }
101
 
102
 
103
 
2143 ghuddy 104
      /// <summary>
105
      /// Finds and returns the ReqPro_object instance that contains the specified GUID. The
106
      /// GUID is that of the originating ReqPro requirement, which is copied into a ReqPro_object
107
      /// instance when it is created. This find operation supports the ability to resolve object to
108
      /// object trace relationships mirrored from the ReqPro database during the construction
109
      /// of the ReqPro_object hierarchy.
110
      /// </summary>
111
      /// <param name="rq_obj"></param>
112
      /// <param name="ReqProGUID"></param>
113
      /// <returns></returns>
114
      private ReqPro_object findReqPro_object_byReqProGUID(ReqPro_object rq_obj, string ReqProGUID)
115
      {
116
         if (rq_obj.guid.CompareTo(ReqProGUID) == 0)
117
         {
118
            return rq_obj;
119
         }
2141 ghuddy 120
 
2143 ghuddy 121
         foreach (ReqPro_object sub_rq_obj in rq_obj.ReqPro_objects)
122
         {
123
            ReqPro_object tgt_obj = findReqPro_object_byReqProGUID(sub_rq_obj, ReqProGUID);
124
            if (tgt_obj != null)
125
               return tgt_obj;
126
         }
127
 
128
         return null;
129
      }
2141 ghuddy 130
 
131
 
132
      /// <summary>
2143 ghuddy 133
      /// This method examines all of the ReqPro_object trace relationships and mirrors them in 
134
      /// the EA requirement elements that have been formed from each un-filtered ReqPro_objects.
135
      /// </summary>
136
      /// <param name="ea_repository"></param>
137
      /// <param name="rq_obj"></param>
138
      private void write_traces(EA.Repository ea_repository, ReqPro_object rq_obj)
139
      {
140
         if (rq_obj.isRequirement)
141
         {
142
            // if this object had an EA element made for it during the write_ea_database() process...
143
            if (rq_obj.ea_element_ID != -1)
144
            {
145
               EA.Element ea_rq_obj = ea_repository.GetElementByID(rq_obj.ea_element_ID);
146
               if (ea_rq_obj != null)
147
               {
148
                  foreach(string s in rq_obj.ReqPro_traces)
149
                  {
150
                     ReqPro_object tgt_obj = findReqPro_object_byReqProGUID(rq_root_package,s);
151
                     if (tgt_obj != null)
152
                     {
153
                        if (tgt_obj.ea_element_ID != -1)
154
                        {
155
                           EA.Element ea_tgt_obj = ea_repository.GetElementByID(tgt_obj.ea_element_ID);
156
                           if (ea_tgt_obj != null)
157
                           {
158
                              add_connection(ea_repository, ea_rq_obj, ea_tgt_obj);
159
                           }
160
                        }
161
                     }
162
                  }
163
               }
164
            }
165
         }
166
 
167
         // recurse to ensure we examine the entire hiearchy
168
         foreach(ReqPro_object sub_obj in rq_obj.ReqPro_objects)
169
         {
170
            write_traces(ea_repository, sub_obj);
171
         }
172
      }
173
 
174
      /// <summary>
175
      /// Adds a connection between one EA element and another
176
      /// </summary>
177
      /// <param name="repository"></param>
178
      /// <param name="rq_artifact"></param>
179
      /// <param name="ea_req"></param>
180
      private void add_connection(EA.Repository ea_repository, EA.Element src_element, EA.Element dest_element)
181
      {
182
         // Add the new requirement to the src_element
183
         EA.Connector c = (EA.Connector)src_element.Connectors.AddNew("", "Relationship");
184
         c.SupplierID = dest_element.ElementID;
185
         //c.Stereotype = "trace";
186
         c.Direction = "Source -> Destination";
187
         if (false == c.Update())
188
         {
189
            ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "New Connector Error : " + c.GetLastError(), dest_element.ElementID );
190
         }
191
         src_element.Connectors.Refresh();
192
      }
193
 
194
      /// <summary>
2141 ghuddy 195
      /// This method (along with its sibling overloads) perform the copy operation once
196
      /// the ReqPro database content has been acquired, and the user has submitted their
197
      /// filtering requirements. This method begins the copy operation, but the real nitty
198
      /// gritty of it occurs in the other overloaded method.
199
      /// </summary>
200
      /// <param name="ea_repository"></param>
201
      private void write_ea_database(EA.Repository ea_repository)
202
      {
203
         ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Copying ReqPro Database Content to EA", -1);
204
 
205
         foreach( ReqPro_object sub_obj in rq_root_package.ReqPro_objects )
206
         {
207
            write_ea_database(ea_repository, ea_rootPackage, null, sub_obj);
208
         }
209
 
210
         ea_rootPackage.Packages.Refresh();
211
         // refresh project browser view
212
         ea_repository.RefreshModelView(ea_rootPackage.PackageID);
2143 ghuddy 213
 
214
         // Setup the internal requirement to requirement connectivity. This is seperate from the browser
215
         // organisation of elements in EA, but since in ReqPro, that organisation tells part of the story
216
         // of requirement to requirement connectivity, it is mirrored in the internal connectivity, along
217
         // with explicit trace relationships setup in ReqPro.
218
         // The purpose of this internal connectivity is to support relationship matrix tables in documentation
219
         // generated by EA_DocGen, or to support diagrammatic representations of the requirements in EA,
220
         // where the connectivity will become apparent through links ajoining the requirement elements in the
221
         // diagram.
222
         ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Writing Trace Information", -1);
223
         foreach( ReqPro_object sub_obj in rq_root_package.ReqPro_objects )
224
         {
225
            write_traces(ea_repository, sub_obj);
226
         }
2141 ghuddy 227
      }
228
 
229
      private void write_ea_database(EA.Repository ea_repository,
230
                                     EA.Package ea_parent_package,
231
                                     EA.Element ea_parent_element,
232
                                     ReqPro_object rq_obj )
233
      {
234
         if (rq_obj.isPackage)
235
         {
236
            if (rq_obj.filtered == false)
237
            {
238
               if (ea_parent_package != null)
239
               {
240
                  // create a representative package in EA
241
                  EA.Package new_ea_package = EA_Utils.createPackage(ea_parent_package, rq_obj.name, rq_obj.treePos);
2143 ghuddy 242
                  rq_obj.ea_element_ID = new_ea_package.PackageID;
2141 ghuddy 243
                  ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Created Package : " + rq_obj.name, new_ea_package.PackageID );
244
 
245
                  // Using recursion, scan this objects sub-objects
246
                  foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
247
                  {
248
                     write_ea_database(ea_repository, new_ea_package, null, sub_obj);
249
                  }
250
               }
251
               else
252
               {
2143 ghuddy 253
                  // should never get here - I have never seen it happen so far.
2141 ghuddy 254
                  ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "ERROR,write_ea_database, parent package was null", -1);
255
               }
256
            }
257
            else if (base.allowPackageStructureFragments)
258
            {
259
               // Using recursion, scan this objects sub-objects
260
               foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
261
               {
262
                  if (sub_obj.isPackage)
263
                     write_ea_database(ea_repository, ea_parent_package, null, sub_obj);
264
               }
265
            }
266
         }
267
         else if (rq_obj.isRequirement)
268
         {
269
            if ( ! (reqTypeIsFiltered(rq_obj) || reqStatusTypeIsFiltered(rq_obj)))
270
            {
2143 ghuddy 271
               string rq_obj_name = rq_obj.tag + " " + rq_obj.name;
272
 
273
               // If needed, create the requirement element as a child of a parent element
2141 ghuddy 274
               if (ea_parent_element != null)
275
               {
276
                  // create a representative element in EA
2143 ghuddy 277
                  EA.Element new_ea_element = (EA.Element)ea_parent_element.Elements.AddNew(rq_obj_name, "Requirement");
278
                  rq_obj.ea_element_ID = new_ea_element.ElementID;
279
                  ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Created Element : " + rq_obj_name, new_ea_element.ElementID );
2141 ghuddy 280
 
2143 ghuddy 281
                  // In ReqPro, a requirement can be related to another requirement in several ways:
282
                  // 1. By virtue of its position relative to another in the browser display. That is, 
283
                  //    if you place a requirement beneath a parent requirement, you are establishing a 
284
                  //    parent-child relationship.
285
                  // 2. By virtue of a specific TraceTo relationship being made via the Traceability menu
286
                  //    option. 
287
                  // Interestingly, ReqPro prevents you creating a relationship of one of the above types,
288
                  // if a relationship of the other type already exists. This implies that the relationship
289
                  // between a parent and child requirement must be singular and is important regardless
290
                  // of the manner in which it was created or represented.
291
                  // The CopyReqProDatabaseToMemory base class will already have taken care of recording
292
                  // relationships detected from ReqPro made using method 2 above. What we need to do here is
293
                  // take care of those apparent from the browser based hierarchical organisation (ie. made
294
                  // in ReqPro using method 1).
295
                  // All we need to do is grab the parent object (if any) and add the GUID of the child to 
296
                  // its list of trace-to's. Later on, the write_traces() class method will turn these into
297
                  // EA based connection objects that belong to the parent requirement elements.
298
                  if (rq_obj.parent != null)
299
                  {
300
                     rq_obj.parent.ReqPro_traces.Add(rq_obj.guid);
301
                  }
302
 
2141 ghuddy 303
                  // If the ReqPro requirements detailed text is more than what the name already contains (allowing for it
304
                  // to have a stop character that the name may not have) then copy it over, otherwise ignore it. This
305
                  // prevents the same text appearing twice in any generated document made using EA_DocGen.
306
                  if (!rq_obj.text.StartsWith(rq_obj.name) || (rq_obj.text.Length > (rq_obj.name.Length + 1)))
307
                     new_ea_element.Notes = rq_obj.text;
308
 
309
                  new_ea_element.TreePos = rq_obj.treePos;
310
                  new_ea_element.Status  = rq_obj.status;
311
                  new_ea_element.Update();
312
 
2143 ghuddy 313
                  // Write EA tag information exactly as is done for the import for traceability use. This 
314
                  // opens up the possibility that a document model import could be converted into a traceability
315
                  // use model in some future update to EA_ReqPro addin.
316
                  EA_Utils.WriteTag(new_ea_element, "GUID", rq_obj.guid);
317
                  EA_Utils.WriteTag(new_ea_element, "TAG", rq_obj.tag);
318
 
2141 ghuddy 319
                  // Using recursion, scan this objects sub-objects
320
                  foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
321
                  {
322
                     write_ea_database(ea_repository, null, new_ea_element, sub_obj);
323
                  }
324
               }
2143 ghuddy 325
               // else create the requirement element as a child of a parent package
2141 ghuddy 326
               else if (ea_parent_package != null)
327
               {
328
                  // create a representative element in EA
2143 ghuddy 329
                  EA.Element new_ea_element = (EA.Element)ea_parent_package.Elements.AddNew(rq_obj_name, "Requirement");
330
                  rq_obj.ea_element_ID = new_ea_element.ElementID;
331
                  ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Created Element : " + rq_obj_name, new_ea_element.ElementID );
2141 ghuddy 332
 
333
                  // If the ReqPro requirements detailed text is more than what the name already contains (allowing for it
334
                  // to have a stop character that the name may not have) then copy it over, otherwise ignore it. This
335
                  // prevents the same text appearing twice in any generated document made using EA_DocGen.
336
                  if (!rq_obj.text.StartsWith(rq_obj.name) || (rq_obj.text.Length > (rq_obj.name.Length + 1)))
337
                     new_ea_element.Notes = rq_obj.text;
338
 
339
                  new_ea_element.TreePos = rq_obj.treePos;
340
                  new_ea_element.Status  = rq_obj.status;
341
                  new_ea_element.Update();
342
 
2143 ghuddy 343
                  // Write EA tag information exactly as is done for the import for traceability use. This 
344
                  // opens up the possibility that a document model import could be converted into a traceability
345
                  // use model in some future update to EA_ReqPro addin.
346
                  EA_Utils.WriteTag(new_ea_element, "GUID", rq_obj.guid);
347
                  EA_Utils.WriteTag(new_ea_element, "TAG", rq_obj.tag);
348
 
2141 ghuddy 349
                  // Using recursion, scan this objects sub-objects
350
                  foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
351
                  {
352
                     write_ea_database(ea_repository, null, new_ea_element, sub_obj);
353
                  }
354
               }
355
               else
356
               {
2143 ghuddy 357
                  // should never get here - I have never seen it happen so far.
2141 ghuddy 358
                  ea_repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "ERROR,write_ea_database, parent package was null", -1);
359
               }
360
            }
361
         }
362
      }
363
 
364
 
365
 
366
 
367
	}
368
 
369
 
370
}