2006-06-14 Marek Sieradzki <marek.sieradzki@gmail.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 #if NET_2_0
29
30 using System;
31 using System.Collections;
32 using System.Collections.Specialized;
33 using System.Reflection;
34 using System.Text;
35 using System.Xml;
36
37 namespace Microsoft.Build.BuildEngine {
38         public class BuildPropertyGroup : IEnumerable {
39         
40                 XmlElement              propertyGroup;
41                 bool                    isImported;
42                 GroupingCollection      parentCollection;
43                 Project                 parentProject;
44                 IList                   properties;
45                 IDictionary             propertiesByName;
46
47                 public BuildPropertyGroup ()
48                         : this (null, null)
49                 {
50                 }
51
52                 internal BuildPropertyGroup (XmlElement xmlElement, Project project)
53                 {
54                         this.isImported = false;
55                         this.parentCollection = null;
56                         this.parentProject = project;
57                         this.isImported = false;
58                         this.propertyGroup = xmlElement;
59
60                         if (FromXml) {
61                                 this.properties = new ArrayList ();
62                                 foreach (XmlElement xe in propertyGroup.ChildNodes) {
63                                         BuildProperty bp = new BuildProperty (parentProject, xe);
64                                         AddProperty (bp);
65                                 } 
66                         } else
67                                 this.propertiesByName = CollectionsUtil.CreateCaseInsensitiveHashtable ();
68                 }
69
70                 public BuildProperty AddNewProperty (string propertyName,
71                                                      string propertyValue)
72                 {
73                         return AddNewProperty (propertyName, propertyValue, false);
74                 }
75                 
76                 public BuildProperty AddNewProperty (string propertyName,
77                                                      string propertyValue,
78                                                      bool treatPropertyValueAsLiteral)
79                 {
80                         BuildProperty prop;
81
82                         if (FromXml) {
83                                 XmlElement xe;
84                                 
85                                 xe = propertyGroup.OwnerDocument.CreateElement (propertyName);
86                                 propertyGroup.AppendChild (xe);
87                                 if (treatPropertyValueAsLiteral) {
88                                         xe.InnerText = Utilities.Escape (propertyValue);
89                                 } else {
90                                         xe.InnerText = propertyValue;
91                                 }
92                                 prop = new BuildProperty (parentProject, xe);
93                         } else {
94                                 prop = new BuildProperty (propertyName, propertyValue);
95                         }
96                         AddProperty (prop);
97                         return prop;
98                 }
99
100                 internal void AddProperty (BuildProperty property)
101                 {
102                         if (FromXml) {
103                                 properties.Add (property);
104                         } else {
105                                 if (propertiesByName.Contains (property.Name)) {
106                                         BuildProperty existing = (BuildProperty) propertiesByName [property.Name];
107                                         if (property.PropertyType <= existing.PropertyType) {
108                                                 propertiesByName.Remove (property.Name);
109                                                 propertiesByName.Add (property.Name, property);
110                                         }
111                                 } else {
112                                         propertiesByName.Add (property.Name, property);
113                                 }
114                         }
115                 }
116                 
117                 [MonoTODO]
118                 public void Clear ()
119                 {
120                         throw new NotImplementedException ();
121                 }
122
123                 [MonoTODO]
124                 public BuildPropertyGroup Clone (bool deepClone)
125                 {
126                         throw new NotImplementedException ();
127                 }
128
129                 public IEnumerator GetEnumerator ()
130                 {
131                         if (properties != null) {
132                                 foreach (BuildProperty bp in properties)
133                                         yield return bp;
134                         } else if (propertiesByName != null) {
135                                 foreach (DictionaryEntry de in propertiesByName)
136                                         yield return (BuildProperty) de.Value;
137                         } else
138                                 throw new Exception ("PropertyGroup is not initialized.");
139                 }
140
141                 public void RemoveProperty (BuildProperty propertyToRemove)
142                 {
143                         if (properties == null)
144                                 throw new Exception ("PropertyGroup is not initialized.");
145                         properties.Remove (propertyToRemove);
146                 }
147
148                 public void RemoveProperty (string propertyName)
149                 {
150                         if (propertiesByName == null)
151                                 throw new Exception ("PropertyGroup is not initialized.");
152                         propertiesByName.Remove (propertyName);
153                 }
154
155                 public void SetProperty (string propertyName,
156                                          string propertyValue)
157                 {
158                         SetProperty (propertyName, propertyValue, false);
159                 }
160                 
161                 // FIXME: use treatPropertyValueAsLiteral
162                 [MonoTODO]
163                 public void SetProperty (string propertyName,
164                                          string propertyValue,
165                                          bool treatPropertyValueAsLiteral)
166                 {
167                         if (propertiesByName.Contains (propertyName) == false) {
168                                 AddNewProperty (propertyName, propertyValue);
169                         }
170                         ((BuildProperty) propertiesByName [propertyName]).Value = propertyValue;
171                 }
172                 
173                 internal void Evaluate ()
174                 {
175                         if (!FromXml) {
176                                 throw new InvalidOperationException ();
177                         }
178                         foreach (BuildProperty bp in properties) {
179                                 bp.Evaluate ();
180                         }
181                 }
182                 
183                 public string Condition {
184                         get {
185                                 if (!FromXml)
186                                         return String.Empty;
187                                 return propertyGroup.GetAttribute ("Condition");
188                         }
189                         set {
190                                 if (!FromXml)
191                                         throw new InvalidOperationException (
192                                         "Cannot set a condition on an object not represented by an XML element in the project file.");
193                                 propertyGroup.SetAttribute ("Condition", value);
194                         }
195                 }
196
197                 public int Count {
198                         get {
199                                 if (properties != null)
200                                         return properties.Count;
201                                 else if (propertiesByName != null)
202                                         return propertiesByName.Count;
203                                 else
204                                         throw new Exception ("PropertyGroup is not initialized.");
205                         }
206                 }
207
208                 public bool IsImported {
209                         get {
210                                 return isImported;
211                         }
212                 }
213
214                 internal bool FromXml {
215                         get {
216                                 return propertyGroup != null;
217                         }
218                 }
219
220                 public BuildProperty this [string propertyName] {
221                         get {
222                                 if (FromXml)
223                                         throw new InvalidOperationException ("Properties in persisted property groups cannot be accessed by name.");
224                                 
225                                 if (propertiesByName.Contains (propertyName)) {
226                                         return (BuildProperty) propertiesByName [propertyName];
227                                 } else {
228                                         return null;
229                                 }
230                         }
231                         set {
232                                 propertiesByName [propertyName] = value;
233                         }
234                 }
235                 
236                 internal GroupingCollection GroupingCollection {
237                         get { return parentCollection; }
238                         set { parentCollection = value; }
239                 }
240         }
241 }
242
243 #endif