/// <summary> /// Creates a new action table object and populates it from an Xml reader. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <returns>The parsed ActionTable.</returns> private static WixActionRowCollection Parse(XmlReader reader) { Debug.Assert("actions" == reader.LocalName); WixActionRowCollection actionRows = new WixActionRowCollection(); bool empty = reader.IsEmptyElement; // there are no legal attributes while (reader.MoveToNextAttribute()) { if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal)) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumber.CreateFromUri(reader.BaseURI), "actions", reader.Name)); } } if (!empty) { bool done = false; // loop through all the fields in a row while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: switch (reader.LocalName) { case "action": WixActionRow[] parsedActionRows = WixActionRow.Parse(reader); foreach (WixActionRow actionRow in parsedActionRows) { actionRows.Add(actionRow); } break; default: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumber.CreateFromUri(reader.BaseURI), "actions", reader.Name)); } break; case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumber.CreateFromUri(reader.BaseURI), "actions")); } } return(actionRows); }
/// <summary> /// Add an ActionRow to the collection. /// </summary> /// <param name="actionRow">The ActionRow to add.</param> /// <param name="overwrite">true to overwrite an existing ActionRow; false otherwise.</param> public void Add(WixActionRow actionRow, bool overwrite) { string key = GetKey(actionRow.SequenceTable, actionRow.Action); if (overwrite) { this.collection[key] = actionRow; } else { this.collection.Add(key, actionRow); } }
/// <summary> /// Add a row to the <paramref name="index"/> using the primary key. /// </summary> /// <param name="index">The indexed rows.</param> /// <param name="row">The row to index.</param> private void AddIndexedRow(IDictionary index, Row row) { string primaryKey = row.GetPrimaryKey('/'); if (null != primaryKey) { // Overriding WixActionRows have a primary key defined and take precedence in the index. if (row is WixActionRow) { WixActionRow currentRow = (WixActionRow)row; if (index.Contains(primaryKey)) { // If the current row is not overridable, see if the indexed row is. if (!currentRow.Overridable) { WixActionRow indexedRow = index[primaryKey] as WixActionRow; if (null != indexedRow && indexedRow.Overridable) { // The indexed key is overridable and should be replaced // (not removed and re-added which results in two Array.Copy // operations for SortedList, or may be re-hashing in other // implementations of IDictionary). index[primaryKey] = currentRow; } } // If we got this far, the row does not need to be indexed. return; } } // Nothing else should be added more than once. if (!index.Contains(primaryKey)) { index.Add(primaryKey, row); } else if (this.showPedanticMessages) { this.OnMessage(WixWarnings.DuplicatePrimaryKey(row.SourceLineNumbers, primaryKey, row.Table.Name)); } } else // use the string representation of the row as its primary key (it may not be unique) { // this is provided for compatibility with unreal tables with no primary key // all real tables must specify at least one column as the primary key primaryKey = row.ToString(); index[primaryKey] = row; } }
/// <summary> /// Determines whether this ActionRow contains the specified ActionRow as a child in its dependency tree. /// </summary> /// <param name="actionRow">The possible child ActionRow.</param> /// <returns>true if the ActionRow is a child of this ActionRow; false otherwise.</returns> internal bool ContainsChildActionRow(WixActionRow actionRow) { if (null != this.previousActionRows) { if (this.previousActionRows.Contains(actionRow.SequenceTable, actionRow.Action)) { return(true); } } if (null != this.nextActionRows) { if (this.nextActionRows.Contains(actionRow.SequenceTable, actionRow.Action)) { return(true); } } return(false); }
/// <summary> /// Instantiates an ActionRow by copying data from another ActionRow. /// </summary> /// <param name="source">The row the data is copied from.</param> /// <remarks>The previous and next action collections are not copied.</remarks> private WixActionRow(WixActionRow source) : base(source) { }
/// <summary> /// Parses ActionRows from the Xml reader. /// </summary> /// <param name="reader">Xml reader that contains serialized ActionRows.</param> /// <returns>The parsed ActionRows.</returns> internal static WixActionRow[] Parse(XmlReader reader) { Debug.Assert("action" == reader.LocalName); string id = null; string condition = null; bool empty = reader.IsEmptyElement; int sequence = int.MinValue; int sequenceCount = 0; SequenceTable[] sequenceTables = new SequenceTable[Enum.GetValues(typeof(SequenceTable)).Length]; while (reader.MoveToNextAttribute()) { switch (reader.Name) { case "name": id = reader.Value; break; case "AdminExecuteSequence": if (Common.IsYes(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", reader.Name, reader.Value)) { sequenceTables[sequenceCount] = SequenceTable.AdminExecuteSequence; ++sequenceCount; } break; case "AdminUISequence": if (Common.IsYes(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", reader.Name, reader.Value)) { sequenceTables[sequenceCount] = SequenceTable.AdminUISequence; ++sequenceCount; } break; case "AdvtExecuteSequence": if (Common.IsYes(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", reader.Name, reader.Value)) { sequenceTables[sequenceCount] = SequenceTable.AdvtExecuteSequence; ++sequenceCount; } break; case "condition": condition = reader.Value; break; case "InstallExecuteSequence": if (Common.IsYes(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", reader.Name, reader.Value)) { sequenceTables[sequenceCount] = SequenceTable.InstallExecuteSequence; ++sequenceCount; } break; case "InstallUISequence": if (Common.IsYes(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", reader.Name, reader.Value)) { sequenceTables[sequenceCount] = SequenceTable.InstallUISequence; ++sequenceCount; } break; case "sequence": sequence = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal)) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", reader.Name)); } break; } } if (null == id) { throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", "name")); } if (int.MinValue == sequence) { throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", "sequence")); } else if (1 > sequence) { throw new WixException(WixErrors.IntegralValueOutOfRange(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", "sequence", sequence, 1, int.MaxValue)); } if (0 == sequenceCount) { throw new WixException(WixErrors.ExpectedAttributes(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", "AdminExecuteSequence", "AdminUISequence", "AdvtExecuteSequence", "InstallExecuteSequence", "InstallUISequence")); } if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent()) { throw new WixException(WixErrors.UnexpectedContentNode(SourceLineNumber.CreateFromUri(reader.BaseURI), "action", reader.NodeType.ToString())); } // create the actions WixActionRow[] actionRows = new WixActionRow[sequenceCount]; for (int i = 0; i < sequenceCount; i++) { WixActionRow actionRow = new WixActionRow(sequenceTables[i], id, condition, sequence); actionRows[i] = actionRow; } return(actionRows); }
/// <summary> /// Compares the current instance with another object of the same type. /// </summary> /// <param name="obj">Other reference to compare this one to.</param> /// <returns>Returns less than 0 for less than, 0 for equals, and greater than 0 for greater.</returns> public int CompareTo(object obj) { WixActionRow otherActionRow = (WixActionRow)obj; return(this.Sequence.CompareTo(otherActionRow.Sequence)); }
/// <summary> /// Add an ActionRow to the collection. /// </summary> /// <param name="actionRow">The ActionRow to add.</param> public void Add(WixActionRow actionRow) { this.Add(actionRow, false); }
/// <summary> /// Creates a new row in the table. /// </summary> /// <param name="sourceLineNumbers">Original source lines for this row.</param> /// <param name="add">Specifies whether to only create the row or add it to the table automatically.</param> /// <returns>Row created in table.</returns> public Row CreateRow(SourceLineNumber sourceLineNumbers, bool add) { Row row; switch (this.Name) { case "BBControl": row = new BBControlRow(sourceLineNumbers, this); break; case "ChainMsiPackage": row = new ChainMsiPackageRow(sourceLineNumbers, this); break; case "Component": row = new ComponentRow(sourceLineNumbers, this); break; case "Control": row = new ControlRow(sourceLineNumbers, this); break; case "File": row = new FileRow(sourceLineNumbers, this); break; case "Media": row = new MediaRow(sourceLineNumbers, this); break; case "PayloadInfo": row = new PayloadInfoRow(sourceLineNumbers, this); break; case "Upgrade": row = new UpgradeRow(sourceLineNumbers, this); break; case "Variable": row = new VariableRow(sourceLineNumbers, this); break; case "WixAction": row = new WixActionRow(sourceLineNumbers, this); break; case "WixComplexReference": row = new WixComplexReferenceRow(sourceLineNumbers, this); break; case "WixFile": row = new WixFileRow(sourceLineNumbers, this); break; case "WixMedia": row = new WixMediaRow(sourceLineNumbers, this); break; case "WixMediaTemplate": row = new WixMediaTemplateRow(sourceLineNumbers, this); break; case "WixMerge": row = new WixMergeRow(sourceLineNumbers, this); break; case "WixProperty": row = new WixPropertyRow(sourceLineNumbers, this); break; case "WixBundle": row = new WixBundleRow(sourceLineNumbers, this); break; case "WixBundlePatchTargetCode": row = new WixBundlePatchTargetCodeRow(sourceLineNumbers, this); break; case "WixBundleUpdate": row = new WixBundleUpdateRow(sourceLineNumbers, this); break; case "WixUpdateRegistration": row = new WixUpdateRegistrationRow(sourceLineNumbers, this); break; case "WixSimpleReference": row = new WixSimpleReferenceRow(sourceLineNumbers, this); break; case "WixVariable": row = new WixVariableRow(sourceLineNumbers, this); break; default: row = new Row(sourceLineNumbers, this); break; } if (add) { this.rows.Add(row); } return(row); }