Subversion Repositories DevTools

Rev

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

//-----------------------------------------------------------------------
// This is open source licensed under GPL
//
//
using System;
using System.Text;
using System.Globalization;
using System.Collections;
using System.Windows.Forms;
using ReqPro40;

namespace EA_ReqPro
{
   public class Main
   {
      bool SyncMode = false;

      public String EA_Connect(EA.Repository Repository) 
      {
         return "a string";
      }


      public readonly static String GUI_OUTPUT_TAB_NAME = "EA_ReqPro";

      ArrayList orphanedRequirements = new ArrayList();

 
      /// <summary>
      /// Called when EA initialised. Creates an output tab for the add in.
      /// </summary>
      /// <param name="repository"></param>
      public void EA_OnPostInitialized(EA.Repository repository)
      {
         repository.CreateOutputTab(GUI_OUTPUT_TAB_NAME);
         repository.EnsureOutputVisible(GUI_OUTPUT_TAB_NAME);
      }


      /// <summary>
      /// Event called when user clicks on an entry in the output 
      /// window. If an element has been associated with the message, it will
      /// be automatically selected in the project browser.
      /// </summary>
      /// <param name="repository"></param>
      /// <param name="outputTabNea"></param>
      /// <param name="lineText"></param>
      /// <param name="lineIdentifier"></param>
      public void EA_OnOutputItemClicked( EA.Repository repository, 
                                          String outputTabName, 
                                          String lineText,
                                          Int32 identifier)
      {
         if ((outputTabName == GUI_OUTPUT_TAB_NAME) && (identifier > 0))
         {
            EA.Element element = repository.GetElementByID(identifier);
            repository.ShowInProjectView(element);
         }                               
      }


      public object EA_GetMenuItems(EA.Repository repository, string location, string menu) 
      {
         switch( menu )
         {
            case "":
               return "-&EA_ReqPro";

            case "-&Orphaned Elements":
               string[] ar1 = { "&Display In Output Tab"
                                //"&Move to Orphaned Package"
                              };
               return ar1;

            case "-&EA_ReqPro":
               string[] ar = { 
                                "&Associate Package To ReqPro Database",
                                "&Export To ReqPro",
                                "&Import From ReqPro",
                                "&Sync With ReqPro",
                                //"&Display EA Element In Output Tab",
                                "&List ReqPro Requirement Info",
                                "-&Orphaned Elements"

                             };
               return ar;
         }
         return "";
      }


      bool IsProjectOpen(EA.Repository Repository)
      {
         try
         {
            EA.Collection collection = Repository.Models;
            return true;
         }
         catch
         {
            return false;
         }
      }


      public void EA_GetMenuState(EA.Repository repository, string location, string menuName, string itemName, ref bool isEnabled, ref bool isChecked)
      {
         object o;
         EA.ObjectType type;

         isChecked = false;

         if (IsProjectOpen(repository))
         {
            switch (itemName)
            {
               case "&Display EA Element In Output Tab":
                  isEnabled = repository.GetTreeSelectedItemType() == EA.ObjectType.otElement;
                  break;

               case "&Associate Package To ReqPro Database":
                  type = repository.GetTreeSelectedItem(out o);
                  if (type == EA.ObjectType.otPackage)
                  {
                     isEnabled = true;
                  }
                  else
                  {
                     isEnabled = false;
                  }
                  break;

               case "&Export To ReqPro":
               case "&Import From ReqPro":
               case "&Sync With ReqPro":
               case "&List ReqPro Requirement Info":
                  type = repository.GetTreeSelectedItem(out o);
                  if ( (type == EA.ObjectType.otElement) && (((EA.Element)o).Stereotype == "ReqProDB"))
                  {
                     isEnabled = true;
                  }
                  else
                  {
                     isEnabled = false;
                  }
                  break;

               case "-&Orphaned Elements":
               case "&Display In Output Tab":
               case "&Move to Orphaned Package":
                  if (orphanedRequirements.Count > 0)
                  {
                     isEnabled = true;
                  }
                  else
                  {
                     isEnabled = false;
                  }
                  break;

            }
         }
         else
         {
            isEnabled = false;
         }
      }


      public void EA_MenuClick(EA.Repository repository, string location, string menu, string itemName)
      {
         switch( itemName )
         {
            case "&Associate Package To ReqPro Database":
               AssociatePackageToReqProDatabase(repository);
               break;

            case "&Export To ReqPro":
               SyncMode = false;
               ExportToReqPro(repository);
               break;

            case "&Import From ReqPro":
               SyncMode = false;
               ImportFromReqPro(repository);
               break;

            case "&Sync With ReqPro":
               SyncMode = true;
               ImportFromReqPro(repository);
               break;

            case "&List ReqPro Requirement Info":
               ListReqProRequirementInfo(repository);
               break;

            case "&Display In Output Tab":
               DisplayOrphanedRequirements(repository);
               break;

            case "&Move to Orphaned Package":
               break;

            case "&Display EA Element In Output Tab":
               DumpEAElement(repository);
               break;
         }
      }

      private void ListReqProRequirementInfo(EA.Repository repository)
      {
         ReqPro40.Project rq_project = null;
         try
         {
            EA.Element rq_artifact = (EA.Element)repository.GetTreeSelectedObject();
            if (rq_artifact != null)
            {
               // Create a ReqPro connection object
               RQConnection rq_connection = new RQConnection(repository, rq_artifact);
               if (rq_connection != null)
               {
                  // open the ReqPro data base
                  rq_project = rq_connection.OpenRqDB();
                  if (rq_project != null)
                  {
                     repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "ReqPro Requirement Info", -1);

                     // Get ReqPro requirements collection
                     ReqPro40.Requirements rq_req_collection = get_rq_req_collection(rq_project);

                     int rq_collection_count = rq_req_collection.Count;

                     // loop through all of the ReqPro requirements
                     rq_req_collection.MoveFirst();

                     string rq_req_name = "";

                     for (int i = 0; i<rq_collection_count; i++)
                     {
                        try
                        {
                           ReqPro40.Requirement rq_req = rq_req_collection.GetCurrentRequirement();
                           if (rq_req != null)
                           {
                              rq_req_name = rq_req.Name;

                              //string rq_datetime = rq_req.VersionDateTime;
                              //DateTime rq_dt = new DateTime();
                              //rq_dt = DateTime.Parse(rq_datetime, cultureInfo, DateTimeStyles.NoCurrentDateDefault);
                              //rq_dt = rq_dt.ToUniversalTime();
                              //rq_req.AttrValues["Difficulty", ReqPro40.enumAttrValueLookups.eAttrValueLookup_Label].Text;
                              //rq_req.AttrValues["Priority", ReqPro40.enumAttrValueLookups.eAttrValueLookup_Label].Text;
                              //rq_req.AttrValues["Status", ReqPro40.enumAttrValueLookups.eAttrValueLookup_Label].Text;
                              //rq_req.VersionNumber;

                              repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, 
                                   "ReqPro : " 
                                 + rq_req.get_Tag(ReqPro40.enumTagFormat.eTagFormat_Tag)  
                                 + ", "
                                 + rq_req_name
                                 + ", "
                                 + rq_req.GUID, -1 );
                           }
                        }
                        catch (Exception ex)
                        {
                           repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Exception (ImportFromReqPro), " + ex.Message + ", " + rq_req_name, -1);

                           // Try an re-establish connection and requirement collection references
                           rq_project = rq_connection.ReOpenRqDB();
                           rq_req_collection = get_rq_req_collection(rq_project);
                           rq_collection_count = rq_req_collection.Count;
                           rq_req_collection.MoveFirst();
                           for (int i2 = 0; i2<i; i2++)
                           {
                              rq_req_collection.MoveNext();
                           }
                           i--;
                           continue;
                        }

                        rq_req_collection.MoveNext();
                     }


                  }
                  else
                  {
                     MessageBox.Show("ERROR: Cannot establish connection to ReqPro database.\n\n" +
                        "Check the tagged values in the artifact are correct.\n" +
                        "Check the database still exists or is not locked by\n" +
                        "another user, or has not been password protected." );
                  }            
               }            
            }
         }
         catch (Exception ex)
         {
            MessageBox.Show(ex.Message, "Error (ImportFromReqPro)", MessageBoxButtons.OK);
            if (rq_project != null)
               rq_project.CloseProject();
         }
      }


      private void DumpEAElement(EA.Repository repository)
      {
         EA.Element ea_ele = (EA.Element)repository.GetTreeSelectedObject();

         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "EA Element : " + ea_ele.Name, ea_ele.ElementID);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,               "Author : " + ea_ele.Author, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,          "ClassfierID : " + ea_ele.ClassfierID.ToString(), -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,       "ClassifierName : " + ea_ele.ClassifierName, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,       "ClassifierType : " + ea_ele.ClassifierType, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,           "Complexity : " + ea_ele.Complexity, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,           "Difficulty : " + ea_ele.Difficulty, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,          "ElementGUID : " + ea_ele.ElementGUID, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,            "ElementID : " + ea_ele.ElementID.ToString(), ea_ele.ElementID);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,           "EventFlags : " + ea_ele.EventFlags, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,      "ExtensionPoints : " + ea_ele.ExtensionPoints, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,              "Genfile : " + ea_ele.Genfile, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,             "Genlinks : " + ea_ele.Genlinks, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,              "Gentype : " + ea_ele.Gentype, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,         "GetLastError : " + ea_ele.GetLastError(), -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,    "GetLinkedDocument : " + ea_ele.GetLinkedDocument(), -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,    "GetStereotypeList : " + ea_ele.GetStereotypeList(), -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,             "MetaType : " + ea_ele.MetaType, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,         "Multiplicity : " + ea_ele.Multiplicity, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,                "Notes : " + ea_ele.Notes, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,            "PackageID : " + ea_ele.PackageID.ToString(), ea_ele.PackageID);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,             "ParentID : " + ea_ele.ParentID.ToString(), ea_ele.ParentID);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,          "Persistence : " + ea_ele.Persistence, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,                "Phase : " + ea_ele.Phase, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,             "Priority : " + ea_ele.Priority, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,         "PropertyType : " + ea_ele.PropertyType.ToString(), -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,             "RunState : " + ea_ele.RunState, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,               "Status : " + ea_ele.Status, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,           "Stereotype : " + ea_ele.Stereotype, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,         "StereotypeEx : " + ea_ele.StereotypeEx, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,              "StyleEx : " + ea_ele.StyleEx, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,              "Subtype : " + ea_ele.Subtype.ToString(), -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,           "Tablespace : " + ea_ele.Tablespace, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,                  "Tag : " + ea_ele.Tag, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,              "TreePos : " + ea_ele.TreePos.ToString(), -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,                 "Type : " + ea_ele.Type, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,              "Version : " + ea_ele.Version, -1);
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,           "Visibility : " + ea_ele.Visibility, -1);
      }

      private void DisplayOrphanedRequirements(EA.Repository repository)
      {
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "EA Orphaned Requirements", -1 );
         foreach (EA.Element theElement in orphanedRequirements)
         {
            repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, theElement.Name, theElement.ElementID );
         }
      }

      private void ImportFromReqPro(EA.Repository repository)
      {
         ReqPro40.Project rq_project = null;
         try
         {
            EA.Element rq_artifact = (EA.Element)repository.GetTreeSelectedObject();
            if (rq_artifact != null)
            {
               // Create a ReqPro connection object
               RQConnection rq_connection = new RQConnection(repository, rq_artifact);
               if (rq_connection != null)
               {
                  // open the ReqPro data base
                  rq_project = rq_connection.OpenRqDB();
                  if (rq_project != null)
                  {
                     orphanedRequirements.Clear();

                     ImportFromReqPro(repository, rq_connection, rq_project, rq_artifact);
                  }
                  else
                  {
                     MessageBox.Show("ERROR: Cannot establish connection to ReqPro database.\n\n" +
                        "Check the tagged values in the artifact are correct.\n" +
                        "Check the database still exists or is not locked by\n" +
                        "another user, or has not been password protected." );
                  }            
               }            
            }
         }
         catch (Exception ex)
         {
            MessageBox.Show(ex.Message, "Error (ImportFromReqPro)", MessageBoxButtons.OK);
            if (rq_project != null)
               rq_project.CloseProject();
         }
      }

      private ReqPro40.Requirements get_rq_req_collection(ReqPro40.Project rq_project)
      {
         return rq_project.GetRequirements(0, 
            enumRequirementsLookups.eReqsLookup_All, 
            enumRequirementsWeights.eReqWeight_Heavy, 
            enumRequirementFlags.eReqFlag_RetainHierarchy, 
            4095, 200);
      }

      /// <summary>
      /// IMPORT requirements from a ReqPro database
      /// </summary>
      /// <param name="repository"></param>
      private void ImportFromReqPro(EA.Repository repository, RQConnection rq_connection, ReqPro40.Project rq_project, EA.Element rq_artifact)
      {
         try
         {
            bool exportNeeded = false;

            IFormatProvider cultureInfo = new CultureInfo("en-US", true);

            string importDateTime = System.TimeZone.CurrentTimeZone.ToUniversalTime( System.DateTime.Now ).ToString();

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

            EA_Utilities EA_Utils = new EA_Utilities(repository);
          
            // Update the ReqProDB stereotypes element with all the EA requirements in the package
            UpdatePackageToReqProDatabaseAssociation(repository, rq_artifact);

            // Get a list of EA requirements and their associated ReqPro GUIDs
            ArrayList ea_reqs = new ArrayList();
            ArrayList ea_GUIDs = new ArrayList();
            ArrayList ea_req_matched = new ArrayList();
            foreach (EA.Connector connector in rq_artifact.Connectors)
            {
               EA.Element ea_req = repository.GetElementByID( connector.SupplierID );
               if (ea_req != null)
               {
                  ea_reqs.Add(ea_req);
                  string GUID = EA_Utils.ReadTag(ea_req, "GUID");
                  ea_GUIDs.Add(GUID);
                  ea_req_matched.Add(false);
               }
            }

            // Obtain the EA parent package so that we can create under it an import package
            // if need be.
            EA.Package parentPackage = repository.GetPackageByID( rq_artifact.PackageID );
            EA.Package importPackage = null;

            // Get ReqPro requirements collection
            ReqPro40.Requirements rq_req_collection = get_rq_req_collection(rq_project);

            int rq_collection_count = rq_req_collection.Count;

            // loop through all of the ReqPro requirements
            rq_req_collection.MoveFirst();

            string rq_req_name = "";

            for (int i = 0; i<rq_collection_count; i++)
            {
               try
               {
                  ReqPro40.Requirement rq_req = rq_req_collection.GetCurrentRequirement();
                  if (rq_req != null)
                  {
                     rq_req_name = rq_req.Name;

                     // Find which EA requirement element refers to the current ReqPro GUID
                     int i_ea_req;
                     i_ea_req = ea_GUIDs.IndexOf( rq_req.GUID );

                     // If EA element was found
                     if (0 <= i_ea_req)
                     {
                        ea_req_matched[i_ea_req] = true;

                        EA.Element ea_req = ((EA.Element)ea_reqs[i_ea_req]);

                        string rq_datetime = rq_req.VersionDateTime;
                        DateTime rq_dt = new DateTime();
                        rq_dt = DateTime.Parse(rq_datetime, cultureInfo, DateTimeStyles.NoCurrentDateDefault);
                        rq_dt = rq_dt.ToUniversalTime();
                        //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, rq_req.Name + " DATETIME: " + rq_dt.ToString(), -1);

                        DateTime ea_dt = ea_req.Modified.ToUniversalTime();
                        //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, ea_req.Name + " DATETIME: " + ea_dt.ToString(), -1);

                        if (SyncMode && (0 <= ea_dt.CompareTo(rq_dt)))
                        {
                           exportNeeded = true;
                           //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "ReqPro Requirement counterpart in EA was NOT updated (was newer): " + ea_req.Name, ea_req.ElementID );
                        }
                        else
                        {
                           // This ReqPro requirement already has a counterpart in EA, so we must simply
                           // update the counterpart.
                           ea_req.Name = rq_req.Name;
                           ea_req.Notes = rq_req.Text;

                           ea_req.Difficulty = rq_req.AttrValues["Difficulty", ReqPro40.enumAttrValueLookups.eAttrValueLookup_Label].Text;
                           ea_req.Priority   = rq_req.AttrValues["Priority", ReqPro40.enumAttrValueLookups.eAttrValueLookup_Label].Text;
                           ea_req.Status     = rq_req.AttrValues["Status", ReqPro40.enumAttrValueLookups.eAttrValueLookup_Label].Text;
                           ea_req.Version    = rq_req.VersionNumber;

                           ea_req.Update();
                           repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "ReqPro Requirement counterpart in EA was updated : " + ea_req.Name, ea_req.ElementID );
                        }
                     }
                     else
                     {
                        // This ReqPro requirement does not have a counterpart in EA, so we must create
                        // a new one.

                        // Create the import package if not already done
                        if (importPackage == null)
                        {
                           importPackage = (EA.Package )parentPackage.Packages.AddNew( "import " + importDateTime, "Package");
                           importPackage.Update();
                        }

                        // create the new EA requirement in the import package
                        EA.Element ea_req = (EA.Element)importPackage.Elements.AddNew( rq_req.Name, "Requirement");
                        ea_req.Notes = rq_req.Text;

                        ea_req.Difficulty = rq_req.AttrValues["Difficulty", ReqPro40.enumAttrValueLookups.eAttrValueLookup_Label].Text;
                        ea_req.Priority   = rq_req.AttrValues["Priority", ReqPro40.enumAttrValueLookups.eAttrValueLookup_Label].Text;
                        ea_req.Status     = rq_req.AttrValues["Status", ReqPro40.enumAttrValueLookups.eAttrValueLookup_Label].Text;
                        ea_req.Version    = rq_req.VersionNumber;

                        EA_Utils.WriteTag(ea_req, "GUID", rq_req.GUID);
                        EA_Utils.WriteTag(ea_req, "TAG", rq_req.get_Tag(ReqPro40.enumTagFormat.eTagFormat_Tag));
                        ea_req.Update();

                        // Add the new requirement to the rq_artifact
                        add_connection(repository, rq_artifact, ea_req);

                        repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "ReqPro Requirement counterpart in EA was created : " + ea_req.Name, ea_req.ElementID );
                     }                  
                  }
               }
               catch (Exception ex)
               {
                  repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Exception (ImportFromReqPro), " + ex.Message + ", " + rq_req_name, -1);

                  // Try an re-establish connection and requirement collection references
                  rq_project = rq_connection.ReOpenRqDB();
                  rq_req_collection = get_rq_req_collection(rq_project);
                  rq_collection_count = rq_req_collection.Count;
                  rq_req_collection.MoveFirst();
                  for (int i2 = 0; i2<i; i2++)
                  {
                     rq_req_collection.MoveNext();
                  }
                  i--;
                  continue;
               }

               rq_req_collection.MoveNext();
            }


            // Now check for orphaned EA requirements
            for (int i = 0; i < ea_GUIDs.Count; i++)
            {
               string rq_GUID = (string)ea_GUIDs[i];
               if (rq_GUID != "")
               {
                  if ((bool)ea_req_matched[i] == false)
                  {
                     EA.Element ea_req = (EA.Element)ea_reqs[i];
                     orphanedRequirements.Add( ea_req );
                     repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "EA Requirement Orphaned (counterpart in ReqPro was missing) : " + ea_req.Name, ea_req.ElementID );
                  }
               }
            }

            if (exportNeeded && SyncMode)
            {
               ExportToReqPro(repository, rq_connection, rq_project, rq_artifact);
            }
            else if (exportNeeded)
            {
               MessageBox.Show("Some EA requirements were modified later than their ReqPro counterparts.\n" +
                               "You may need to perform an export following this import");
            }

            rq_project.CloseProject();  

            repository.RefreshModelView(parentPackage.PackageID);

            if (importPackage == null)
            {
               if (orphanedRequirements.Count == 0)
                  MessageBox.Show("Import From ReqPro Complete.\n\n" + 
                     "No new requirements were found.");
               else
                  MessageBox.Show("Import From ReqPro Complete.\n\n" + 
                     "No new requirements were found.\n\n" +
                     "Some EA requirements were orphaned.");
            }
            else
            {
               if (orphanedRequirements.Count == 0)
                  MessageBox.Show("Import From ReqPro Complete.\n\n" +  
                     "New requirements were found\n" +
                     "and added under package \"" + importPackage.Name + "\"" );
               else
                  MessageBox.Show("Import From ReqPro Complete.\n\n" +  
                     "New requirements were found\n" +
                     "and added under package \"" + importPackage.Name + "\"\n\n" +
                     "Some EA requirements were orphaned.");
            }
         }
         catch (Exception ex)
         {
            MessageBox.Show(ex.Message, "Error (ImportFromReqPro)", MessageBoxButtons.OK);
            if (rq_project != null)
               rq_project.CloseProject();
         }
      }


      private void add_connection(EA.Repository repository, EA.Element rq_artifact, EA.Element ea_req)
      {
         // Add the new requirement to the rq_artifact
         EA.Connector c = (EA.Connector)rq_artifact.Connectors.AddNew("", "Dependency");
         c.SupplierID = ea_req.ElementID;
         c.Stereotype = "trace";
         c.Direction = "Destination -> Source";
         if (false == c.Update())
         {
            repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "New Connector Error : " + c.GetLastError(), ea_req.ElementID );
         }
      }



      private void ExportAttr(EA.Repository repository, ReqPro40.Requirement rq_req, string EA_AttrLabel, string EA_AttrValue)
      {
         try
         {
            //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,"EA_AttrLabel = " + EA_AttrLabel, -1);
            //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,"EA_AttrValue = " + EA_AttrValue, -1);
            foreach(ReqPro40.AttrValue rq_AttrValue in rq_req.AttrValues)
            {
               //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,"  rq_AttrValue.Text = " + rq_AttrValue.Text,-1);
               //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,"  rq_AttrValue.Label = " + rq_AttrValue.Label, -1);

               if (rq_AttrValue.Label.StartsWith(EA_AttrLabel))
               {
                  switch (rq_AttrValue.DataType)
                  {
                     case ReqPro40.enumAttrDataTypes.eAttrDataTypes_Text:
                        rq_AttrValue.Text = EA_AttrValue;
                        break;

                     case ReqPro40.enumAttrDataTypes.eAttrDataTypes_List:
                     case ReqPro40.enumAttrDataTypes.eAttrDataTypes_MultiSelect:

                        foreach( ReqPro40.ListItemValue rq_ListItemValue in rq_AttrValue.ListItemValues)
                        {
                           //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "    rq_ListItemValue.Text = " + rq_ListItemValue.Text,-1);
                           //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,"    BEFORE: " + rq_ListItemValue.Selected.ToString(),-1);

                           if (rq_ListItemValue.Text == EA_AttrValue)
                           {
                              rq_ListItemValue.Selected = true;
                           }
                           else
                           {
                              rq_ListItemValue.Selected = false;
                           }
                           //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,"    AFTER: " + rq_ListItemValue.Selected.ToString(),-1);
                           
                        }
                        break;
                  }
                  break;
               }
            }
         }
         catch
         {

            // do nothing
         }
      }


      private void ExportToReqPro(EA.Repository repository)
      {
         ReqPro40.Project rq_project = null;

         try
         {
            EA.Element rq_artifact = (EA.Element)repository.GetTreeSelectedObject();
            if (rq_artifact != null)
            {
               // Create a ReqPro connection object
               RQConnection rq_connection = new RQConnection(repository, rq_artifact);
               if (rq_connection != null)
               {
                  // open the ReqPro data base
                  rq_project = rq_connection.OpenRqDB();
                  if (rq_project != null)
                  {
                     orphanedRequirements.Clear();

                     ExportToReqPro(repository, rq_connection, rq_project, rq_artifact);
                  }
                  else
                  {
                     MessageBox.Show("ERROR: Cannot establish connection to ReqPro database.\n\n" +
                        "Check the tagged values in the artifact are correct.\n" +
                        "Check the database still exists or is not locked by\n" +
                        "another user, or has not been password protected." );
                  }
               }
            }
         }
         catch (Exception ex)
         {
            MessageBox.Show(ex.Message, "Error (ExportToReqPro)", MessageBoxButtons.OK);
            if (rq_project != null)
               rq_project.CloseProject();
         }
      }

      /// <summary>
      /// EXPORT requirements to ReqPro Database
      /// </summary>
      /// <param name="repository"></param>
      private void ExportToReqPro(EA.Repository repository, RQConnection rq_connection, ReqPro40.Project rq_project, EA.Element rq_artifact)
      {
         ReqPro40.Requirements rq_req_collection;

         try
         {
            IFormatProvider cultureInfo = new CultureInfo("en-US", true);

            bool importNeeded = false;

            string exportDateTime = System.TimeZone.CurrentTimeZone.ToUniversalTime( System.DateTime.Now ).ToString();

            bool newReqMade = false;

            EA_Utilities EA_Utils = new EA_Utilities(repository);

            repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "EA Requirement export at " + exportDateTime, -1 );
                  
            // Get ReqPro requirements collection
            rq_req_collection = get_rq_req_collection(rq_project);

            // Get a list of ReqPro requirements and GUIDs
            //ArrayList rq_GUIDs = new ArrayList();
            //ArrayList rq_reqs = new ArrayList();
            //rq_req_collection.MoveFirst();
            //for (int i = 0; i < rq_req_collection.Count; i++)
           // {
           //    ReqPro40.Requirement rq_req = rq_req_collection.GetCurrentRequirement();
           //    rq_GUIDs.Add( rq_req.GUID );
           //    rq_reqs.Add(rq_req);
           //    rq_req_collection.MoveNext();
           // }
      
            // Update the ReqProDB stereotypes element with all the requirements in the package
            UpdatePackageToReqProDatabaseAssociation(repository, rq_artifact);

            // Scan through the EA requirement artifact's links.
            foreach (EA.Connector connector in rq_artifact.Connectors)
            {
               System.Threading.Thread.Sleep(100);

               EA.Element ea_req = repository.GetElementByID( connector.SupplierID );
               while (ea_req != null)
               {
                  try
                  {
                     //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME,"Exporting " + ea_req.Name, ea_req.ElementID);
                     // if the linked element does not have a ReqPro GUID, then we assume it is
                     // a new requirement that must be added to ReqPro
                     string GUID = EA_Utils.ReadTag(ea_req, "GUID");
                     if (GUID == "")
                     {
                        // must add the requirement to ReqPro
                        object vReqTypeLookupValue = "SR"; 
                        object nothing = Type.Missing;
                        ReqPro40.Requirement rq_req = 
                           rq_req_collection.Add( ea_req.Name, ea_req.Notes, 
                           vReqTypeLookupValue,
                           ReqPro40.enumReqTypesLookups.eReqTypesLookups_Prefix,
                           ea_req.Version,
                           "",
                           nothing,
                           ReqPro40.enumRequirementLookups.eReqLookup_Empty);
                              
                        ExportAttr(repository, rq_req, "Difficulty", ea_req.Difficulty );
                        ExportAttr(repository, rq_req, "Priority"  , ea_req.Priority   );
                        ExportAttr(repository, rq_req, "Status"    , ea_req.Status     );
                        //ExportAttr(repository, rq_req, "Type"      , ea_req.Stereotype );

                        rq_req.Save();

                        rq_req_collection.Save(); 
                     
                        EA_Utils.WriteTag( ea_req, "GUID", rq_req.GUID );
                        repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "EA Requirement counterpart in ReqPro was created : " + ea_req.Name, ea_req.ElementID );
                        newReqMade = true;
                     }
                     else
                     {
                        //string TAG = EA_Utils.ReadTag(ea_req, "TAG");
                        //if (TAG != "")
                        {
                           ReqPro40.Requirement rq_req = rq_project.GetRequirement(GUID, 
                              ReqPro40.enumRequirementLookups.eReqLookup_GUID, 
                              ReqPro40.enumRequirementsWeights.eReqWeight_Heavy, 
                              ReqPro40.enumRequirementFlags.eReqFlag_RetainHierarchy);
                        
                           //rq_req_collection = 
                           //   rq_project.GetRequirements(0, 
                           //   enumRequirementsLookups.eReqsLookup_All, 
                           //   enumRequirementsWeights.eReqWeight_Heavy, 
                           //   enumRequirementFlags.eReqFlag_RetainHierarchy, 
                           //   1024, 5);

                           //foreach(object key in rq_req_collection)
                           //{
                           //   ReqPro40.Requirement lrq_req = rq_project.GetRequirement(key, ReqPro40.enumRequirementLookups.eReqLookup_Key, ReqPro40.enumRequirementsWeights.eReqWeight_Heavy, ReqPro40.enumRequirementFlags.eReqFlag_RetainHierarchy);
                           //   if (lrq_req.GUID.StartsWith(GUID))
                           //   {
                           //      rq_req = lrq_req;
                           //      break;
                           //   }
                           //}

                           //rq_req_collection.MoveFirst();
                           //for (int i = 0; i < rq_req_collection.Count; i++)
                           //{
                           //   ReqPro40.Requirement lrq_req = rq_req_collection.GetCurrentRequirement();
                           //   if (lrq_req.GUID.StartsWith(GUID))
                           //   {
                           //      rq_req = lrq_req;
                           //      break;
                           //   }
                           //   rq_req_collection.MoveNext();
                           //}
                           if (rq_req != null)

                              // EA requirement has the GUID of a ReqPro requirement, so look it up in the
                              // array list we created earlier in order to obtain the reference to the ReqPro
                              // requirement.
                              //int i_rq_req = rq_GUIDs.IndexOf(GUID);
                              //if (0 <= i_rq_req)
                           {
                              // must now update the requirement in ReqPro
                              //ReqPro40.Requirement rq_req = (ReqPro40.Requirement)rq_reqs[i_rq_req];

                              //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, rq_req.get_Tag(ReqPro40.enumTagFormat.eTagFormat_FullTag).ToString(), -1);

                              string rq_datetime = rq_req.VersionDateTime;
                              DateTime rq_dt = new DateTime();
                                    
                              rq_dt = DateTime.Parse(rq_datetime, cultureInfo, DateTimeStyles.NoCurrentDateDefault);
                              rq_dt = rq_dt.ToUniversalTime();
                              //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, rq_req.Name + " DATETIME: " + rq_dt.ToString(), -1);

                              DateTime ea_dt = ea_req.Modified.ToUniversalTime();
                              //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, ea_req.Name + " DATETIME: " + ea_dt.ToString(), -1);

                              if (SyncMode && (0 <= rq_dt.CompareTo(ea_dt)))
                              {
                                 importNeeded = true;
                                 //repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "EA Requirement counterpart in ReqPro was NOT updated (was newer): " + ea_req.Name, ea_req.ElementID );
                              }
                              else
                              {
                                 rq_req.Name = ea_req.Name;
                                 rq_req.Text = ea_req.Notes;

                                 ExportAttr(repository, rq_req, "Difficulty", ea_req.Difficulty );
                                 ExportAttr(repository, rq_req, "Priority"  , ea_req.Priority   );
                                 ExportAttr(repository, rq_req, "Status"    , ea_req.Status     );
                                 //ExportAttr(repository, rq_req, "Type"      , ea_req.Stereotype );

                                 rq_req.Save();
                                 
                                 //rq_req.Refresh(ReqPro40.enumRequirementsWeights.eReqWeight_Heavy);

                                 //rq_req_collection.Save();
                                 //rq_req_collection.Refresh(ReqPro40.enumRequirementsWeights.eReqWeight_Heavy);

                                 //rq_project.Save();

                                 repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "EA Requirement counterpart in ReqPro was updated : " + ea_req.Name, ea_req.ElementID );
                              }
                           }
                           else
                           {
                              // EA requirement has a ReqPro GUID, but that GUID does not exist in
                              // the ReqPro requirement collection. So, we assume someone deleted the
                              // ReqPro requirement, and warn the user that this EA requirement is
                              // probably dead and needs to be removed. This is based on the assumption 
                              // that ReqPro holds the master copy of the requirement and normally, addition
                              // and deletion of requirements happens in ReqPro first.
                              repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "EA Requirement Orphaned (counterpart in ReqPro was missing) : " + ea_req.Name, ea_req.ElementID );

                              // add the EA requirement to the orphaned list for processing later on via another
                              // add-in menu item
                              orphanedRequirements.Add( ea_req );
                           }
                        }
                     }                     
                  }
                  catch (Exception ex)
                  {
                     repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Exception (ExportToReqPro), " + ex.Message + ", " + ea_req.Name, ea_req.ElementID);

                     // Try an re-establish connection and requirement collection references
                     rq_project = rq_connection.ReOpenRqDB();
                     rq_req_collection = get_rq_req_collection(rq_project);
                     continue;
                  }
                  break;

               }
            }
          
            rq_req_collection.Save();

            if (importNeeded && SyncMode)
            {
               ImportFromReqPro(repository, rq_connection, rq_project, rq_artifact);
            }
            else if (importNeeded)
            {
               MessageBox.Show("Some ReqPro requirements were modified later than their EA counterparts.\n" +
                  "You may need to perform an import following this export");
            }

            //rq_project.Refresh(true);
            if (!SyncMode)
               rq_project.CloseProject();  

            if (newReqMade)
            {
               if (orphanedRequirements.Count == 0)
               {
                  MessageBox.Show("Export To ReqPro Complete.\n\n" +
                     "New requirements were added to ReqPro.");
               }
               else
               {
                  MessageBox.Show("Export To ReqPro Complete.\n\n" +
                     "New requirements were added to ReqPro." +
                     "Some EA requirements were orphaned." );
               }
            }
            else if (orphanedRequirements.Count == 0)
            {
               MessageBox.Show("Export To ReqPro Complete.\n\n" + 
                  "No new requirements were added to ReqPro.");
            }
            else
            {
               MessageBox.Show("Export To ReqPro Complete.\n\n" +
                  "No new requirements were added to ReqPro.\n\n" +
                  "Some EA requirements were orphaned." );
            }
         }
         catch (Exception ex)
         {
            MessageBox.Show(ex.Message, "Error (ExportToReqPro)", MessageBoxButtons.OK);
            if (rq_project != null)
               rq_project.CloseProject();
         }
      }


      private void UpdatePackageToReqProDatabaseAssociation(EA.Repository repository, EA.Element rq_artifact)
      {
         repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "Please Wait - Updating ReqProDB element", rq_artifact.ElementID);

         // Scan EA package to find all requirement elements, and add links to them
         // from the ReqPro artifact element we have written into the selected package.
         EA_Utilities EA_Utils = new EA_Utilities(repository);

         ArrayList allowedElementTypes = new ArrayList();
         allowedElementTypes.Add("Requirement");
         allowedElementTypes.Add("UseCase");

         ElementAccumulator reqLister = new ElementAccumulator(allowedElementTypes);

         EA.Package thePackage = repository.GetPackageByID( rq_artifact.PackageID );
         EA_Utils.findAndProcessPackageElements( thePackage, reqLister, true );
  
         // Get all existing connectors into a list
         ArrayList connectors = new ArrayList();
         foreach(EA.Connector theConnector in rq_artifact.Connectors)
         {
            connectors.Add(theConnector.SupplierID);
         }

         // For each element, if it is not already referred to by a connector, add a connector for it
         foreach (EA.Element theElement in reqLister.Elements)
         {
            if (!connectors.Contains(theElement.ElementID))
            {
               add_connection(repository, rq_artifact, theElement);
            }
         }
         rq_artifact.Connectors.Refresh();


         // Now remove any connectors that point to element IDs that are no longer in the package
         short i = 0;
         foreach (EA.Connector theConnector in rq_artifact.Connectors)
         {
            if (!reqLister.ElementIDs.Contains(theConnector.SupplierID))
            {
               rq_artifact.Connectors.Delete(i);
               rq_artifact.Connectors.Refresh();
            }
            else
            {
               i++;
            }
         }  
         rq_artifact.Update();
         rq_artifact.Refresh();
      }

      private void UpdatePackageToReqProDatabaseAssociation(EA.Repository repository)
      {
         EA.Element rq_artifact = (EA.Element)repository.GetTreeSelectedObject();
         if (rq_artifact != null)
         {
            UpdatePackageToReqProDatabaseAssociation(repository, rq_artifact);
         }
      }


      /// <summary>
      /// 
      /// </summary>
      /// <param name="repository"></param>
      private void AssociatePackageToReqProDatabase(EA.Repository repository)
      {
         try
         {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "Select Requisite Pro project file";
            ofd.Filter = "ReqPro files (*.rqs)|*.rqs|All files (*.*)|*.*";
            DialogResult dlgRes = ofd.ShowDialog();

            if (dlgRes == DialogResult.OK)
            {
               Logon logon = new Logon("");
               dlgRes = logon.ShowDialog();

               if (dlgRes == DialogResult.OK)
               {
                  string username = logon.ebUserName.Text;
                  string password = logon.ebPassword.Text;
                  

                  // check if the project will open
                  RQConnection connection = new RQConnection(ofd.FileName, logon.ebUserName.Text, logon.ebPassword.Text);

                  // add the RQ project to the EA repository
                  object o;
                  EA.ObjectType type = repository.GetTreeSelectedItem(out o);

                  connection.SaveAsEAElement(repository, (EA.Package)o);

                  EA.Element rq_artifact = repository.GetElementByID( connection.EAId );
                  if (rq_artifact != null)
                  {
                     UpdatePackageToReqProDatabaseAssociation(repository, rq_artifact);
                  }
               }
            }
         }
         catch (Exception ex)
         {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
         }
      }


 


 


      public void EA_Disconnect()  
      {
         GC.Collect();  
         GC.WaitForPendingFinalizers();   
      }

   }



   /// <summary>
   /// This class is one derived from the EA_UtilitiesRecursionWorker base class so that
   /// an instance of it can be used as a parameter in the EA_Utilities.findAndProcessPackageElements
   /// method which recursively parses a given package. Thus, clients can parse EA model structure but
   /// specify their own functionality to be carried out on packages and elements found in the 
   /// parsing.
   /// This particular derived class is designed to collect a list of element names from the
   /// package, from elements that have a type that is acceptable.
   /// </summary>
   public class ElementAccumulator : EA_UtilitiesRecursionWorker
   {
      public ArrayList Elements = null;
      public ArrayList ElementIDs = null;
      private ArrayList validElementTypes = null;

      public ElementAccumulator(ArrayList elementTypeList): base()
      {
         validElementTypes = elementTypeList;
         Elements = new ArrayList();
         ElementIDs = new ArrayList();
      }

      public override void processElement( EA.Element theElement )
      {
         if (validElementTypes.Contains( theElement.Type ))
         {
            Elements.Add( theElement );
            ElementIDs.Add( theElement.ElementID );
         }
      }
   }

}