Subversion Repositories DevTools

Rev

Rev 2153 | Rev 2157 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

using System;
using System.Text;
using System.Globalization;
using System.Collections;
using System.Windows.Forms;
using ReqPro40;

namespace EA_ReqPro
{
        /// <summary>
        /// CopyReqProDatabase is a specialisation of CopyReqProDatabaseToMemory, designed to copy the 
        /// ReqPro database content into an EA database, maintaining the structure of 
        /// and hierarchy of packages and requirements found in the ReqPro database.
        /// </summary>
   public class CopyReqProDatabase : CopyReqProDatabaseToMemory
   {
      private int totalRequirements = 0;

      /// <summary>
      /// Construct the object
      /// </summary>
      /// <param name="ea_repository"></param>
      public CopyReqProDatabase(): base()
      {
         totalRequirements = 0;
      }


      /// <summary>
      /// Method to parse a ReqPro database and copy it into an EA database.
      /// </summary>
      /// <param name="ea_repository"></param>
      /// <returns></returns>
      public override bool prompt_and_parse(ReqProDB_Artifact.MODE mode, out bool cancelled)
      {
         cancelled = false;

         try
         {
            // use the base classes parser to read the ReqPro database content and allow the user to
            // filter it.
            base.structure_only = false;

            string importDateTime = System.DateTime.Now.ToString();

            Main.WriteOutput("EA Requirement import at " + importDateTime, -1 );
            Main.WriteOutput("",-1);

            if (true == base.prompt_and_parse(mode, out cancelled))
            {
               if (Main.mustAbort)
                  return false;

               try
               {
                  // Look for existing requirement elements
                  bool reqElementsFound = false;
                  for(short i=0; i < ea_rootPackage.Elements.Count; i++)
                  {
                     if ( ((EA.Element)ea_rootPackage.Elements.GetAt(i)).Type.StartsWith("Requirement") )
                     {
                        reqElementsFound = true;
                     }
                  }

                  // if there are existing requirement elements or sub-packages...
                  if (reqElementsFound == true
                     || ea_rootPackage.Packages.Count > 0)
                  {
                     DialogResult dlgRes = MessageBoxEx.Show(
                        "ReqPro import package is not empty. Delete existing content\n" + 
                        "first?\n\nNOTE:\n" +
                        "For DocModel imports, normally YES is the desired action here.\n" +
                        "All sub-packages within the ReqPro import package will be\n" +
                        "deleted along with any requirement elements found within the\n" +
                        "package itself, so that the import will begin with a clean sheet.\n" +
                        "If you have done any local modelling under the package, that work\n" + 
                        "will be lost. In future, do all such modelling elsewhere, and leave\n" +
                        "the ReqPro import package alone to be updated solely by the\n" +
                        "EA_ReqPro add-in's DocModel import operation.", 
                        "Confirm", 
                        MessageBoxButtons.YesNoCancel);
                     if (dlgRes == DialogResult.Yes)
                     {
                        // Delete packages and requirement elements
                        short i;
                        for(i=0; i < ea_rootPackage.Packages.Count; i++)
                        {
                           ea_rootPackage.Packages.Delete(i);
                        }
                        for(i=0; i < ea_rootPackage.Elements.Count; i++)
                        {
                           if ( ((EA.Element)ea_rootPackage.Elements.GetAt(i)).Type.StartsWith("Requirement") )
                           {
                              ea_rootPackage.Elements.Delete(i);
                           }
                        }
                        ea_rootPackage.Packages.Refresh();
                        // refresh project browser view
                        Main.EA_Repository.RefreshModelView(ea_rootPackage.PackageID);
                     }
                     else if (dlgRes == DialogResult.Cancel)
                     {
                        cancelled = true;
                        return false;
                     }
                  }
               }
               catch (Exception ex)
               {
                  Main.MessageBoxException(ex, "Exception (CopyReqProDatabase)");
               }   

               Main.EA_Repository.EnsureOutputVisible(Main.GUI_OUTPUT_TAB_NAME);

               if (Main.mustAbort)
                  return false;

               // write the captured info from reqpro, into the ea database, obeying the filter
               // settings the user has specified.
               write_ea_database();

               // Configure the ReqProDB artifact as a document model artifact
               RQ_Artifact.set_doc_model_mode(RQ_Element);

               if (Main.mustAbort)
                  return false;

               writeDelayedMessages();

               Main.WriteOutput("Import Completed", -1);
               MessageBoxEx.Show("Import Completed", "Progress");
               return true;
            }
         }
         catch (Exception ex)
         {
            Main.MessageBoxException(ex, "Exception (parse)");
         }  
    
         return false;
      }
 

   
 

 



      /// <summary>
      /// This method (along with its sibling overloads) perform the copy operation once
      /// the ReqPro database content has been acquired, and the user has submitted their
      /// filtering requirements. This method begins the copy operation, but the real nitty
      /// gritty of it occurs in the other overloaded method.
      /// </summary>
      /// <param name="ea_repository"></param>
      private void write_ea_database()
      {
         Main.WriteOutput("Copying ReqPro Database Content to EA", -1);

         foreach( ReqPro_object sub_obj in rq_root_package.ReqPro_objects )
         {
            if (Main.mustAbort)
               break;

            write_ea_database(ea_rootPackage, null, sub_obj);
         }

         ea_rootPackage.Packages.Refresh();
         // refresh project browser view
         Main.EA_Repository.RefreshModelView(ea_rootPackage.PackageID);

         if (Main.mustAbort)
            return;

         // Setup the internal requirement to requirement connectivity. This is seperate from the browser
         // organisation of elements in EA, but since in ReqPro, that organisation tells part of the story
         // of requirement to requirement connectivity, it is mirrored in the internal connectivity, along
         // with explicit trace relationships setup in ReqPro.
         // The purpose of this internal connectivity is to support relationship matrix tables in documentation
         // generated by EA_DocGen, or to support diagrammatic representations of the requirements in EA,
         // where the connectivity will become apparent through links ajoining the requirement elements in the
         // diagram.
         write_traces(totalRequirements);
      }

      private void write_ea_database(EA.Package ea_parent_package,
                                     EA.Element ea_parent_element,
                                     ReqPro_object rq_obj )
      {
         if (Main.mustAbort)
            return;

         if (rq_obj.isPackage)
         {
            if (rq_obj.filtered == false)
            {
               if (ea_parent_package != null)
               {
                  // create a representative package in EA
                  EA.Package new_ea_package = EA_Utilities.createPackage(ea_parent_package, rq_obj.name, rq_obj.treePos);
                  rq_obj.ea_element_ID = new_ea_package.PackageID;
                  Main.WriteOutput("Created Package : " + rq_obj.name, new_ea_package.PackageID );

                  // Using recursion, scan this objects sub-objects
                  foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
                  {
                     if (Main.mustAbort)
                        break;

                     write_ea_database(new_ea_package, null, sub_obj);  //recurse
                  }
               }
               else
               {
                  // should never get here - I have never seen it happen so far.
                  Main.WriteOutput("ERROR,write_ea_database, parent package was null", -1);
               }
            }
            else if (base.allowPackageStructureFragments)
            {
               // Using recursion, scan this objects sub-objects
               foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
               {
                  if (Main.mustAbort)
                     break;

                  if (sub_obj.isPackage)
                     write_ea_database(ea_parent_package, null, sub_obj);  // recurse
               }
            }
         }
         else if (rq_obj.isRequirement)
         {
            if ( ! (reqTypeIsFiltered(rq_obj) || reqStatusTypeIsFiltered(rq_obj)))
            {
               string rq_obj_name = rq_obj.tag + " " + rq_obj.name;

               EA.Element new_ea_element = null;

               // If needed, create the requirement element as a child of a parent element
               if (ea_parent_element != null)
               {
                  // create a representative element in EA
                  new_ea_element = (EA.Element)ea_parent_element.Elements.AddNew(rq_obj_name, "Requirement");
                  
                  Main.WriteOutput("Created Element : " + rq_obj_name, new_ea_element.ElementID );

                  // In ReqPro, a requirement can be related to another requirement in several ways:
                  // 1. By virtue of its position relative to another in the browser display. That is, 
                  //    if you place a requirement beneath a parent requirement, you are establishing a 
                  //    parent-child relationship.
                  // 2. By virtue of a specific TraceTo/TraceFrom relationship being made via the Traceability menu
                  //    option. 
                  // Interestingly, ReqPro prevents you creating a relationship of one of the above types,
                  // if a relationship of the other type already exists. This implies that the relationship
                  // between a parent and child requirement must be singular and is important regardless
                  // of the manner in which it was created or represented.
                  // The CopyReqProDatabaseToMemory base class will already have taken care of recording
                  // relationships detected from ReqPro made using method 2 above. What we need to do here is
                  // take care of those apparent from the browser based hierarchical organisation (ie. made
                  // in ReqPro using method 1).
                  // All we need to do is grab the parent object (if any) and add the GUID of the child to 
                  // its list of trace-to's. Later on, the write_traces() class method will turn these into
                  // EA based connection objects
                  if (rq_obj.parent != null)
                  {
                     rq_obj.parent.ReqPro_traces.Add(rq_obj.guid);
                  }
               }
               // else create the requirement element as a child of a parent package
               else if (ea_parent_package != null)
               {
                  // create a representative element in EA
                  new_ea_element = (EA.Element)ea_parent_package.Elements.AddNew(rq_obj_name, "Requirement");
                  
                  Main.WriteOutput("Created Element : " + rq_obj_name, new_ea_element.ElementID );
               }
               else
               {
                  // should never get here - I have never seen it happen so far.
                  Main.WriteOutput("ERROR, write_ea_database, parent package was null", -1);
               }

               if (new_ea_element != null)
               {
                  totalRequirements++;

                  rq_obj.ea_element_ID = new_ea_element.ElementID;

                  new_ea_element.TreePos = rq_obj.treePos; // deliberately dont do TreePos in copyReq()

                  copyReq(new_ea_element, rq_obj);

                  new_ea_element.Update();

                  // Using recursion, scan this objects sub-objects
                  foreach( ReqPro_object sub_obj in rq_obj.ReqPro_objects )
                  {
                     if (Main.mustAbort)
                        break;

                     write_ea_database(null, new_ea_element, sub_obj);  // recurse
                  }
               }
            }
         }
      }

      public static void copyReq(EA.Element new_ea_element, ReqPro_object rq_obj)
      {
         // If the ReqPro requirements detailed text is more than what the name already contains (allowing for it
         // to have a stop character that the name may not have) then copy it over, otherwise ignore it. This
         // prevents the same text appearing twice in any generated document made using EA_DocGen.
         if (!rq_obj.text.StartsWith(rq_obj.name) || (rq_obj.text.Length > (rq_obj.name.Length + 1)))
            new_ea_element.Notes = rq_obj.text;

         new_ea_element.Status     = rq_obj.status;
         new_ea_element.Difficulty = rq_obj.difficulty;
         new_ea_element.Priority   = rq_obj.priority;
         new_ea_element.Version    = rq_obj.version;

         // Write EA tag information exactly as is done for the import for traceability use. This 
         // opens up the possibility that a document model import could be converted into a traceability
         // use model in some future update to EA_ReqPro addin.
         EA_TaggedValues.Write(new_ea_element, Constants.TAG_GUID, rq_obj.guid);
         EA_TaggedValues.Write(new_ea_element, Constants.TAG_TAG, rq_obj.tag);

         if (rq_obj.source != null && rq_obj.source.Length > 0)
            EA_TaggedValues.Write(new_ea_element,Constants.TAG_SOURCE, rq_obj.source);
         if (rq_obj.sourceVersion != null && rq_obj.sourceVersion.Length > 0)
            EA_TaggedValues.Write(new_ea_element,Constants.TAG_SOURCE_VERSION, rq_obj.sourceVersion);
         if (rq_obj.sourceSection != null && rq_obj.sourceSection.Length > 0)
            EA_TaggedValues.Write(new_ea_element,Constants.TAG_SOURCE_SECTION, rq_obj.sourceSection);

         if (rq_obj.subsystem != null && rq_obj.subsystem.Length > 0)
            EA_TaggedValues.Write(new_ea_element,Constants.TAG_SUBSYSTEM, rq_obj.subsystem);

         if (rq_obj.stability != null && rq_obj.stability.Length > 0)
            EA_TaggedValues.Write(new_ea_element,Constants.TAG_STABILITY, rq_obj.stability);

         if (0 > new_ea_element.StereotypeEx.IndexOf(rq_obj.type))
         {
            if (new_ea_element.StereotypeEx.Length > 0)
               new_ea_element.StereotypeEx = rq_obj.type + "," + new_ea_element.StereotypeEx;
            else
               new_ea_element.StereotypeEx = rq_obj.type;
         }
         if (new_ea_element.Stereotype.Length == 0)
         {
            new_ea_element.Stereotype = new_ea_element.StereotypeEx.Split(",".ToCharArray())[0];
         }

      }


        }


}