Rev 2157 | 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 elementsbool 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 elementsshort 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 viewMain.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 artifactRQ_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 viewMain.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 EAEA.Package new_ea_package = EA_Package.create(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-objectsforeach( 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-objectsforeach( 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 elementif (ea_parent_element != null){// create a representative element in EAnew_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 objectsif (rq_obj.parent != null){rq_obj.parent.ReqPro_traces.Add(rq_obj.guid);}}// else create the requirement element as a child of a parent packageelse if (ea_parent_package != null){// create a representative element in EAnew_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++;// tie the new EA element back to the facsimile of the req pro requirement that led to its creation.// This will support the writing of trace info later on.rq_obj.ea_element_ID = new_ea_element.ElementID;// NOTE: deliberately dont do TreePos in copyReq() because copyReq() may be called in other// contexts where the caller does not want any fiddling with the tree position in the EA browser.new_ea_element.TreePos = rq_obj.treePos;copyReq(new_ea_element, rq_obj);new_ea_element.Update();// Using recursion, scan this objects sub-objectsforeach( ReqPro_object sub_obj in rq_obj.ReqPro_objects ){if (Main.mustAbort)break;write_ea_database(null, new_ea_element, sub_obj); // recurse}}}}}/// <summary>/// Copy the details of the reqpro based requirement facsimile, into an EA element/// </summary>/// <param name="new_ea_element"></param>/// <param name="rq_obj"></param>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);// for requirement type attribute, enforce just a single stereotype in the EA element, even though// StereotypeEx can be a comma seperated list.new_ea_element.StereotypeEx = rq_obj.type;new_ea_element.Stereotype = rq_obj.type;}}}