2005-09-19 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / BuildPropertyGroup.cs
1 //
2 // BuildPropertyGroup.cs: Represents a group of properties
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 // 
7 // (C) 2005 Marek Sieradzki
8 //
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
27
28 using System;
29 using System.Collections;
30 using System.Reflection;
31 using System.Text;
32 using System.Xml;
33
34 namespace Microsoft.Build.BuildEngine {
35         public class BuildPropertyGroup : ItemPropertyGroupingBase, IBuildPropertyGroup, IEnumerable {
36         
37                 XmlElement              propertyGroup;
38                 XmlAttribute            condition;
39                 string                  importedFromFilename;
40                 bool                    isImported;
41                 GroupingCollection      parentCollection;
42                 Project                 parentProject;
43                 IList                   properties;
44                 IDictionary             propertiesByName;
45         
46                 public BuildPropertyGroup ()
47                         : this (true, null)
48                 {
49                 }
50                 
51                 internal BuildPropertyGroup (bool forXml, Project project)
52                 {
53                         this.propertyGroup = null;
54                         this.condition = null;
55                         this.importedFromFilename = null;
56                         this.isImported = false;
57                         this.parentCollection = null;
58                         this.parentProject = project;
59                         if (forXml == true)
60                                 this.properties = new ArrayList ();
61                         else
62                                 this.propertiesByName = new Hashtable (new CaseInsensitiveHashCodeProvider(), new CaseInsensitiveComparer ());
63                 }
64
65                 public BuildProperty AddNewProperty (string propertyName,
66                                                      string propertyValue)
67                 {
68                         return AddNewProperty (propertyName, propertyValue,
69                                 PropertyType.Normal);
70                 }
71                 
72                 internal BuildProperty AddNewProperty (string propertyName,
73                                                        string propertyValue,
74                                                        PropertyType propertyType)
75                 {
76                         BuildProperty added, existing;
77                         
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);
88                                         }
89                                 } else {
90                                         propertiesByName.Add (added.Name, added);
91                                 }
92                         } else
93                                 throw new Exception ("PropertyGroup is not initialized.");
94                         return added;
95                 }
96                 
97                 internal void AddFromExistingProperty (BuildProperty buildProperty)
98                 {
99                         BuildProperty added, existing;
100                         
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);
107                                 }
108                         } else
109                                 propertiesByName.Add (added.Name, added);
110                 }
111                 
112                 public void Clear ()
113                 {
114                 }
115
116                 public BuildPropertyGroup Clone (bool deepClone)
117                 {
118                         return null;
119                 }
120
121                 // FIXME: what it is doing?
122                 public override void Evaluate (BuildPropertyGroup evaluatedPropertyBag,
123                                                bool ignoreCondition,
124                                                bool honorCondition,
125                                                Hashtable conditionedPropertiesTable,
126                                                ProcessingPass pass)
127                 {
128                 }
129                 
130                 public IEnumerator GetEnumerator ()
131                 {
132                         if (properties != null)
133                                 foreach (BuildProperty bp in properties)
134                                         yield return bp;
135                         else if (propertiesByName != null)
136                                 foreach (DictionaryEntry de in propertiesByName)
137                                         yield return (BuildProperty) de.Value;
138                         else
139                                 throw new Exception ("PropertyGroup is not initialized.");
140                 }
141
142                 public void GetStringArraysForAllProperties (out string[] propertyNames,
143                                                              out string[] propertyValues,
144                                                              out string[] propertyFinalValues)
145                 {
146                         propertyNames = null;
147                         propertyValues = null;
148                         propertyFinalValues = null;
149                         int i = 0;
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;
155                                         i++;
156                                 }
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;
162                                         i++;
163                                 }
164                         }
165                 }
166
167                 public void RemoveProperty (BuildProperty propertyToRemove)
168                 {
169                         if (properties == null)
170                                 throw new Exception ("PropertyGroup is not initialized.");
171                         properties.Remove (propertyToRemove);
172                 }
173
174                 public void RemovePropertyByName (string propertyNameToRemove)
175                 {
176                         if (propertiesByName == null)
177                                 throw new Exception ("PropertyGroup is not initialized.");
178                         propertiesByName.Remove (propertyNameToRemove);
179                 }
180
181                 public void SetProperty (string propertyName,
182                                          string propertyValue)
183                 {
184                         if (propertiesByName.Contains (propertyName) == false) {
185                                 AddNewProperty (propertyName, propertyValue);
186                         }
187                         ((BuildProperty) propertiesByName [propertyName]).Value = propertyValue;
188                 }
189                 
190                 internal void BindToXml (XmlElement propertyGroupElement)
191                 {
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;
202                                 bp.BindToXml (xe);
203                                 Expression finalValue = new Expression (parentProject, bp.Value);
204                                 bp.FinalValue = (string) finalValue.ToNonArray (typeof (string));
205                                 parentProject.EvaluatedProperties.AddFromExistingProperty (bp);
206                         } 
207                 }
208                 
209                 public string Condition {
210                         get {
211                                 if (condition == null)
212                                         return null;
213                                 else
214                                         return condition.Value;
215                         }
216                         set {
217                                 if (condition != null)
218                                         condition.Value = value;
219                         }
220                 }
221
222                 public int Count {
223                         get {
224                                 if (properties != null)
225                                         return properties.Count;
226                                 else if (propertiesByName != null)
227                                         return propertiesByName.Count;
228                                 else
229                                         throw new Exception ("PropertyGroup is not initialized.");
230                         }
231                 }
232
233                 public string ImportedFromFilename {
234                         get {
235                                 return importedFromFilename;
236                         }
237                 }
238
239                 public bool IsImported {
240                         get {
241                                 return isImported;
242                         }
243                 }
244
245                 public BuildProperty this[string propertyName] {
246                         get {
247                                 if (propertiesByName.Contains (propertyName)) {
248                                         return (BuildProperty) propertiesByName [propertyName];
249                                 } else {
250                                         return null;
251                                 }
252                         }
253                         set {
254                                 propertiesByName [propertyName] = value;
255                         }
256                 }
257                 
258                 internal GroupingCollection GroupingCollection {
259                         get { return parentCollection; }
260                         set { parentCollection = value; }
261                 }
262         }
263 }