New test.
[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.Generic;
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                 List <BuildProperty>    properties;
45                 Dictionary <string, BuildProperty>      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 List <BuildProperty> ();
62                                 foreach (XmlNode xn in propertyGroup.ChildNodes) {
63                                         if (xn is XmlElement == false)
64                                                 continue;
65                                         
66                                         XmlElement xe = (XmlElement) xn;
67                                         BuildProperty bp = new BuildProperty (parentProject, xe);
68                                         AddProperty (bp);
69                                 } 
70                         } else
71                                 this.propertiesByName = new Dictionary <string, BuildProperty> (StringComparer.InvariantCultureIgnoreCase);
72                 }
73
74                 public BuildProperty AddNewProperty (string propertyName,
75                                                      string propertyValue)
76                 {
77                         return AddNewProperty (propertyName, propertyValue, false);
78                 }
79                 
80                 public BuildProperty AddNewProperty (string propertyName,
81                                                      string propertyValue,
82                                                      bool treatPropertyValueAsLiteral)
83                 {
84                         BuildProperty prop;
85
86                         if (FromXml) {
87                                 XmlElement xe;
88                                 
89                                 xe = propertyGroup.OwnerDocument.CreateElement (propertyName);
90                                 propertyGroup.AppendChild (xe);
91                                 
92                                 if (treatPropertyValueAsLiteral)
93                                         xe.InnerText = Utilities.Escape (propertyValue);
94                                 else
95                                         xe.InnerText = propertyValue;
96                                 
97                                 prop = new BuildProperty (parentProject, xe);
98                         } else {
99                                 prop = new BuildProperty (propertyName, propertyValue);
100                         }
101                         AddProperty (prop);
102                         return prop;
103                 }
104
105                 internal void AddProperty (BuildProperty property)
106                 {
107                         if (FromXml) {
108                                 properties.Add (property);
109                         } else {
110                                 if (propertiesByName.ContainsKey (property.Name)) {
111                                         BuildProperty existing = propertiesByName [property.Name];
112                                         if (property.PropertyType <= existing.PropertyType) {
113                                                 propertiesByName.Remove (property.Name);
114                                                 propertiesByName.Add (property.Name, property);
115                                         }
116                                 } else {
117                                         propertiesByName.Add (property.Name, property);
118                                 }
119                         }
120                 }
121                 
122                 [MonoTODO]
123                 public void Clear ()
124                 {
125                         throw new NotImplementedException ();
126                 }
127
128                 [MonoTODO]
129                 public BuildPropertyGroup Clone (bool deepClone)
130                 {
131                         throw new NotImplementedException ();
132                 }
133
134                 public IEnumerator GetEnumerator ()
135                 {
136                         if (properties != null) {
137                                 foreach (BuildProperty bp in properties)
138                                         yield return bp;
139                         } else if (propertiesByName != null) {
140                                 foreach (KeyValuePair <string, BuildProperty> kvp in propertiesByName)
141                                         yield return kvp.Value;
142                         } else
143                                 throw new Exception ("PropertyGroup is not initialized.");
144                 }
145
146                 public void RemoveProperty (BuildProperty propertyToRemove)
147                 {
148                         if (properties == null)
149                                 throw new Exception ("PropertyGroup is not initialized.");
150                         properties.Remove (propertyToRemove);
151                 }
152
153                 public void RemoveProperty (string propertyName)
154                 {
155                         if (propertiesByName == null)
156                                 throw new Exception ("PropertyGroup is not initialized.");
157                         propertiesByName.Remove (propertyName);
158                 }
159
160                 public void SetProperty (string propertyName,
161                                          string propertyValue)
162                 {
163                         SetProperty (propertyName, propertyValue, false);
164                 }
165                 
166                 // FIXME: use treatPropertyValueAsLiteral
167                 [MonoTODO]
168                 public void SetProperty (string propertyName,
169                                          string propertyValue,
170                                          bool treatPropertyValueAsLiteral)
171                 {
172                         if (!propertiesByName.ContainsKey (propertyName)) {
173                                 AddNewProperty (propertyName, propertyValue);
174                         }
175                         propertiesByName [propertyName].Value = propertyValue;
176                 }
177                 
178                 internal void Evaluate ()
179                 {
180                         if (!FromXml) {
181                                 throw new InvalidOperationException ();
182                         }
183                         foreach (BuildProperty bp in properties) {
184                                 if (bp.Condition == String.Empty)
185                                         bp.Evaluate ();
186                                 else {
187                                         ConditionExpression ce = ConditionParser.ParseCondition (bp.Condition);
188                                         if (ce.BoolEvaluate (parentProject))
189                                                 bp.Evaluate ();
190                                 }
191                         }
192                 }
193                 
194                 public string Condition {
195                         get {
196                                 if (!FromXml)
197                                         return String.Empty;
198                                 return propertyGroup.GetAttribute ("Condition");
199                         }
200                         set {
201                                 if (!FromXml)
202                                         throw new InvalidOperationException (
203                                         "Cannot set a condition on an object not represented by an XML element in the project file.");
204                                 propertyGroup.SetAttribute ("Condition", value);
205                         }
206                 }
207
208                 public int Count {
209                         get {
210                                 if (properties != null)
211                                         return properties.Count;
212                                 else if (propertiesByName != null)
213                                         return propertiesByName.Count;
214                                 else
215                                         throw new Exception ("PropertyGroup is not initialized.");
216                         }
217                 }
218
219                 public bool IsImported {
220                         get {
221                                 return isImported;
222                         }
223                 }
224
225                 internal bool FromXml {
226                         get {
227                                 return propertyGroup != null;
228                         }
229                 }
230
231                 public BuildProperty this [string propertyName] {
232                         get {
233                                 if (FromXml)
234                                         throw new InvalidOperationException ("Properties in persisted property groups cannot be accessed by name.");
235                                 
236                                 if (propertiesByName.ContainsKey (propertyName)) {
237                                         return propertiesByName [propertyName];
238                                 } else {
239                                         return null;
240                                 }
241                         }
242                         set {
243                                 propertiesByName [propertyName] = value;
244                         }
245                 }
246                 
247                 internal GroupingCollection GroupingCollection {
248                         get { return parentCollection; }
249                         set { parentCollection = value; }
250                 }
251         }
252 }
253
254 #endif