private void executeInstructions(FMTreeNode node, string priority) { List <TagType> tags = new List <TagType>(); if (node.baseModelObject.tag != null) { tags.AddRange(node.baseModelObject.tag); } // remove empty value tags (cleans up) tags.RemoveAll(t => string.IsNullOrEmpty(t.value)); // remove old Reference and set new Reference to base tags.RemoveAll(t => t.name.StartsWith("Reference.")); if (!node.isNew) { switch (node.baseModelObject.stereotype) { case R2Const.ST_CRITERION: tags.Add(new TagType() { name = "Reference.Alias", value = baseName }); string functionId = node.baseModelObject.name.Substring(0, node.baseModelObject.name.IndexOf('#')); tags.Add(new TagType() { name = "Reference.FunctionID", value = functionId }); int criterionId = int.Parse(node.baseModelObject.name.Substring(node.baseModelObject.name.IndexOf('#') + 1)); tags.Add(new TagType() { name = "Reference.CriterionID", value = criterionId.ToString() }); break; case R2Const.ST_HEADER: case R2Const.ST_FUNCTION: tags.Add(new TagType() { name = "Reference.Alias", value = baseName }); tags.Add(new TagType() { name = "Reference.FunctionID", value = node.baseModelObject.alias }); break; case R2Const.ST_SECTION: tags.Add(new TagType() { name = "Reference.Alias", value = baseName }); tags.Add(new TagType() { name = "Reference.SectionID", value = node.baseModelObject.alias }); break; } } // set Priority & set ChangeIndicator to default "NC"; changed when executing instruction switch (node.baseModelObject.stereotype) { case R2Const.ST_SECTION: case R2Const.ST_HEADER: case R2Const.ST_FUNCTION: case R2Const.ST_CRITERION: tags.RemoveAll(t => "Reference.ChangeIndicator".Equals(t.name)); tags.Add(new TagType() { name = "Reference.ChangeIndicator", value = node.isNew?CHANGEINDICATOR_NEW:CHANGEINDICATOR_NOCHANGE }); tags.Add(new TagType() { name = R2Const.TV_PRIORITY, value = priority }); break; } // copy changenote.value if any if (node.hasInstruction) { int changeNoteCount = node.instructionObject.tag.Count(t => R2Const.TV_CHANGENOTE.Equals(t.name)); if (changeNoteCount > 1) { _OutputListener.writeOutput("[WARN] {0} expected 0..1 ChangeNote tag but got {1}", node.baseModelObject.name, changeNoteCount, node.instrID); } TagType tagChangeNote = FirstOrDefaultNonEmptyValue(node.instructionObject.tag, R2Const.TV_CHANGENOTE); if (tagChangeNote != null) { tags.Add(tagChangeNote); } } node.baseModelObject.tag = tags.ToArray(); if (node.hasInstruction) { TagType tagChangeIndicator = node.baseModelObject.tag.Single(t => "Reference.ChangeIndicator".Equals(t.name)); // copy ExternalReferences List <TagType> tags2 = new List <TagType>(); if (node.baseModelObject.tag != null) { tags2.AddRange(node.baseModelObject.tag); } tags2.AddRange(node.instructionObject.tag.Where(t => R2Const.TV_EXTERNALREFERENCE.Equals(t.name))); node.baseModelObject.tag = tags2.ToArray(); // update Optionality for Criterion if (R2Const.ST_CRITERION.Equals(node.baseModelObject.stereotype)) { int optionalityCount = node.baseModelObject.tag.Count(t => R2Const.TV_OPTIONALITY.Equals(t.name)); if (optionalityCount == 0) { _OutputListener.writeOutput("[ERROR] {0} expected 1 Optionality tag but got none", node.baseModelObject.name, node.instrID); return; } else if (optionalityCount != 1) { _OutputListener.writeOutput("[WARN] {0} expected 1 Optionality tag but got {1}", node.baseModelObject.name, optionalityCount, node.instrID); } TagType tagOptionality = node.baseModelObject.tag.First(t => R2Const.TV_OPTIONALITY.Equals(t.name)); int newOptionalityCount = node.instructionObject.tag.Count(t => R2Const.TV_OPTIONALITY.Equals(t.name)); if (newOptionalityCount > 1) { _OutputListener.writeOutput("[WARN] {0} expected 0..1 Optionality tag but got {1}", node.baseModelObject.name, newOptionalityCount, node.instrID); } TagType tagOptionalityNew = FirstOrDefaultNonEmptyValue(node.instructionObject.tag, R2Const.TV_OPTIONALITY); if (tagOptionalityNew != null && !tagOptionalityNew.value.Equals(tagOptionality.value)) { if (tagChangeIndicator.value != CHANGEINDICATOR_NEW) { tagChangeIndicator.value = CHANGEINDICATOR_CHANGED; } tagOptionality.value = tagOptionalityNew.value; } } // update name if changed if (!node.baseModelObject.name.Equals(node.instructionObject.name)) { if (tagChangeIndicator.value != CHANGEINDICATOR_NEW) { tagChangeIndicator.value = CHANGEINDICATOR_CHANGED; } string newName = node.instructionObject.name; node.baseModelObject.name = newName; // set alias to ID in name if Header or Function switch (node.baseModelObject.stereotype) { case R2Const.ST_HEADER: case R2Const.ST_FUNCTION: int sp = newName.IndexOf(' '); if (sp == -1) { sp = newName.Length; } node.baseModelObject.alias = newName.Substring(0, sp); break; } } // update notes if instruction has notes if (node.instructionObject.notes != null && node.instructionObject.notes.Text.Length > 0) { if (tagChangeIndicator.value != CHANGEINDICATOR_NEW) { tagChangeIndicator.value = CHANGEINDICATOR_CHANGED; } node.baseModelObject.notes = node.instructionObject.notes; } // is a new Priority in the instruction? TagType tagPriorityNew = FirstOrDefaultNonEmptyValue(node.instructionObject.tag, R2Const.TV_PRIORITY); if (tagPriorityNew != null) { int newPriorityCount = node.instructionObject.tag.Count(t => R2Const.TV_PRIORITY.Equals(t.name)); if (newPriorityCount > 1) { _OutputListener.writeOutput("[WARN] {0} expected 1 Priority tag but got {1}", node.baseModelObject.name, newPriorityCount, node.instrID); } if (!string.IsNullOrEmpty(tagPriorityNew.value)) { priority = tagPriorityNew.value; } } // update priority in the compiled (base) profile TagType tagPriority = FirstOrDefaultNonEmptyValue(node.baseModelObject.tag, R2Const.TV_PRIORITY); if (tagPriority != null) { tagPriority.value = priority; } else { node.addBaseModelTag(R2Const.TV_PRIORITY, priority); } // do Qualifier stuff. Delete or Deprecate int newQualifierCount = node.instructionObject.tag.Count(t => R2Const.TV_QUALIFIER.Equals(t.name)); if (newQualifierCount > 1) { _OutputListener.writeOutput("[WARN] {0} expected 0..1 Qualifier tag but got {1}", node.baseModelObject.name, newQualifierCount, node.instrID); } TagType tagQualifier = FirstOrDefaultNonEmptyValue(node.instructionObject.tag, R2Const.TV_QUALIFIER); if (tagQualifier != null) { if (QUALIFIER_DELETE.Equals(tagQualifier.value)) { tagChangeIndicator.value = CHANGEINDICATOR_DELETED; // Make sure children are not included in profile and stop processing node.children.Clear(); } else if (QUALIFIER_DEPRECATE.Equals(tagQualifier.value)) { tagChangeIndicator.value = CHANGEINDICATOR_DEPRECATED; } } } List <FMTreeNode> newChildren = new List <FMTreeNode>(); foreach (FMTreeNode child in node.children) { executeInstructions(child, priority); if (child.includeInProfile) { newChildren.Add(child); } } node.children = newChildren; }
private void setCompilerInclusionReason(FMTreeNode node, string reason) { node.addBaseModelTag(TV_INCLUSIONREASON, reason); }