Subversion Repositories DevTools

Rev

Rev 2155 | 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;
2151 ghuddy 2
using System.Text;
3
using System.Globalization;
4
using System.Collections;
5
using System.Windows.Forms;
2141 ghuddy 6
using ReqPro40;
7
 
8
namespace EA_ReqPro
9
{
10
	/// <summary>
2151 ghuddy 11
	/// CopyReqProDatabase is a specialisation of CopyReqProDatabaseToMemory, designed to copy the 
2141 ghuddy 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
   {
2151 ghuddy 17
      private int totalRequirements = 0;
18
 
2141 ghuddy 19
      /// <summary>
20
      /// Construct the object
21
      /// </summary>
22
      /// <param name="ea_repository"></param>
2151 ghuddy 23
      public CopyReqProDatabase(): base()
2141 ghuddy 24
      {
2151 ghuddy 25
         totalRequirements = 0;
2141 ghuddy 26
      }
2151 ghuddy 27
 
28
 
2141 ghuddy 29
      /// <summary>
30
      /// Method to parse a ReqPro database and copy it into an EA database.
31
      /// </summary>
32
      /// <param name="ea_repository"></param>
2151 ghuddy 33
      /// <returns></returns>
2155 ghuddy 34
      public override bool prompt_and_parse(ReqProDB_Artifact.MODE mode, out bool cancelled)
2151 ghuddy 35
      {
2155 ghuddy 36
         cancelled = false;
37
 
2151 ghuddy 38
         try
39
         {
40
            // use the base classes parser to read the ReqPro database content and allow the user to
41
            // filter it.
2155 ghuddy 42
            base.structure_only = false;
43
 
44
            string importDateTime = System.DateTime.Now.ToString();
45
 
46
            Main.WriteOutput("EA Requirement import at " + importDateTime, -1 );
47
            Main.WriteOutput("",-1);
48
 
49
            if (true == base.prompt_and_parse(mode, out cancelled))
2151 ghuddy 50
            {
51
               if (Main.mustAbort)
52
                  return false;
53
 
2145 ghuddy 54
               try
55
               {
56
                  // Look for existing requirement elements
57
                  bool reqElementsFound = false;
2151 ghuddy 58
                  for(short i=0; i < ea_rootPackage.Elements.Count; i++)
59
                  {
60
                     if ( ((EA.Element)ea_rootPackage.Elements.GetAt(i)).Type.StartsWith("Requirement") )
61
                     {
62
                        reqElementsFound = true;
63
                     }
2145 ghuddy 64
                  }
65
 
66
                  // if there are existing requirement elements or sub-packages...
2151 ghuddy 67
                  if (reqElementsFound == true
68
                     || ea_rootPackage.Packages.Count > 0)
69
                  {
2155 ghuddy 70
                     DialogResult dlgRes = MessageBoxEx.Show(
71
                        "ReqPro import package is not empty. Delete existing content\n" + 
72
                        "first?\n\nNOTE:\n" +
73
                        "For DocModel imports, normally YES is the desired action here.\n" +
74
                        "All sub-packages within the ReqPro import package will be\n" +
75
                        "deleted along with any requirement elements found within the\n" +
76
                        "package itself, so that the import will begin with a clean sheet.\n" +
77
                        "If you have done any local modelling under the package, that work\n" + 
78
                        "will be lost. In future, do all such modelling elsewhere, and leave\n" +
79
                        "the ReqPro import package alone to be updated solely by the\n" +
80
                        "EA_ReqPro add-in's DocModel import operation.", 
81
                        "Confirm", 
82
                        MessageBoxButtons.YesNoCancel);
2151 ghuddy 83
                     if (dlgRes == DialogResult.Yes)
84
                     {
85
                        // Delete packages and requirement elements
86
                        short i;
87
                        for(i=0; i < ea_rootPackage.Packages.Count; i++)
88
                        {
89
                           ea_rootPackage.Packages.Delete(i);
90
                        }
91
                        for(i=0; i < ea_rootPackage.Elements.Count; i++)
92
                        {
93
                           if ( ((EA.Element)ea_rootPackage.Elements.GetAt(i)).Type.StartsWith("Requirement") )
94
                           {
95
                              ea_rootPackage.Elements.Delete(i);
96
                           }
97
                        }
98
                        ea_rootPackage.Packages.Refresh();
2145 ghuddy 99
                        // refresh project browser view
2151 ghuddy 100
                        Main.EA_Repository.RefreshModelView(ea_rootPackage.PackageID);
101
                     }
2155 ghuddy 102
                     else if (dlgRes == DialogResult.Cancel)
103
                     {
104
                        cancelled = true;
105
                        return false;
106
                     }
2151 ghuddy 107
                  }
2145 ghuddy 108
               }
2151 ghuddy 109
               catch (Exception ex)
110
               {
2153 ghuddy 111
                  Main.MessageBoxException(ex, "Exception (CopyReqProDatabase)");
2151 ghuddy 112
               }   
113
 
114
               Main.EA_Repository.EnsureOutputVisible(Main.GUI_OUTPUT_TAB_NAME);
115
 
116
               if (Main.mustAbort)
117
                  return false;
118
 
119
               // write the captured info from reqpro, into the ea database, obeying the filter
120
               // settings the user has specified.
121
               write_ea_database();
122
 
123
               // Configure the ReqProDB artifact as a document model artifact
124
               RQ_Artifact.set_doc_model_mode(RQ_Element);
125
 
126
               if (Main.mustAbort)
127
                  return false;
128
 
129
               writeDelayedMessages();
130
 
2155 ghuddy 131
               Main.WriteOutput("Import Completed", -1);
2153 ghuddy 132
               MessageBoxEx.Show("Import Completed", "Progress");
2151 ghuddy 133
               return true;
134
            }
135
         }
136
         catch (Exception ex)
137
         {
2153 ghuddy 138
            Main.MessageBoxException(ex, "Exception (parse)");
2155 ghuddy 139
         }  
140
 
2151 ghuddy 141
         return false;
142
      }
2149 ghuddy 143
 
2141 ghuddy 144
 
2151 ghuddy 145
 
2149 ghuddy 146
 
2141 ghuddy 147
 
2151 ghuddy 148
 
2143 ghuddy 149
 
150
 
2151 ghuddy 151
 
2143 ghuddy 152
      /// <summary>
2141 ghuddy 153
      /// This method (along with its sibling overloads) perform the copy operation once
154
      /// the ReqPro database content has been acquired, and the user has submitted their
155
      /// filtering requirements. This method begins the copy operation, but the real nitty
156
      /// gritty of it occurs in the other overloaded method.
157
      /// </summary>
158
      /// <param name="ea_repository"></param>
2151 ghuddy 159
      private void write_ea_database()
2141 ghuddy 160
      {
2155 ghuddy 161
         Main.WriteOutput("Copying ReqPro Database Content to EA", -1);
2141 ghuddy 162
 
163
         foreach( ReqPro_object sub_obj in rq_root_package.ReqPro_objects )
164
         {
2151 ghuddy 165
            if (Main.mustAbort)
166
               break;
167
 
168
            write_ea_database(ea_rootPackage, null, sub_obj);
2141 ghuddy 169
         }
170
 
2151 ghuddy 171
         ea_rootPackage.Packages.Refresh();
2141 ghuddy 172
         // refresh project browser view
2151 ghuddy 173
         Main.EA_Repository.RefreshModelView(ea_rootPackage.PackageID);
2143 ghuddy 174
 
2151 ghuddy 175
         if (Main.mustAbort)
176
            return;
177
 
2143 ghuddy 178
         // Setup the internal requirement to requirement connectivity. This is seperate from the browser
179
         // organisation of elements in EA, but since in ReqPro, that organisation tells part of the story
180
         // of requirement to requirement connectivity, it is mirrored in the internal connectivity, along
181
         // with explicit trace relationships setup in ReqPro.
182
         // The purpose of this internal connectivity is to support relationship matrix tables in documentation
183
         // generated by EA_DocGen, or to support diagrammatic representations of the requirements in EA,
184
         // where the connectivity will become apparent through links ajoining the requirement elements in the
185
         // diagram.
2151 ghuddy 186
         write_traces(totalRequirements);
2141 ghuddy 187
      }
188
 
2151 ghuddy 189
      private void write_ea_database(EA.Package ea_parent_package,
2141 ghuddy 190
                                     EA.Element ea_parent_element,
191
                                     ReqPro_object rq_obj )
192
      {
2151 ghuddy 193
         if (Main.mustAbort)
194
            return;
195
 
2141 ghuddy 196
         if (rq_obj.isPackage)
197
         {
198
            if (rq_obj.filtered == false)
199
            {
200
               if (ea_parent_package != null)
201
               {
202
                  // create a representative package in EA
2153 ghuddy 203
                  EA.Package new_ea_package = EA_Utilities.createPackage(ea_parent_package, rq_obj.name, rq_obj.treePos);
2143 ghuddy 204
                  rq_obj.ea_element_ID = new_ea_package.PackageID;
2155 ghuddy 205
                  Main.WriteOutput("Created Package : " + rq_obj.name, new_ea_package.PackageID );
2141 ghuddy 206
 
207
                  // Using recursion, scan this objects sub-objects
208
                  foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
209
                  {
2151 ghuddy 210
                     if (Main.mustAbort)
211
                        break;
212
 
2153 ghuddy 213
                     write_ea_database(new_ea_package, null, sub_obj);  //recurse
2141 ghuddy 214
                  }
215
               }
216
               else
217
               {
2143 ghuddy 218
                  // should never get here - I have never seen it happen so far.
2155 ghuddy 219
                  Main.WriteOutput("ERROR,write_ea_database, parent package was null", -1);
2141 ghuddy 220
               }
221
            }
222
            else if (base.allowPackageStructureFragments)
223
            {
224
               // Using recursion, scan this objects sub-objects
225
               foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
226
               {
2151 ghuddy 227
                  if (Main.mustAbort)
228
                     break;
229
 
2141 ghuddy 230
                  if (sub_obj.isPackage)
2153 ghuddy 231
                     write_ea_database(ea_parent_package, null, sub_obj);  // recurse
2141 ghuddy 232
               }
233
            }
234
         }
235
         else if (rq_obj.isRequirement)
236
         {
237
            if ( ! (reqTypeIsFiltered(rq_obj) || reqStatusTypeIsFiltered(rq_obj)))
238
            {
2143 ghuddy 239
               string rq_obj_name = rq_obj.tag + " " + rq_obj.name;
240
 
2155 ghuddy 241
               EA.Element new_ea_element = null;
242
 
2143 ghuddy 243
               // If needed, create the requirement element as a child of a parent element
2141 ghuddy 244
               if (ea_parent_element != null)
245
               {
246
                  // create a representative element in EA
2155 ghuddy 247
                  new_ea_element = (EA.Element)ea_parent_element.Elements.AddNew(rq_obj_name, "Requirement");
248
 
249
                  Main.WriteOutput("Created Element : " + rq_obj_name, new_ea_element.ElementID );
2141 ghuddy 250
 
2143 ghuddy 251
                  // In ReqPro, a requirement can be related to another requirement in several ways:
252
                  // 1. By virtue of its position relative to another in the browser display. That is, 
253
                  //    if you place a requirement beneath a parent requirement, you are establishing a 
254
                  //    parent-child relationship.
2155 ghuddy 255
                  // 2. By virtue of a specific TraceTo/TraceFrom relationship being made via the Traceability menu
2143 ghuddy 256
                  //    option. 
257
                  // Interestingly, ReqPro prevents you creating a relationship of one of the above types,
258
                  // if a relationship of the other type already exists. This implies that the relationship
259
                  // between a parent and child requirement must be singular and is important regardless
260
                  // of the manner in which it was created or represented.
261
                  // The CopyReqProDatabaseToMemory base class will already have taken care of recording
262
                  // relationships detected from ReqPro made using method 2 above. What we need to do here is
263
                  // take care of those apparent from the browser based hierarchical organisation (ie. made
264
                  // in ReqPro using method 1).
265
                  // All we need to do is grab the parent object (if any) and add the GUID of the child to 
266
                  // its list of trace-to's. Later on, the write_traces() class method will turn these into
2155 ghuddy 267
                  // EA based connection objects
2143 ghuddy 268
                  if (rq_obj.parent != null)
269
                  {
270
                     rq_obj.parent.ReqPro_traces.Add(rq_obj.guid);
271
                  }
2141 ghuddy 272
               }
2143 ghuddy 273
               // else create the requirement element as a child of a parent package
2141 ghuddy 274
               else if (ea_parent_package != null)
275
               {
2155 ghuddy 276
                  // create a representative element in EA
277
                  new_ea_element = (EA.Element)ea_parent_package.Elements.AddNew(rq_obj_name, "Requirement");
278
 
279
                  Main.WriteOutput("Created Element : " + rq_obj_name, new_ea_element.ElementID );
280
               }
281
               else
282
               {
283
                  // should never get here - I have never seen it happen so far.
284
                  Main.WriteOutput("ERROR, write_ea_database, parent package was null", -1);
285
               }
286
 
287
               if (new_ea_element != null)
288
               {
2151 ghuddy 289
                  totalRequirements++;
290
 
2157 ghuddy 291
                  // tie the new EA element back to the facsimile of the req pro requirement that led to its creation.
292
                  // This will support the writing of trace info later on.
2143 ghuddy 293
                  rq_obj.ea_element_ID = new_ea_element.ElementID;
2141 ghuddy 294
 
2157 ghuddy 295
                  // NOTE: deliberately dont do TreePos in copyReq() because copyReq() may be called in other
296
                  // contexts where the caller does not want any fiddling with the tree position in the EA browser.
297
                  new_ea_element.TreePos = rq_obj.treePos; 
2141 ghuddy 298
 
2155 ghuddy 299
                  copyReq(new_ea_element, rq_obj);
300
 
2141 ghuddy 301
                  new_ea_element.Update();
302
 
303
                  // Using recursion, scan this objects sub-objects
304
                  foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
305
                  {
2151 ghuddy 306
                     if (Main.mustAbort)
307
                        break;
308
 
2153 ghuddy 309
                     write_ea_database(null, new_ea_element, sub_obj);  // recurse
2141 ghuddy 310
                  }
311
               }
312
            }
313
         }
314
      }
315
 
2157 ghuddy 316
      /// <summary>
317
      /// Copy the details of the reqpro based requirement facsimile, into an EA element
318
      /// </summary>
319
      /// <param name="new_ea_element"></param>
320
      /// <param name="rq_obj"></param>
2155 ghuddy 321
      public static void copyReq(EA.Element new_ea_element, ReqPro_object rq_obj)
322
      {
323
         // If the ReqPro requirements detailed text is more than what the name already contains (allowing for it
324
         // to have a stop character that the name may not have) then copy it over, otherwise ignore it. This
325
         // prevents the same text appearing twice in any generated document made using EA_DocGen.
326
         if (!rq_obj.text.StartsWith(rq_obj.name) || (rq_obj.text.Length > (rq_obj.name.Length + 1)))
327
            new_ea_element.Notes = rq_obj.text;
2141 ghuddy 328
 
2155 ghuddy 329
         new_ea_element.Status     = rq_obj.status;
330
         new_ea_element.Difficulty = rq_obj.difficulty;
331
         new_ea_element.Priority   = rq_obj.priority;
332
         new_ea_element.Version    = rq_obj.version;
2141 ghuddy 333
 
2155 ghuddy 334
         // Write EA tag information exactly as is done for the import for traceability use. This 
335
         // opens up the possibility that a document model import could be converted into a traceability
336
         // use model in some future update to EA_ReqPro addin.
337
         EA_TaggedValues.Write(new_ea_element, Constants.TAG_GUID, rq_obj.guid);
338
         EA_TaggedValues.Write(new_ea_element, Constants.TAG_TAG, rq_obj.tag);
2141 ghuddy 339
 
2155 ghuddy 340
         if (rq_obj.source != null && rq_obj.source.Length > 0)
341
            EA_TaggedValues.Write(new_ea_element,Constants.TAG_SOURCE, rq_obj.source);
342
         if (rq_obj.sourceVersion != null && rq_obj.sourceVersion.Length > 0)
343
            EA_TaggedValues.Write(new_ea_element,Constants.TAG_SOURCE_VERSION, rq_obj.sourceVersion);
344
         if (rq_obj.sourceSection != null && rq_obj.sourceSection.Length > 0)
345
            EA_TaggedValues.Write(new_ea_element,Constants.TAG_SOURCE_SECTION, rq_obj.sourceSection);
346
 
347
         if (rq_obj.subsystem != null && rq_obj.subsystem.Length > 0)
348
            EA_TaggedValues.Write(new_ea_element,Constants.TAG_SUBSYSTEM, rq_obj.subsystem);
349
 
350
         if (rq_obj.stability != null && rq_obj.stability.Length > 0)
351
            EA_TaggedValues.Write(new_ea_element,Constants.TAG_STABILITY, rq_obj.stability);
352
 
2157 ghuddy 353
         // for requirement type attribute, enforce just a single stereotype in the EA element, even though
354
         // StereotypeEx can be a comma seperated list.
355
         new_ea_element.StereotypeEx = rq_obj.type;
356
         new_ea_element.Stereotype = rq_obj.type;
2155 ghuddy 357
 
358
      }
359
 
360
 
2141 ghuddy 361
	}
362
 
363
 
364
}