Example #1
0
        /// <summary>
        /// Process the complex references.
        /// </summary>
        /// <param name="output">Active output to add sections to.</param>
        /// <param name="sections">Sections that are referenced during the link process.</param>
        /// <param name="referencedSymbols">Collection of all symbols referenced during linking.</param>
        /// <param name="componentsToComponentGroupsComplexReferences">Component to ComponentGroup complex references.</param>
        /// <param name="componentGroupsToFeatures">ComponentGroups to features complex references.</param>
        /// <param name="componentGroupsToModules">ComponentGroups to modules complex references.</param>
        /// <param name="componentsToFeatures">Component to feature complex references.</param>
        /// <param name="featuresToFeatures">Feature to feature complex references.</param>
        private void ProcessComplexReferences(
			Output output,
			SectionCollection sections,
			StringCollection referencedSymbols,
			ComplexReferenceCollection componentsToComponentGroupsComplexReferences,
			ConnectToFeatureCollection componentGroupsToFeatures,
			ConnectToModuleCollection componentGroupsToModules,
			ConnectToFeatureCollection componentsToFeatures,
			ConnectToFeatureCollection featuresToFeatures)
        {
            Hashtable componentsToModules = new Hashtable();

            foreach (Section section in sections)
            {
                foreach (ComplexReference cref in section.ComplexReferences)
                {
                    ConnectToFeature connection;
                    switch (cref.ParentType)
                    {
                        case ComplexReferenceParentType.ComponentGroup:
                        switch (cref.ChildType)
                        {
                            case ComplexReferenceChildType.Component:
                                componentsToComponentGroupsComplexReferences.Add(cref);
                                break;
                            default:
                                throw new ApplicationException("Unexpected complex reference child type."); // TODO: come up with a real exception to throw (Unexpected complex reference child type)
                        }
                            break;
                        case ComplexReferenceParentType.Feature:
                        switch (cref.ChildType)
                        {
                            case ComplexReferenceChildType.Component:
                                connection = componentsToFeatures[cref.ChildId];
                                if (null == connection)
                                {
                                    componentsToFeatures.Add(new ConnectToFeature(section, cref.ChildId, cref.ParentId, cref.IsPrimary));
                                }
                                else if (cref.IsPrimary && connection.IsExplicitPrimaryFeature)
                                {
                                    this.OnMessage(WixErrors.MultiplePrimaryReferences(SourceLineNumberCollection.FromFileName(section.Intermediate.Path), cref.ChildType.ToString(), cref.ChildId, cref.ParentId, connection.PrimaryFeature));
                                    continue;
                                }
                                else if (cref.IsPrimary)
                                {
                                    connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects
                                    connection.PrimaryFeature = cref.ParentId; // set the new primary feature
                                    connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
                                }
                                else
                                {
                                    connection.ConnectFeatures.Add(cref.ParentId);
                                }

                                // add a row to the FeatureComponents table
                                Row row = Common.CreateRowInSection(null, section, this.tableDefinitions["FeatureComponents"]);
                                if (this.sectionIdOnTuples)
                                {
                                    row.SectionId = section.Id;
                                }
                                row[0] = cref.ParentId;
                                row[1] = cref.ChildId;

                                // index the component for finding orphaned records
                                string symbolName = String.Concat("Component:", cref.ChildId);
                                if (!referencedSymbols.Contains(symbolName))
                                {
                                    referencedSymbols.Add(symbolName);
                                }

                                break;
                            case ComplexReferenceChildType.ComponentGroup:
                                connection = componentGroupsToFeatures[cref.ChildId];
                                if (null == connection)
                                {
                                    componentGroupsToFeatures.Add(new ConnectToFeature(section, cref.ChildId, cref.ParentId, cref.IsPrimary));
                                }
                                else if (cref.IsPrimary && connection.IsExplicitPrimaryFeature)
                                {
                                    this.OnMessage(WixErrors.MultiplePrimaryReferences(SourceLineNumberCollection.FromFileName(section.Intermediate.Path), cref.ChildType.ToString(), cref.ChildId, cref.ParentId, connection.PrimaryFeature));
                                    continue;
                                }
                                else if (cref.IsPrimary)
                                {
                                    connection.ConnectFeatures.Add(connection.PrimaryFeature);
                                    connection.PrimaryFeature = cref.ParentId;
                                    connection.IsExplicitPrimaryFeature = true;
                                }
                                else
                                {
                                    connection.ConnectFeatures.Add(cref.ParentId);
                                }
                                break;

                            case ComplexReferenceChildType.Feature:
                                connection = featuresToFeatures[cref.ChildId];
                                if (null != connection)
                                {
                                    this.OnMessage(WixErrors.MultiplePrimaryReferences(SourceLineNumberCollection.FromFileName(section.Intermediate.Path), cref.ChildType.ToString(), cref.ChildId, cref.ParentId, connection.PrimaryFeature));
                                    continue;
                                }

                                featuresToFeatures.Add(new ConnectToFeature(section, cref.ChildId, cref.ParentId, cref.IsPrimary));
                                break;

                            case ComplexReferenceChildType.Module:
                                connection = output.ModulesToFeatures[cref.ChildId];
                                if (null == connection)
                                {
                                    output.ModulesToFeatures.Add(new ConnectToFeature(section, cref.ChildId, cref.ParentId, cref.IsPrimary));
                                }
                                else if (cref.IsPrimary && connection.IsExplicitPrimaryFeature)
                                {
                                    this.OnMessage(WixErrors.MultiplePrimaryReferences(SourceLineNumberCollection.FromFileName(section.Intermediate.Path), cref.ChildType.ToString(), cref.ChildId, cref.ParentId, connection.PrimaryFeature));
                                    continue;
                                }
                                else if (cref.IsPrimary)
                                {
                                    connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects
                                    connection.PrimaryFeature = cref.ParentId; // set the new primary feature
                                    connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
                                }
                                else
                                {
                                    connection.ConnectFeatures.Add(cref.ParentId);
                                }
                                break;

                            default:
                                throw new ApplicationException("Unexpected complex reference child type"); // TODO: come up with a real exception to throw (Unexpected complex reference child type)
                        }
                            break;

                        case ComplexReferenceParentType.Module:
                        switch (cref.ChildType)
                        {
                            case ComplexReferenceChildType.Component:
                                if (componentsToModules.ContainsKey(cref.ChildId))
                                {
                                    this.OnMessage(WixErrors.ComponentReferencedTwice(SourceLineNumberCollection.FromFileName(section.Intermediate.Path), cref.ChildId));
                                    continue;
                                }
                                else
                                {
                                    componentsToModules.Add(cref.ChildId, cref); // should always be new

                                    // add a row to the ModuleComponents table
                                    Row row = Common.CreateRowInSection(null, section, this.tableDefinitions["ModuleComponents"]);
                                    if (this.sectionIdOnTuples)
                                    {
                                        row.SectionId = section.Id;
                                    }
                                    row[0] = cref.ChildId;
                                    row[1] = cref.ParentId;
                                    row[2] = cref.ParentLanguage;
                                }

                                // index the component for finding orphaned records
                                string componentSymbolName = String.Concat("Component:", cref.ChildId);
                                if (!referencedSymbols.Contains(componentSymbolName))
                                {
                                    referencedSymbols.Add(componentSymbolName);
                                }

                                break;

                            case ComplexReferenceChildType.ComponentGroup:
                                ConnectToModule moduleConnection = componentGroupsToModules[cref.ChildId];
                                if (null == moduleConnection)
                                {
                                    componentGroupsToModules.Add(new ConnectToModule(cref.ChildId, cref.ParentId, cref.ParentLanguage));
                                }
                                break;

                            default:
                                throw new ApplicationException("Unexpected complex reference child type"); // TODO: come up with a real exception to throw (Unexpected complex reference child type)
                        }
                            break;
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Resolve component groups.
        /// </summary>
        /// <param name="output">Active output to add sections to.</param>
        /// <param name="referencedSymbols">Collection of all symbols referenced during linking.</param>
        /// <param name="componentsToComponentGroupsComplexReferences">Component to ComponentGroup complex references.</param>
        /// <param name="componentGroupsToFeatures">ComponentGroups to features complex references.</param>
        /// <param name="componentGroupsToModules">ComponentGroups to modules complex references.</param>
        /// <param name="componentsToFeatures">Component to feature complex references.</param>
        private void ResolveComponentGroups(
			Output output,
			StringCollection referencedSymbols,
			ComplexReferenceCollection componentsToComponentGroupsComplexReferences,
			ConnectToFeatureCollection componentGroupsToFeatures,
			ConnectToModuleCollection componentGroupsToModules,
			ConnectToFeatureCollection componentsToFeatures)
        {
            foreach (ComplexReference cref in componentsToComponentGroupsComplexReferences)
            {
                // only connect a Component to a Feature if the ComponentGroup is connected to a Feature
                ConnectToFeature connectComponentGroupToFeature = componentGroupsToFeatures[cref.ParentId];
                if (null != connectComponentGroupToFeature)
                {
                    // create a list of all features (use an ArrayList because StringCollection lacks an AddRange method that takes an ICollection)
                    ArrayList features = new ArrayList(connectComponentGroupToFeature.ConnectFeatures);
                    features.Add(connectComponentGroupToFeature.PrimaryFeature);

                    foreach (string feature in features)
                    {
                        ConnectToFeature connectComponentToFeature = componentsToFeatures[cref.ChildId];
                        bool isExplicitPrimaryFeature = (connectComponentGroupToFeature.IsExplicitPrimaryFeature && (connectComponentGroupToFeature.PrimaryFeature == feature));

                        if (null == connectComponentToFeature)
                        {
                            componentsToFeatures.Add(new ConnectToFeature(connectComponentGroupToFeature.Section, cref.ChildId, feature, isExplicitPrimaryFeature));
                        }
                        else if (isExplicitPrimaryFeature && connectComponentToFeature.IsExplicitPrimaryFeature && feature != connectComponentToFeature.PrimaryFeature)
                        {
                            this.OnMessage(WixErrors.MultiplePrimaryReferences(SourceLineNumberCollection.FromFileName(connectComponentToFeature.Section.Intermediate.Path), cref.ChildType.ToString(), cref.ChildId, cref.ParentId, feature));
                            continue;
                        }
                        else if (isExplicitPrimaryFeature)
                        {
                            connectComponentToFeature.ConnectFeatures.Add(connectComponentToFeature.PrimaryFeature); // move the guessed primary feature to the list of connects
                            connectComponentToFeature.PrimaryFeature = feature; // set the new primary feature
                            connectComponentToFeature.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
                        }
                        else
                        {
                            connectComponentToFeature.ConnectFeatures.Add(feature);
                        }

                        // add a row to the FeatureComponents table
                        Row row = Common.CreateRowInSection(null, output.EntrySection, this.tableDefinitions["FeatureComponents"]);
                        row[0] = feature;
                        row[1] = cref.ChildId;

                        // index the component for finding orphaned records
                        Reference reference = new Reference("Component", cref.ChildId);
                        if (!referencedSymbols.Contains(reference.SymbolicName))
                        {
                            referencedSymbols.Add(reference.SymbolicName);
                        }
                    }
                }

                // only connect a Component to a Module if the ComponentGroup is connected to a Module
                ConnectToModule connectComponentGroupToModule = componentGroupsToModules[cref.ParentId];
                if (null != connectComponentGroupToModule)
                {
                    // add a row to the ModuleComponents table
                    Row row = Common.CreateRowInSection(null, output.EntrySection, this.tableDefinitions["ModuleComponents"]);
                    row[0] = cref.ChildId;
                    row[1] = connectComponentGroupToModule.Module;
                    row[2] = connectComponentGroupToModule.ModuleLanguage;

                    // index the component for finding orphaned records
                    Reference reference = new Reference("Component", cref.ChildId);
                    if (!referencedSymbols.Contains(reference.SymbolicName))
                    {
                        referencedSymbols.Add(reference.SymbolicName);
                    }
                }
            }
        }
Example #3
0
File: Linker.cs Project: zooba/wix3
        /// <summary>
        /// Process the complex references.
        /// </summary>
        /// <param name="output">Active output to add sections to.</param>
        /// <param name="sections">Sections that are referenced during the link process.</param>
        /// <param name="referencedSymbols">Collection of all symbols referenced during linking.</param>
        /// <param name="componentsToFeatures">Component to feature complex references.</param>
        /// <param name="featuresToFeatures">Feature to feature complex references.</param>
        /// <param name="modulesToFeatures">Module to feature complex references.</param>
        private void ProcessComplexReferences(
            Output output,
            SectionCollection sections,
            StringCollection referencedSymbols,
            ConnectToFeatureCollection componentsToFeatures,
            ConnectToFeatureCollection featuresToFeatures,
            ConnectToFeatureCollection modulesToFeatures)
        {
            Hashtable componentsToModules = new Hashtable();

            foreach (Section section in sections)
            {
                Table wixComplexReferenceTable = section.Tables["WixComplexReference"];

                if (null != wixComplexReferenceTable)
                {
                    foreach (WixComplexReferenceRow wixComplexReferenceRow in wixComplexReferenceTable.Rows)
                    {
                        ConnectToFeature connection;
                        switch (wixComplexReferenceRow.ParentType)
                        {
                            case ComplexReferenceParentType.Feature:
                                switch (wixComplexReferenceRow.ChildType)
                                {
                                    case ComplexReferenceChildType.Component:
                                        connection = componentsToFeatures[wixComplexReferenceRow.ChildId];
                                        if (null == connection)
                                        {
                                            componentsToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentId, wixComplexReferenceRow.IsPrimary));
                                        }
                                        else if (wixComplexReferenceRow.IsPrimary)
                                        {
                                            if (connection.IsExplicitPrimaryFeature)
                                            {
                                                this.OnMessage(WixErrors.MultiplePrimaryReferences(section.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.ParentId, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : this.activeOutput.EntrySection.Id)));
                                                continue;
                                            }
                                            else
                                            {
                                                connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects
                                                connection.PrimaryFeature = wixComplexReferenceRow.ParentId; // set the new primary feature
                                                connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
                                            }
                                        }
                                        else
                                        {
                                            connection.ConnectFeatures.Add(wixComplexReferenceRow.ParentId);
                                        }

                                        // add a row to the FeatureComponents table
                                        Table featureComponentsTable = output.EnsureTable(this.tableDefinitions["FeatureComponents"]);
                                        Row row = featureComponentsTable.CreateRow(null);
                                        if (this.sectionIdOnRows)
                                        {
                                            row.SectionId = section.Id;
                                        }
                                        row[0] = wixComplexReferenceRow.ParentId;
                                        row[1] = wixComplexReferenceRow.ChildId;

                                        // index the component for finding orphaned records
                                        string symbolName = String.Concat("Component:", wixComplexReferenceRow.ChildId);
                                        if (!referencedSymbols.Contains(symbolName))
                                        {
                                            referencedSymbols.Add(symbolName);
                                        }

                                        break;

                                    case ComplexReferenceChildType.Feature:
                                        connection = featuresToFeatures[wixComplexReferenceRow.ChildId];
                                        if (null != connection)
                                        {
                                            this.OnMessage(WixErrors.MultiplePrimaryReferences(section.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.ParentId, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : this.activeOutput.EntrySection.Id)));
                                            continue;
                                        }

                                        featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentId, wixComplexReferenceRow.IsPrimary));
                                        break;

                                    case ComplexReferenceChildType.Module:
                                        connection = modulesToFeatures[wixComplexReferenceRow.ChildId];
                                        if (null == connection)
                                        {
                                            modulesToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentId, wixComplexReferenceRow.IsPrimary));
                                        }
                                        else if (wixComplexReferenceRow.IsPrimary)
                                        {
                                            if (connection.IsExplicitPrimaryFeature)
                                            {
                                                this.OnMessage(WixErrors.MultiplePrimaryReferences(section.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.ParentId, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : this.activeOutput.EntrySection.Id)));
                                                continue;
                                            }
                                            else
                                            {
                                                connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects
                                                connection.PrimaryFeature = wixComplexReferenceRow.ParentId; // set the new primary feature
                                                connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
                                            }
                                        }
                                        else
                                        {
                                            connection.ConnectFeatures.Add(wixComplexReferenceRow.ParentId);
                                        }
                                        break;

                                    default:
                                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
                                }
                                break;

                            case ComplexReferenceParentType.Module:
                                switch (wixComplexReferenceRow.ChildType)
                                {
                                    case ComplexReferenceChildType.Component:
                                        if (componentsToModules.ContainsKey(wixComplexReferenceRow.ChildId))
                                        {
                                            this.OnMessage(WixErrors.ComponentReferencedTwice(section.SourceLineNumbers, wixComplexReferenceRow.ChildId));
                                            continue;
                                        }
                                        else
                                        {
                                            componentsToModules.Add(wixComplexReferenceRow.ChildId, wixComplexReferenceRow); // should always be new

                                            // add a row to the ModuleComponents table
                                            Table moduleComponentsTable = output.EnsureTable(this.tableDefinitions["ModuleComponents"]);
                                            Row row = moduleComponentsTable.CreateRow(null);
                                            if (this.sectionIdOnRows)
                                            {
                                                row.SectionId = section.Id;
                                            }
                                            row[0] = wixComplexReferenceRow.ChildId;
                                            row[1] = wixComplexReferenceRow.ParentId;
                                            row[2] = wixComplexReferenceRow.ParentLanguage;
                                        }

                                        // index the component for finding orphaned records
                                        string componentSymbolName = String.Concat("Component:", wixComplexReferenceRow.ChildId);
                                        if (!referencedSymbols.Contains(componentSymbolName))
                                        {
                                            referencedSymbols.Add(componentSymbolName);
                                        }

                                        break;

                                    default:
                                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
                                }
                                break;

                            case ComplexReferenceParentType.Patch:
                                switch(wixComplexReferenceRow.ChildType)
                                {
                                    case ComplexReferenceChildType.PatchFamily:
                                    case ComplexReferenceChildType.PatchFamilyGroup:
                                        break;

                                    default:
                                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
                                }
                                break;

                            case ComplexReferenceParentType.Product:
                                switch (wixComplexReferenceRow.ChildType)
                                {
                                    case ComplexReferenceChildType.Feature:
                                        connection = featuresToFeatures[wixComplexReferenceRow.ChildId];
                                        if (null != connection)
                                        {
                                            this.OnMessage(WixErrors.MultiplePrimaryReferences(section.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.ChildId, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.ParentId, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : this.activeOutput.EntrySection.Id)));
                                            continue;
                                        }

                                        featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.ChildId, null, wixComplexReferenceRow.IsPrimary));
                                        break;

                                    default:
                                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
                                }
                                break;

                            default:
                                // Note: Groups have been processed before getting here so they are not handled by any case above.
                                throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, WixStrings.EXP_UnexpectedComplexReferenceChildType, Enum.GetName(typeof(ComplexReferenceParentType), wixComplexReferenceRow.ParentType)));
                        }
                    }
                }
            }
        }