2 // BuildPropertyGroup.cs: Represents a group of properties
5 // Marek Sieradzki (marek.sieradzki@gmail.com)
7 // (C) 2005 Marek Sieradzki
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Collections;
30 using System.Reflection;
34 namespace Microsoft.Build.BuildEngine {
35 public class BuildPropertyGroup : ItemPropertyGroupingBase, IBuildPropertyGroup, IEnumerable {
37 XmlElement propertyGroup;
38 XmlAttribute condition;
39 string importedFromFilename;
41 GroupingCollection parentCollection;
42 Project parentProject;
44 IDictionary propertiesByName;
46 public BuildPropertyGroup ()
51 internal BuildPropertyGroup (bool forXml, Project project)
53 this.propertyGroup = null;
54 this.condition = null;
55 this.importedFromFilename = null;
56 this.isImported = false;
57 this.parentCollection = null;
58 this.parentProject = project;
60 this.properties = new ArrayList ();
62 this.propertiesByName = new Hashtable (new CaseInsensitiveHashCodeProvider(), new CaseInsensitiveComparer ());
65 public BuildProperty AddNewProperty (string propertyName,
68 return AddNewProperty (propertyName, propertyValue,
72 internal BuildProperty AddNewProperty (string propertyName,
74 PropertyType propertyType)
76 BuildProperty added, existing;
78 added = new BuildProperty (propertyName, propertyValue);
79 added.PropertyType = propertyType;
80 if (properties != null) {
81 properties.Add (added);
82 } else if (propertiesByName != null) {
83 if (propertiesByName.Contains (propertyName) == true) {
84 existing = (BuildProperty) propertiesByName [added.Name];
85 if (added.PropertyType <= existing.PropertyType) {
86 propertiesByName.Remove (added.Name);
87 propertiesByName.Add (added.Name, added);
90 propertiesByName.Add (added.Name, added);
93 throw new Exception ("PropertyGroup is not initialized.");
97 internal void AddFromExistingProperty (BuildProperty buildProperty)
99 BuildProperty added, existing;
101 added = buildProperty.Clone (false);
102 if (propertiesByName.Contains (added.Name) == true) {
103 existing = (BuildProperty) propertiesByName [added.Name];
104 if (added.PropertyType <= existing.PropertyType) {
105 propertiesByName.Remove (added.Name);
106 propertiesByName.Add (added.Name, added);
109 propertiesByName.Add (added.Name, added);
116 public BuildPropertyGroup Clone (bool deepClone)
121 // FIXME: what it is doing?
122 public override void Evaluate (BuildPropertyGroup evaluatedPropertyBag,
123 bool ignoreCondition,
125 Hashtable conditionedPropertiesTable,
130 public IEnumerator GetEnumerator ()
132 if (properties != null)
133 foreach (BuildProperty bp in properties)
135 else if (propertiesByName != null)
136 foreach (DictionaryEntry de in propertiesByName)
137 yield return (BuildProperty) de.Value;
139 throw new Exception ("PropertyGroup is not initialized.");
142 public void GetStringArraysForAllProperties (out string[] propertyNames,
143 out string[] propertyValues,
144 out string[] propertyFinalValues)
146 propertyNames = null;
147 propertyValues = null;
148 propertyFinalValues = null;
150 if (properties != null) {
151 foreach (BuildProperty bp in properties) {
152 propertyNames [i] = bp.Name;
153 propertyValues [i] = bp.Value;
154 propertyFinalValues [i] = bp.FinalValue;
157 } else if (propertiesByName != null) {
158 foreach (DictionaryEntry de in propertiesByName) {
159 propertyNames [i] = ((BuildProperty) de.Value).Name;
160 propertyValues [i] = ((BuildProperty) de.Value).Value;
161 propertyFinalValues [i] = ((BuildProperty) de.Value).FinalValue;
167 public void RemoveProperty (BuildProperty propertyToRemove)
169 if (properties == null)
170 throw new Exception ("PropertyGroup is not initialized.");
171 properties.Remove (propertyToRemove);
174 public void RemovePropertyByName (string propertyNameToRemove)
176 if (propertiesByName == null)
177 throw new Exception ("PropertyGroup is not initialized.");
178 propertiesByName.Remove (propertyNameToRemove);
181 public void SetProperty (string propertyName,
182 string propertyValue)
184 if (propertiesByName.Contains (propertyName) == false) {
185 AddNewProperty (propertyName, propertyValue);
187 ((BuildProperty) propertiesByName [propertyName]).Value = propertyValue;
190 internal void BindToXml (XmlElement propertyGroupElement)
192 if (propertyGroupElement == null)
193 throw new ArgumentNullException ();
194 this.properties = new ArrayList ();
195 this.propertyGroup = propertyGroupElement;
196 this.condition = propertyGroupElement.GetAttributeNode ("Condition");
197 this.importedFromFilename = null;
198 this.isImported = false;
199 foreach (XmlElement xe in propertyGroupElement.ChildNodes) {
200 BuildProperty bp = AddNewProperty(xe.Name, xe.InnerText);
201 bp.PropertyType = PropertyType.Normal;
203 Expression finalValue = new Expression (parentProject, bp.Value);
204 bp.FinalValue = (string) finalValue.ToNonArray (typeof (string));
205 parentProject.EvaluatedProperties.AddFromExistingProperty (bp);
209 public string Condition {
211 if (condition == null)
214 return condition.Value;
217 if (condition != null)
218 condition.Value = value;
224 if (properties != null)
225 return properties.Count;
226 else if (propertiesByName != null)
227 return propertiesByName.Count;
229 throw new Exception ("PropertyGroup is not initialized.");
233 public string ImportedFromFilename {
235 return importedFromFilename;
239 public bool IsImported {
245 public BuildProperty this[string propertyName] {
247 if (propertiesByName.Contains (propertyName)) {
248 return (BuildProperty) propertiesByName [propertyName];
254 propertiesByName [propertyName] = value;
258 internal GroupingCollection GroupingCollection {
259 get { return parentCollection; }
260 set { parentCollection = value; }