/// <summary>
        /// Loads a configuration into Confeaturator. Configuration validation errors do not pop-up
        /// in the UI, but a list of them are returned.
        /// </summary>
        /// <param name="fileName">The .confeaturator file path containing the configuration to be loaded.</param>
        /// <returns>Any path with errors that were found when loading the configuration.</returns>
        private List <string> LoadConfiguration(string fileName)
        {
            List <string> pathWithErrors   = new List <string>();
            XmlSerializer xmlSerializer    = new XmlSerializer(typeof(List <string>));
            FileStream    fs               = new FileStream(fileName, FileMode.Open);
            List <string> checkedNodePaths = xmlSerializer.Deserialize(fs) as List <string>;

            fs.Close();
            foreach (string checkedNodePath in checkedNodePaths)
            {
                string path = HttpUtility.HtmlDecode(checkedNodePath);
                FeatureModelTreeNode node = GetNodeFromFullPath(trvFeatures.Nodes, path);
                if (node != null)
                {
                    if (node.Kind == FeatureModelNodeKind.Optional || node.Kind == FeatureModelNodeKind.NotApply)
                    {
                        node.Check();
                    }
                }
                else
                {
                    pathWithErrors.Add(path);
                }
            }
            return(pathWithErrors);
        }
        // TODO: the code below can be optimized! I'm using a dumb/slow approach here checking every node.

        /// <summary>
        /// Traverses a tree looking for the node containing a given full path.
        /// </summary>
        /// <param name="nodes">The collection of nodes.</param>
        /// <param name="path">Path to be searched for.</param>
        /// <returns></returns>
        private FeatureModelTreeNode GetNodeFromFullPath(TreeNodeCollection nodes, string path)
        {
            FeatureModelTreeNode result = null;

            foreach (FeatureModelTreeNode node in nodes)
            {
                if (node.FullPath == path)
                {
                    result = node;
                    break;
                }
            }
            if (result == null)
            {
                foreach (FeatureModelTreeNode node in nodes)
                {
                    result = GetNodeFromFullPath(node.Nodes, path);
                    if (result != null)
                    {
                        break;
                    }
                }
            }
            return(result);
        }
        /// <summary>
        /// Gets a list of errors present in the current configuration.
        /// </summary>
        /// <returns>A list of errors present in the current configuration.</returns>
        private List <string> GetConfigurationErrors()
        {
            List <string> errors = new List <string>();

            DTEHelper.ClearErrorsFromOutputPane();
            if (this.trvFeatures.Nodes == null || this.trvFeatures.Nodes.Count == 0)
            {
                errors.Add("No features available. Ensure you feature model diagram(s) has features and Confeaturator is refreshed.");
            }
            else
            {
                FeatureModelTreeNode rootNode = this.trvFeatures.Nodes[0] as FeatureModelTreeNode;
                Feature feature = rootNode.FeatureModelElement as Feature;
                if (feature == null)
                {
                    errors.Add("Root node should be a feature. Please re-check you feature model diagrams.");
                }
                else
                {
                    if (rootNode.Status == FeatureModelNodeStatus.Unchecked)
                    {
                        string errorMessage = string.Format("Root Confeaturator node '{0}' should be checked.", feature.Name);
                        errors.Add(errorMessage);
                    }
                    rootNode.LogAlternativeIntervalErrors(errors);
                }
            }
            return(errors);
        }
        /// <summary>
        /// Adds child Confeaturator nodes to a given node.
        /// </summary>
        /// <param name="node">The node to which children should be added.</param>
        private void AddChildFeatureModelNodes(FeatureModelTreeNode node)
        {
            FeatureModelElement fmElement = node.FeatureModelElement;

            foreach (FeatureModelElement childFMElement in fmElement.SubFeatureModelElements)
            {
                node.Nodes.Add(CreateFeatureModelTreeNode(childFMElement));
            }

            // cross-feature model logic
            Feature feature = fmElement as Feature;

            if (feature != null)
            {
                if (feature.IsReference && !addedFeatures.Contains(feature.Name))
                {
                    FeatureModel definitionFeatureModel = Util.LoadFeatureModel(DTEHelper.GetFullProjectItemPath(feature.DefinitionFeatureModelFile));
                    Feature      definitionFeature      = definitionFeatureModel.GetFeature(feature.Name);
                    if (definitionFeature != null)
                    {
                        foreach (FeatureModelElement childFMElement in definitionFeature.SubFeatureModelElements)
                        {
                            node.Nodes.Add(CreateFeatureModelTreeNode(childFMElement));
                        }
                    }
                }
                addedFeatures.Add(feature.Name);
            }
        }
        /// <summary>
        /// Creates a Confeaturator node.
        /// </summary>
        /// <param name="fmElement">Feature model element used to create the node.</param>
        /// <returns>The created Confeaturator node.</returns>
        private FeatureModelTreeNode CreateFeatureModelTreeNode(FeatureModelElement fmElement)
        {
            FeatureModelTreeNode node = new FeatureModelTreeNode(fmElement);

            AddChildFeatureModelNodes(node);
            node.AdjustFont(trvFeatures.Font);
            return(node);
        }
 /// <summary>
 /// Recursively logs the checked Confeaturator node paths into a list of paths.
 /// </summary>
 /// <param name="node">The node where to start the logging recursion.</param>
 /// <param name="checkedNodePaths">The cumulative list of strings where to log the checked node paths.</param>
 private void LogCheckedNodePaths(FeatureModelTreeNode node, List <string> checkedNodePaths)
 {
     if (node.IsChecked)
     {
         checkedNodePaths.Add(HttpUtility.HtmlEncode(node.FullPath));
     }
     foreach (FeatureModelTreeNode childNode in node.Nodes)
     {
         LogCheckedNodePaths(childNode, checkedNodePaths);
     }
 }
        /// <summary>
        /// Inovkes actions from registered Confeaturator Action Providers.
        /// </summary>
        /// <param name="sender">The event sender object.</param>
        /// <param name="e">The event arguments.</param>
        private void btnConfigureEnvironment_Click(object sender, EventArgs e)
        {
            if (this.ConfeaturatorTreeViewHasNodes)
            {
                List <string> errors = GetConfigurationErrors();
                if (errors.Count > 0)
                {
                    MessageBox.Show("You feature model configuration has errors, therefore Confeaturator Actions cannot be launched. Please check the Error List and fix the errors reported.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    ShowErrorsInErrorList(errors);
                }
                else
                {
                    // launching Confeaturator actions registered through FeatureModelConfigureEnvironment event
                    if (ConfeaturatorActions != null)
                    {
                        try {
                            ConfeaturatorActions(this, new ConfeaturatorActionProviderEventArgs(trvFeatures.Nodes[0] as FeatureModelTreeNode, serviceProvider));
                        } catch (Exception ex) {
                            MessageBox.Show("Error launching Confeaturator actions: " + ex.Message);
                        }
                    }

                    // launching Confeaturator actions registered through IConfeaturatorActionProvider iterface
                    List <ConfeaturatorActionProviderSetting> confeaturatorActionSettings = LoadConfeaturatorActionSettings();
                    if (confeaturatorActionSettings.Count == 0)
                    {
                        MessageBox.Show("No Confeaturator Action Providers are currently specified for this solution. You can edit the Confeaturator Action Providers for this solution by clicking in the \"Add/Remove Confeaturator Action Providers\" button.", "Confeaturator Actions not run", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    foreach (ConfeaturatorActionProviderSetting confeaturatorActionSetting in confeaturatorActionSettings)
                    {
                        try {
                            string projectPath  = DTEHelper.GetProjectFolderPath();
                            string assemblyPath = Path.Combine(projectPath, confeaturatorActionSetting.AssemblyName);
                            //AppDomainSetup appDomainSetup = new AppDomainSetup();
                            // setting ShadowCopyFile to true so that we don't lock the assembly
                            //appDomainSetup.ShadowCopyFiles = "true";
                            //appDomainSetup.ApplicationBase = Path.GetDirectoryName(projectPath);
                            //tempDomain = AppDomain.CreateDomain("TempConfeaturatorDomain", null, appDomainSetup);
                            //Assembly confeaturatorActionAssembly = tempDomain.Load(AssemblyName.GetAssemblyName(assemblyPath));
                            Assembly confeaturatorActionAssembly             = Assembly.LoadFile(assemblyPath);
                            IConfeaturatorActionProvider confeaturatorAction = confeaturatorActionAssembly.CreateInstance(confeaturatorActionSetting.QualifiedClassName) as IConfeaturatorActionProvider;
                            FeatureModelTreeNode         rootNode            = trvFeatures.Nodes[0] as FeatureModelTreeNode;
                            confeaturatorAction.PerformConfeaturatorAction(DTEHelper.DTE, GetSelectedFeatures());
                        } catch (Exception ex) {
                            MessageBox.Show("Error launching Confeaturator actions: " + ex.Message + "\r\n\r\nYou can edit the Confeaturator Action Providers for this solution by clicking in the \"Add/Remove Confeaturator Action Providers\" button.", "Confeaturator Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                }
            }
            else
            {
                Util.ShowError("Confeaturator tree view has no nodes! Please refresh it.");
            }
        }
 /// <summary>
 /// Enables the user to check/uncheck nodes using the space keyboard key.
 /// </summary>
 /// <param name="sender">Event sender object.</param>
 /// <param name="e">Event arguments.</param>
 private void trvFeatures_KeyDown(object sender, KeyEventArgs e)
 {
     if (e.KeyCode == Keys.Space)
     {
         if (trvFeatures != null && trvFeatures.SelectedNode != null)
         {
             FeatureModelTreeNode selectedNode = trvFeatures.SelectedNode as FeatureModelTreeNode;
             selectedNode.Click();
         }
     }
 }
 /// <summary>
 /// Checks/unchecks a Confeaturator node and perform related actions, unless the
 /// click happened as a result collapsing/expanding the node.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void trvFeatures_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
 {
     if (!(e.Node as FeatureModelTreeNode).IsCollapsingOrExpanding)
     {
         if (e.Button == MouseButtons.Left)
         {
             FeatureModelTreeNode node = e.Node as FeatureModelTreeNode;
             node.Click();
         }
     }
     (e.Node as FeatureModelTreeNode).IsCollapsingOrExpanding = false;
 }
示例#10
0
        /// <summary>
        /// Recursively logs included features from a given Feature Model tree node into a list of features.
        /// </summary>
        /// <param name="node">The node from where to start the recursion.</param>
        /// <param name="result">A cumulative list of included features.</param>
        private void LogIncludedFeatures(FeatureModelTreeNode node, List <Feature> result)
        {
            Feature feature = node.FeatureModelElement as Feature;

            if (feature != null && node.IsPartOfConfiguration)
            {
                result.Add(feature);
            }
            foreach (FeatureModelTreeNode childNode in node.Nodes)
            {
                LogIncludedFeatures(childNode, result);
            }
        }
示例#11
0
        /// <summary>
        /// Appends the Details table to the report to the specified StringBuilder.
        /// </summary>
        /// <param name="htmlBuilder">The HTML string builder</param>
        /// <param name="root">The root Confeaturator node.</param>
        /// <param name="configurations">List of configurations.</param>
        internal static void AppendTable(StringBuilder htmlBuilder, FeatureModelTreeNode root, List<Configuration> configurations)
        {
            htmlBuilder.Append("<h2>Details</h2>");
            htmlBuilder.Append("<table border='1' cellpadding='5'>"); htmlBuilder.Append("<tr style='background-color:wheat'><th>Features</th>");
            foreach (Configuration configuration in configurations) {
                htmlBuilder.Append("<th>" + configuration.ProductName + "</th>");
            }

            // no Total column if this report is being generated for only one configuration.
            if (configurations.Count > 1) {
                htmlBuilder.Append("<th>Total</th></tr>");
            }
            AppendRow(htmlBuilder, root, configurations, 0);
        }
示例#12
0
        /// <summary>
        /// Appends the Details table to the report to the specified StringBuilder.
        /// </summary>
        /// <param name="htmlBuilder">The HTML string builder</param>
        /// <param name="root">The root Confeaturator node.</param>
        /// <param name="configurations">List of configurations.</param>
        internal static void AppendTable(StringBuilder htmlBuilder, FeatureModelTreeNode root, List <Configuration> configurations)
        {
            htmlBuilder.Append("<h2>Details</h2>");
            htmlBuilder.Append("<table border='1' cellpadding='5'>"); htmlBuilder.Append("<tr style='background-color:wheat'><th>Features</th>");
            foreach (Configuration configuration in configurations)
            {
                htmlBuilder.Append("<th>" + configuration.ProductName + "</th>");
            }

            // no Total column if this report is being generated for only one configuration.
            if (configurations.Count > 1)
            {
                htmlBuilder.Append("<th>Total</th></tr>");
            }
            AppendRow(htmlBuilder, root, configurations, 0);
        }
示例#13
0
        /// <summary>
        /// Generates a configuration report from a one or more configurations. If the number of configurations
        /// is more than one, an additional "Total" column gets generated in the detailed report.
        /// </summary>
        /// <param name="outputFileName">The output HTML file name.</param>
        /// <param name="root">The root Confeaturator node.</param>
        /// <param name="configurations">The set of configurations from which the report will be generated.</param>
        internal static void GenerateReport(string outputFileName, FeatureModelTreeNode root, List<Configuration> configurations)
        {
            InitializeCounters();
            string configurationName = Path.GetFileNameWithoutExtension(outputFileName);
            StringBuilder htmlStart = new StringBuilder();
            StringBuilder htmlTable = new StringBuilder();
            AppendStart(htmlStart, configurations);
            AppendTable(htmlTable, root, configurations);
            AppendEnd(htmlTable);
            AppendSummary(htmlStart);

            htmlStart.Append(htmlTable.ToString());

            StreamWriter sr = new StreamWriter(outputFileName);
            sr.Write(htmlStart.ToString());
            sr.Close();
        }
示例#14
0
        /// <summary>
        /// Generates a configuration report from a one or more configurations. If the number of configurations
        /// is more than one, an additional "Total" column gets generated in the detailed report.
        /// </summary>
        /// <param name="outputFileName">The output HTML file name.</param>
        /// <param name="root">The root Confeaturator node.</param>
        /// <param name="configurations">The set of configurations from which the report will be generated.</param>
        internal static void GenerateReport(string outputFileName, FeatureModelTreeNode root, List <Configuration> configurations)
        {
            InitializeCounters();
            string        configurationName = Path.GetFileNameWithoutExtension(outputFileName);
            StringBuilder htmlStart         = new StringBuilder();
            StringBuilder htmlTable         = new StringBuilder();

            AppendStart(htmlStart, configurations);
            AppendTable(htmlTable, root, configurations);
            AppendEnd(htmlTable);
            AppendSummary(htmlStart);

            htmlStart.Append(htmlTable.ToString());

            StreamWriter sr = new StreamWriter(outputFileName);

            sr.Write(htmlStart.ToString());
            sr.Close();
        }
示例#15
0
 /// <summary>
 /// Creates or updates the Confeaturator tree.
 /// </summary>
 private void RefreshConfeaturatorTree()
 {
     try {
         SingleDiagramDocView   diagramDocView = DesignerHelper.GetDiagramDocView(serviceProvider);
         FeatureModelDSLDiagram diagram        = diagramDocView.CurrentDiagram as FeatureModelDSLDiagram;
         if (diagram != null)
         {
             FeatureModel featureModel = diagram.Subject as FeatureModel;
             if (featureModel != null)
             {
                 Feature rootFeature = FeatureModel.GetCrossDiagramRootFeature(featureModel);
                 trvFeatures.Nodes.Clear();
                 if (rootFeature != null)
                 {
                     addedFeatures = new List <string>();
                     FeatureModelTreeNode rootNode = CreateFeatureModelTreeNode(rootFeature);
                     trvFeatures.Nodes.Add(rootNode);
                     rootNode.Expand();
                     rootNode.Kind            = FeatureModelNodeKind.Root;
                     rootNode.Status          = FeatureModelNodeStatus.CheckedAndDisabled;
                     trvFeatures.SelectedNode = rootNode;
                 }
                 else
                 {
                     Util.ShowError("Feature model was loaded but root feature is null.");
                 }
             }
             else
             {
                 Util.ShowError("Could not load feature model into Confeaturator. Please ensure you have a valid feature model file opened.");
             }
         }
         else
         {
             Util.ShowError("Please have the feature model diagram you want to refresh into Confeaturator open and active in Visual Studio.");
         }
     } catch (Exception ex) {
         Util.ShowError("Error loading feature model into Confeaturator: " + ex.Message);
     }
 }
示例#16
0
        /// <summary>
        /// Generates a configuration report from a set of input configurations.
        /// </summary>
        /// <param name="ouputFileName">The HTML file where to generate the report.</param>
        /// <param name="inputFileNames">Input configuration (.confeaturator) files.</param>
        private void GenerateReport(string ouputFileName, params string[] inputFileNames)
        {
            List <Configuration> configurations = new List <Configuration>();

            bool generatedWithWarnings = false;

            foreach (string fileName in inputFileNames)
            {
                if (LoadConfiguration(fileName).Count > 0)
                {
                    generatedWithWarnings = true;
                }
                Dictionary <string, bool> configurationFeatures = new Dictionary <string, bool>();
                XmlSerializer             xmlSerializer         = new XmlSerializer(typeof(List <string>));
                FileStream    fs = new FileStream(fileName, FileMode.Open);
                List <string> checkedNodePaths = xmlSerializer.Deserialize(fs) as List <string>;
                fs.Close();
                foreach (string checkedNodePath in checkedNodePaths)
                {
                    FeatureModelTreeNode node = GetNodeFromFullPath(trvFeatures.Nodes, checkedNodePath);
                    if (node != null && node.IsPartOfConfiguration)
                    {
                        string[] featurePathItems = checkedNodePath.Split(new[] { trvFeatures.PathSeparator }, StringSplitOptions.RemoveEmptyEntries);
                        string   featureName      = featurePathItems[featurePathItems.Length - 1];
                        configurationFeatures[featureName] = true;
                    }
                }
                string configurationName = Path.GetFileNameWithoutExtension(fileName);
                configurations.Add(new Configuration {
                    ProductName = configurationName, Features = configurationFeatures
                });
            }
            ReportGenerator.GenerateReport(ouputFileName, trvFeatures.Nodes[0] as FeatureModelTreeNode, configurations);
            System.Diagnostics.Process.Start(ouputFileName);
            if (generatedWithWarnings)
            {
                Util.ShowWarning("Report generated, but one or more configurations seem to be out of sync with the feature model. Please re-check your configurations and save them to ensure everything is in sync.");
            }
        }
示例#17
0
        /// <summary>
        /// Appens a row to the Details table report to the specified StringBuilder.
        /// </summary>
        /// <param name="htmlFile">The HTML string builder.</param>
        /// <param name="node">The Confeaturator node from which the report row will be generated.</param>
        /// <param name="configurations">List of configurations.</param>
        /// <param name="identLevel">Identation level of the row.</param>
        private static void AppendRow(StringBuilder htmlFile, FeatureModelTreeNode node, List <Configuration> configurations, int identLevel)
        {
            StringBuilder blankSpaces = new StringBuilder();

            for (int i = 0; i < 5 * identLevel; i++)
            {
                blankSpaces.Append(blank);
            }

            string  nodeText      = node.Text;
            Feature feature       = node.FeatureModelElement as Feature;
            bool    isFeatureNode = false;

            if (feature != null)
            {
                isFeatureNode = true;
            }
            if (node.Kind == FeatureModelNodeKind.NotApply || node.Kind == FeatureModelNodeKind.Optional)
            {
                nodeText = "<i>" + nodeText + "</i>";
            }
            if (node.FeatureModelElement is Feature)
            {
                htmlFile.Append("<tr><td style='background-color:lightyellow'>" + blankSpaces + nodeText + "</td>");
            }
            else
            {
                int colsToSpan = configurations.Count + 1; // Total # of products + feature column
                if (configurations.Count > 1)
                {
                    colsToSpan++; // Adding "total" column
                }
                htmlFile.Append("<tr><td style='color:dimgray;background-color:lightyellow' colspan='" + colsToSpan + "'>" + blankSpaces + node.Text + "</td>");
            }

            int timesSelected = 0;

            foreach (Configuration configuration in configurations)
            {
                if (isFeatureNode)
                {
                    if (configuration.Features.Keys.Contains(feature.Name) && configuration.Features[feature.Name])
                    {
                        htmlFile.Append("<td style='text-align:center;background-color:" + selectedBackgroundColor + "'>&bull;</td>");
                        timesSelected++;
                    }
                    else
                    {
                        htmlFile.Append("<td>&nbsp;</td>");
                    }
                }
            }

            // "Total" column and counters
            if (isFeatureNode)
            {
                if (node.Kind == FeatureModelNodeKind.Root || node.Kind == FeatureModelNodeKind.Mandatory)
                {
                    totalRootMandatory++;
                }
                else if (node.Kind == FeatureModelNodeKind.NotApply || node.Kind == FeatureModelNodeKind.Optional)
                {
                    totalOptionalAlternative++;
                }

                if (timesSelected > 0)
                {
                    if (node.Kind == FeatureModelNodeKind.Root || node.Kind == FeatureModelNodeKind.Mandatory)
                    {
                        totalRootMandatorySelected++;
                    }
                    else if (node.Kind == FeatureModelNodeKind.NotApply || node.Kind == FeatureModelNodeKind.Optional)
                    {
                        totalOptionalAlternativeSelected++;
                    }

                    // "Total" columns
                    if (configurations.Count > 1)
                    {
                        htmlFile.Append("<td style='text-align:center;background-color:" + selectedBackgroundColor + "'>" + timesSelected + "</td>");
                    }
                }
                else
                {
                    // "Total" columns
                    if (configurations.Count > 1)
                    {
                        htmlFile.Append("<td style='text-align:center'>0</td>");
                    }
                }
            }

            htmlFile.Append("</tr>");

            foreach (FeatureModelTreeNode childNode in node.Nodes)
            {
                AppendRow(htmlFile, childNode, configurations, identLevel + 1);
            }
        }
示例#18
0
 /// <summary>
 /// Creates a ConfeaturatorActionProviderEventArgs instance.
 /// </summary>
 /// <param name="rootFeatureNode">The root feature model node.</param>
 /// <param name="serviceProvider">A service provider.</param>
 public ConfeaturatorActionProviderEventArgs(FeatureModelTreeNode rootFeatureNode, IServiceProvider serviceProvider)
 {
     RootFeatureNode = rootFeatureNode;
     ServiceProvider = serviceProvider;
     DTE             = serviceProvider.GetService(typeof(DTE)) as DTE;
 }
示例#19
0
        /// <summary>
        /// Appens a row to the Details table report to the specified StringBuilder.
        /// </summary>
        /// <param name="htmlFile">The HTML string builder.</param>
        /// <param name="node">The Confeaturator node from which the report row will be generated.</param>
        /// <param name="configurations">List of configurations.</param>
        /// <param name="identLevel">Identation level of the row.</param>
        private static void AppendRow(StringBuilder htmlFile, FeatureModelTreeNode node, List<Configuration> configurations, int identLevel)
        {
            StringBuilder blankSpaces = new StringBuilder();
            for (int i = 0; i < 5*identLevel; i++) {
                blankSpaces.Append(blank);
            }

            string nodeText = node.Text;
            Feature feature = node.FeatureModelElement as Feature;
            bool isFeatureNode = false;
            if (feature != null) {
                isFeatureNode = true;
            }
            if (node.Kind == FeatureModelNodeKind.NotApply || node.Kind == FeatureModelNodeKind.Optional) {
                nodeText = "<i>" + nodeText + "</i>";
            }
            if (node.FeatureModelElement is Feature) {
                htmlFile.Append("<tr><td style='background-color:lightyellow'>" + blankSpaces + nodeText + "</td>");
            } else {
                int colsToSpan = configurations.Count + 1; // Total # of products + feature column
                if (configurations.Count > 1) {
                    colsToSpan++; // Adding "total" column
                }
                htmlFile.Append("<tr><td style='color:dimgray;background-color:lightyellow' colspan='"+colsToSpan+"'>" + blankSpaces + node.Text + "</td>");
            }

            int timesSelected = 0;

            foreach (Configuration configuration in configurations) {
                if (isFeatureNode) {
                    if (configuration.Features.Keys.Contains(feature.Name) && configuration.Features[feature.Name]) {
                        htmlFile.Append("<td style='text-align:center;background-color:" + selectedBackgroundColor + "'>&bull;</td>");
                        timesSelected++;
                    } else {
                        htmlFile.Append("<td>&nbsp;</td>");
                    }
                }
            }

            // "Total" column and counters
            if (isFeatureNode) {
                if (node.Kind == FeatureModelNodeKind.Root || node.Kind == FeatureModelNodeKind.Mandatory) {
                    totalRootMandatory++;
                } else if (node.Kind == FeatureModelNodeKind.NotApply || node.Kind == FeatureModelNodeKind.Optional) {
                    totalOptionalAlternative++;
                }

                if (timesSelected > 0) {

                    if (node.Kind == FeatureModelNodeKind.Root || node.Kind == FeatureModelNodeKind.Mandatory) {
                        totalRootMandatorySelected++;
                    } else if (node.Kind == FeatureModelNodeKind.NotApply || node.Kind == FeatureModelNodeKind.Optional) {
                        totalOptionalAlternativeSelected++;
                    }

                    // "Total" columns
                    if (configurations.Count > 1) {
                        htmlFile.Append("<td style='text-align:center;background-color:" + selectedBackgroundColor + "'>" + timesSelected + "</td>");
                    }

                } else {

                    // "Total" columns
                    if (configurations.Count > 1) {
                        htmlFile.Append("<td style='text-align:center'>0</td>");
                    }
                }
            }

            htmlFile.Append("</tr>");

            foreach (FeatureModelTreeNode childNode in node.Nodes) {
                AppendRow(htmlFile, childNode, configurations, identLevel + 1);
            }
        }
 /// <summary>
 /// Recursively logs included features from a given Feature Model tree node into a list of features.
 /// </summary>
 /// <param name="node">The node from where to start the recursion.</param>
 /// <param name="result">A cumulative list of included features.</param>
 private void LogIncludedFeatures(FeatureModelTreeNode node, List<Feature> result)
 {
     Feature feature = node.FeatureModelElement as Feature;
     if (feature != null && node.IsPartOfConfiguration) {
         result.Add(feature);
     }
     foreach (FeatureModelTreeNode childNode in node.Nodes) {
         LogIncludedFeatures(childNode, result);
     }
 }
示例#21
0
 /// <summary>
 /// Creates a Confeaturator node.
 /// </summary>
 /// <param name="fmElement">Feature model element used to create the node.</param>
 /// <returns>The created Confeaturator node.</returns>
 private FeatureModelTreeNode CreateFeatureModelTreeNode(FeatureModelElement fmElement)
 {
     FeatureModelTreeNode node = new FeatureModelTreeNode(fmElement);
     AddChildFeatureModelNodes(node);
     node.AdjustFont(trvFeatures.Font);
     return node;
 }
示例#22
0
 /// <summary>
 /// Recursively logs the checked Confeaturator node paths into a list of paths.
 /// </summary>
 /// <param name="node">The node where to start the logging recursion.</param>
 /// <param name="checkedNodePaths">The cumulative list of strings where to log the checked node paths.</param>
 private void LogCheckedNodePaths(FeatureModelTreeNode node, List<string> checkedNodePaths)
 {
     if (node.IsChecked) {
         checkedNodePaths.Add(HttpUtility.HtmlEncode(node.FullPath));
     }
     foreach (FeatureModelTreeNode childNode in node.Nodes) {
         LogCheckedNodePaths(childNode, checkedNodePaths);
     }
 }
 /// <summary>
 /// Creates a ConfeaturatorActionProviderEventArgs instance.
 /// </summary>
 /// <param name="rootFeatureNode">The root feature model node.</param>
 /// <param name="serviceProvider">A service provider.</param>
 public ConfeaturatorActionProviderEventArgs(FeatureModelTreeNode rootFeatureNode, IServiceProvider serviceProvider)
 {
     RootFeatureNode = rootFeatureNode;
     ServiceProvider = serviceProvider;
     DTE = serviceProvider.GetService(typeof(DTE)) as DTE;
 }
示例#24
0
        /// <summary>
        /// Adds child Confeaturator nodes to a given node.
        /// </summary>
        /// <param name="node">The node to which children should be added.</param>
        private void AddChildFeatureModelNodes(FeatureModelTreeNode node)
        {
            FeatureModelElement fmElement = node.FeatureModelElement;
            foreach (FeatureModelElement childFMElement in fmElement.SubFeatureModelElements) {
                node.Nodes.Add(CreateFeatureModelTreeNode(childFMElement));
            }

            // cross-feature model logic
            Feature feature = fmElement as Feature;
            if (feature != null) {
                if (feature.IsReference && !addedFeatures.Contains(feature.Name)) {
                    FeatureModel definitionFeatureModel = Util.LoadFeatureModel(DTEHelper.GetFullProjectItemPath(feature.DefinitionFeatureModelFile));
                    Feature definitionFeature = definitionFeatureModel.GetFeature(feature.Name);
                    if (definitionFeature != null) {
                        foreach (FeatureModelElement childFMElement in definitionFeature.SubFeatureModelElements) {
                            node.Nodes.Add(CreateFeatureModelTreeNode(childFMElement));
                        }
                    }
                }
                addedFeatures.Add(feature.Name);
            }
        }