This script was developed to support parallel development on a project where requirements were branched and merged. This used a specific (one-to-one) link module to link master and branched requirements.
This script provides a simple to use dialog that enables you to copy attribute values from the branched requirement back up to the master copy. It assumes that each requirement is a branched copy of a master requirement and that they are linked one-to-one.
// Copy Attributes Up /* Copy attribute values from (in) linked requirements to the current module. Provides a dialog to control the update of the master copy of requirements from branched requirements that were previously flowed down.. Tony Goodman Initial Version */ // Current module Module masterModule = null // dialog box elements DB dbMain = null DBE dbeDialogLabel = null DBE dbeFrame = null DBE dbeMasterModuleFrame = null DBE dbeMasterModule = null DBE dbeBranchedRequirementsFrame = null DBE dbeRelationships = null DBE dbeSpacer = null DBE dbeBranchedModules = null DBE dbeAttributes = null DBE dbeUpdate = null DBE dbeSelectAll = null DBE dbeClearAll = null string dummy[] = {} Skip skipMasterAttributes = createString Skip skipBranchedAttributes = createString Skip skipRelationships = createString Skip skipBranchedModules = createString Skip skipSelectedBranchedModules = createString Skip skipSelectedAttributes = createString bool relationshipsFound = false string selectedRelationship = "" Buffer errBuf = create int errors = 0 int objectsUpdated = 0 /********************** getAttributes **************************/ string getAttributes() { string mName = "" Module branchedModule = null AttrDef ad = null string attr = "" int i = 0 empty(dbeAttributes) if (!relationshipsFound) { inactive(dbeAttributes) return("") } delete(skipBranchedAttributes) skipBranchedAttributes = createString for mName in skipSelectedBranchedModules do { branchedModule = read(mName, false) if (null branchedModule) { return("Error opening module:\n" mName) } (current ModuleRef__) = branchedModule filtering off outlining off for ad in branchedModule do { if (!ad.object) continue if (ad.name == "Absolute Number") continue if (ad.system) continue put(skipBranchedAttributes, ad.name, ad.name) } } delete(skipMasterAttributes) skipMasterAttributes = createString (current ModuleRef__) = masterModule for ad in masterModule do { if (!ad.object) continue if (ad.dxl) continue if (ad.name == "Absolute Number") continue if (ad.system) continue if (!find(skipBranchedAttributes, ad.name)) continue put(skipMasterAttributes, ad.name, ad.name) } put(skipMasterAttributes, "Object Heading", "Object Heading") put(skipMasterAttributes, "Object Text", "Object Text") // Refresh dialog i = 0 for attr in skipMasterAttributes do { insert(dbeAttributes, i, attr, iconNone) setCheck(dbeAttributes, i, true) i++ } return("") } /******************** getBrachedModules *********************/ void getBrachedModules() { ModName_ mn = null Object o = null LinkRef lr = null string mName = "" int i = 0 empty(dbeBranchedModules) if (!relationshipsFound) { return() } delete(skipBranchedModules) skipBranchedModules = createString delete(skipSelectedBranchedModules) skipSelectedBranchedModules = createString for o in masterModule do { for lr in o <- "*" do { if (name(module(lr)) != selectedRelationship) continue mn = source(lr) put(skipBranchedModules, fullName(mn), fullName(mn)) } } i = 0 for mName in skipBranchedModules do { insert(dbeBranchedModules, i, mName, iconNone) set(dbeBranchedModules, i, true) i++ put(skipSelectedBranchedModules, mName, mName) } } /***************** getRelationships *********************/ void getRelationships() { Object o = null LinkRef lr = null int i = 0 string relationship = "" delete(skipRelationships) skipRelationships = createString for o in masterModule do { for lr in o <- "*" do { put(skipRelationships, name(module(lr)), name(module(lr))) relationshipsFound = true } } if (relationshipsFound) { i = 0 for relationship in skipRelationships do { insert(dbeRelationships, i++, relationship) } } else { insert(dbeRelationships, 0, "<no relationships found>") inactive(dbeUpdate) } set(dbeRelationships, 0) selectedRelationship = get(dbeRelationships) } /******************** updateObject *********************/ void updateObject(Object o, Object othero) { string attr = "" for attr in skipSelectedAttributes do { // ignores attributes that do not exist without error copyAttribute_(othero, o, attr) } objectsUpdated++ } /****************** doSelectBranchedModules *********************/ void doSelectBranchedModules(DBE dbe, int x) { string res = "" string mName = "" delete(skipSelectedBranchedModules) skipSelectedBranchedModules = createString for mName in dbeBranchedModules do { put(skipSelectedBranchedModules, mName, mName) } res = getAttributes() if (res != "") { infoBox("ERROR: " res) } } /****************** doSelectRelationship *********************/ void doSelectRelationship(DBE dbe) { string res = "" selectedRelationship = get(dbeRelationships) getBrachedModules() res = getAttributes() if (res != "") { infoBox("ERROR: " res) } } /********************* doUpdate *********************/ void doUpdate(DB db) { ModName_ mn = null string res = "" Object o = null Object othero = null Link l = null string attr = "" string mName = "" int i = 0 if (!confirm("You are about to update master requirements in the current module with values\n" //- "copied from linked (branched) requirements.\n\nAre you sure you want to continue?")) { return } delete(skipSelectedAttributes) skipSelectedAttributes = createString for (i = 0; i < noElems(dbeAttributes); i++) { if (getCheck(dbeAttributes, i)) { attr = getColumnValue(dbeAttributes, i, 0) put(skipSelectedAttributes, attr, attr) } } for o in masterModule do { for l in o <- "*" do { if (name(module(l)) != selectedRelationship) continue mn = source(l) if (!find(skipSelectedBranchedModules, fullName(mn))) continue othero = source(l) if (null othero) { errBuf += "Object " identifier(o) " is linked to a null object\n" errors++ continue } if (isDeleted othero) { errBuf += "Object " identifier(o) " is linked to a deleted object\n" errors++ continue } updateObject(o, othero) } } if (errors > 0) { infoBox("Update complete, but with errors:\n" stringOf(errBuf)) } else { infoBox("Update completed successfully.\n" //- objectsUpdated " object" (objectsUpdated == 1 ? " has " : "s have " ) //- "been updated\nPlease remember to save your module.") } release(dbMain) } /***************** doSelectAll *********************/ void doSelectAll(DBE dbe) { int i = 0 for (i = 0; i < noElems(dbeAttributes); i++) { setCheck(dbeAttributes, i, true) } } /******************** doClearAll *********************/ void doClearAll(DBE dbe) { int i = 0 for (i = 0; i < noElems(dbeAttributes); i++) { setCheck(dbeAttributes, i, false) } } /******************** doClose *********************/ void doClose(DB db) { release(dbMain) } /******************** buildDialog *********************/ void buildDialog() { string res = "" dbMain = create(masterModule, "Copy Attributes Up", styleCentered) dbeDialogLabel = label(dbMain, "This utility allows you to update attribute values in your master requirements module.\n" //- "Values are copied from branched requirements that they are linked to via the selected relationship.\n" //- "Only values for the selected attributes are compared and updated.") dbeFrame = frame(dbMain, "", 450, 460) dbeFrame->"top"->"flush"->dbeDialogLabel dbeFrame->"left"->"form" dbeFrame->"right"->"form" dbeFrame->"bottom"->"form" dbeMasterModuleFrame = frame(dbMain, "Master requirements module", 400, 20) dbeMasterModuleFrame->"top"->"inside"->dbeFrame dbeMasterModuleFrame->"left"->"inside"->dbeFrame dbeMasterModuleFrame->"right"->"inside"->dbeFrame dbeMasterModuleFrame->"bottom"->"unattached" dbeMasterModule = field(dbMain, "", fullName(masterModule), 50, true) dbeMasterModule->"top"->"inside"->dbeMasterModuleFrame dbeMasterModule->"left"->"inside"->dbeMasterModuleFrame dbeMasterModule->"right"->"inside"->dbeMasterModuleFrame dbeMasterModule->"bottom"->"inside"->dbeMasterModuleFrame dbeBranchedRequirementsFrame = frame(dbMain, "Branched requirements", 400, 360) dbeBranchedRequirementsFrame->"top"->"flush"->dbeMasterModuleFrame dbeBranchedRequirementsFrame->"left"->"inside"->dbeFrame dbeBranchedRequirementsFrame->"right"->"inside"->dbeFrame dbeBranchedRequirementsFrame->"bottom"->"inside"->dbeFrame dbeRelationships = choice(dbMain, "Relationship:", dummy, 0, 30, false) dbeRelationships->"top"->"inside"->dbeBranchedRequirementsFrame dbeRelationships->"left"->"inside"->dbeBranchedRequirementsFrame dbeRelationships->"right"->"inside"->dbeBranchedRequirementsFrame dbeRelationships->"bottom"->"unattached" dbeBranchedModules = listView(dbMain, listViewOptionMultiselect, 400, 5, dummy) dbeBranchedModules->"top"->"flush"->dbeRelationships dbeBranchedModules->"left"->"inside"->dbeBranchedRequirementsFrame dbeBranchedModules->"right"->"inside"->dbeBranchedRequirementsFrame dbeBranchedModules->"bottom"->"unattached" dbeAttributes = listView(dbMain, listViewOptionCheckboxes | listViewOptionMultiselect, 400, 10, dummy) dbeAttributes->"top"->"flush"->dbeBranchedModules dbeAttributes->"left"->"inside"->dbeBranchedRequirementsFrame dbeAttributes->"right"->"inside"->dbeBranchedRequirementsFrame dbeAttributes->"bottom"->"unattached" dbeSelectAll = button(dbMain, "Select All", doSelectAll) dbeSelectAll->"top"->"flush"->dbeAttributes dbeSelectAll->"left"->"inside"->dbeBranchedRequirementsFrame dbeSelectAll->"right"->"unattached" dbeSelectAll->"bottom"->"inside"->dbeBranchedRequirementsFrame dbeClearAll = button(dbMain, "ClearAll", doClearAll) dbeClearAll->"top"->"flush"->dbeAttributes dbeClearAll->"left"->"flush"->dbeSelectAll dbeClearAll->"right"->"unattached" dbeClearAll->"bottom"->"inside"->dbeBranchedRequirementsFrame dbeUpdate = apply(dbMain, "Update", doUpdate) realize(dbMain) insertColumn(dbeAttributes, 0, "Attributes to compare/update", 430, iconNone) insertColumn(dbeBranchedModules, 0, "Branched requirements modules", 430, iconNone) set(dbeRelationships, doSelectRelationship) set(dbeBranchedModules, doSelectBranchedModules, doSelectBranchedModules, doSelectBranchedModules) getRelationships() getBrachedModules() getAttributes() block(dbMain) destroy(dbMain) dbMain = null } /*************************** requirementsFlowUp ***************************/ void requirementsFlowUp() { masterModule = current Module if (null masterModule || !isEdit masterModule) { infoBox("This utility can only be run from a formal module open for exclusive edit.") halt } (current ModuleRef__) = masterModule buildDialog() } /*************************** MAIN ***************************/ requirementsFlowUp()