~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric-updates

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Projects/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-02-18 08:40:51 UTC
  • mfrom: (1.2.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090218084051-gh8m6ukvokbwj7cf
Tags: 1.9.2+dfsg-1ubuntu1
* Merge from Debian Experimental (LP: #330519), remaining Ubuntu changes:
  + debian/control:
    - Update for Gnome# 2.24
    - Add libmono-cairo1.0-cil to build-deps to fool pkg-config check

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// MSBuildProject.cs
 
2
//
 
3
// Author:
 
4
//   Lluis Sanchez Gual <lluis@novell.com>
 
5
//
 
6
// Copyright (c) 2008 Novell, Inc (http://www.novell.com)
 
7
//
 
8
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
9
// of this software and associated documentation files (the "Software"), to deal
 
10
// in the Software without restriction, including without limitation the rights
 
11
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
12
// copies of the Software, and to permit persons to whom the Software is
 
13
// furnished to do so, subject to the following conditions:
 
14
//
 
15
// The above copyright notice and this permission notice shall be included in
 
16
// all copies or substantial portions of the Software.
 
17
//
 
18
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
19
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
20
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
21
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
22
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
23
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
24
// THE SOFTWARE.
 
25
//
 
26
//
 
27
 
 
28
using System;
 
29
using System.IO;
 
30
using System.Collections.Generic;
 
31
using System.Xml;
 
32
 
 
33
namespace MonoDevelop.Projects.Formats.MSBuild
 
34
{
 
35
        class MSBuildProject
 
36
        {
 
37
                public XmlDocument doc;
 
38
                Dictionary<XmlElement,MSBuildObject> elemCache = new Dictionary<XmlElement,MSBuildObject> ();
 
39
                
 
40
                public const string Schema = "http://schemas.microsoft.com/developer/msbuild/2003";
 
41
                static XmlNamespaceManager manager;
 
42
                
 
43
                bool useCrLf;
 
44
                
 
45
                internal static XmlNamespaceManager XmlNamespaceManager {
 
46
                        get {
 
47
                                if (manager == null) {
 
48
                                        manager = new XmlNamespaceManager (new NameTable ());
 
49
                                        manager.AddNamespace ("tns", Schema);
 
50
                                }
 
51
                                return manager;
 
52
                        }
 
53
                }
 
54
                
 
55
                public MSBuildProject ()
 
56
                {
 
57
                        doc = new XmlDocument ();
 
58
                        doc.PreserveWhitespace = false;
 
59
                        doc.AppendChild (doc.CreateElement (null, "Project", Schema));
 
60
                }
 
61
                
 
62
                public void Load (string file)
 
63
                {
 
64
                        doc = new XmlDocument ();
 
65
                        doc.PreserveWhitespace = false;
 
66
                        doc.Load (file);
 
67
                }
 
68
                
 
69
                public void LoadXml (string xml)
 
70
                {
 
71
                        doc = new XmlDocument ();
 
72
                        doc.PreserveWhitespace = false;
 
73
                        doc.LoadXml (xml);
 
74
                        useCrLf = CountNewLines ("\r\n", xml) > (CountNewLines ("\n", xml) / 2);
 
75
                }
 
76
                
 
77
                public void Save (string file)
 
78
                {
 
79
                        StreamWriter sw = new StreamWriter (file);
 
80
                        if (useCrLf)
 
81
                                sw.NewLine = "\r\n";
 
82
                        else
 
83
                                sw.NewLine = "\n";
 
84
                        using (sw) {
 
85
                                doc.Save (sw);
 
86
                        }
 
87
                }
 
88
                
 
89
                int CountNewLines (string nl, string text)
 
90
                {
 
91
                        int i = -1;
 
92
                        int c = -1;
 
93
                        do {
 
94
                                c++;
 
95
                                i++;
 
96
                                i = text.IndexOf (nl, i);
 
97
                        }
 
98
                        while (i != -1);
 
99
                        return c;
 
100
                }
 
101
                
 
102
                public string DefaultTargets {
 
103
                        get { return doc.DocumentElement.GetAttribute ("DefaultTargets"); }
 
104
                        set { doc.DocumentElement.SetAttribute ("DefaultTargets", value); }
 
105
                }
 
106
                
 
107
                public string ToolsVersion {
 
108
                        get { return doc.DocumentElement.GetAttribute ("ToolsVersion"); }
 
109
                        set {
 
110
                                if (!string.IsNullOrEmpty (value))
 
111
                                        doc.DocumentElement.SetAttribute ("ToolsVersion", value);
 
112
                                else
 
113
                                        doc.DocumentElement.RemoveAttribute ("ToolsVersion");
 
114
                        }
 
115
                }
 
116
                
 
117
                public void AddNewImport (string name, string condition)
 
118
                {
 
119
                        XmlElement elem = doc.CreateElement (null, "Import", MSBuildProject.Schema);
 
120
                        doc.DocumentElement.AppendChild (elem);
 
121
                        elem.SetAttribute ("Project", name);
 
122
                }
 
123
                
 
124
                public MSBuildPropertyGroup GetGlobalPropertyGroup ()
 
125
                {
 
126
                        foreach (MSBuildPropertyGroup grp in PropertyGroups) {
 
127
                                if (grp.Condition.Length == 0)
 
128
                                        return grp;
 
129
                        }
 
130
                        return null;
 
131
                }
 
132
                
 
133
                public MSBuildPropertyGroup AddNewPropertyGroup (bool insertAtEnd)
 
134
                {
 
135
                        XmlElement elem = doc.CreateElement (null, "PropertyGroup", MSBuildProject.Schema);
 
136
                        
 
137
                        XmlElement last = doc.DocumentElement.SelectSingleNode ("tns:PropertyGroup[last()]", XmlNamespaceManager) as XmlElement;
 
138
                        if (last != null)
 
139
                                doc.DocumentElement.InsertAfter (elem, last);
 
140
                        else
 
141
                                doc.DocumentElement.AppendChild (elem);
 
142
                        
 
143
                        return GetGroup (elem);
 
144
                }
 
145
                
 
146
                public IEnumerable<MSBuildItem> GetAllItems ()
 
147
                {
 
148
                        foreach (XmlElement elem in doc.DocumentElement.SelectNodes ("tns:ItemGroup/*", XmlNamespaceManager)) {
 
149
                                yield return GetItem (elem);
 
150
                        }
 
151
                }
 
152
                
 
153
                public IEnumerable<MSBuildItem> GetAllItems (params string[] names)
 
154
                {
 
155
                        string name = string.Join ("|tns:ItemGroup/tns:", names);
 
156
                        foreach (XmlElement elem in doc.DocumentElement.SelectNodes ("tns:ItemGroup/tns:" + name, XmlNamespaceManager)) {
 
157
                                yield return GetItem (elem);
 
158
                        }
 
159
                }
 
160
                
 
161
                public IEnumerable<MSBuildPropertyGroup> PropertyGroups {
 
162
                        get {
 
163
                                foreach (XmlElement elem in doc.DocumentElement.SelectNodes ("tns:PropertyGroup", XmlNamespaceManager))
 
164
                                        yield return GetGroup (elem);
 
165
                        }
 
166
                }
 
167
                
 
168
                public IEnumerable<MSBuildItemGroup> ItemGroups {
 
169
                        get {
 
170
                                foreach (XmlElement elem in doc.DocumentElement.SelectNodes ("tns:ItemGroup", XmlNamespaceManager))
 
171
                                        yield return GetItemGroup (elem);
 
172
                        }
 
173
                }
 
174
                
 
175
                public MSBuildItemGroup AddNewItemGroup ()
 
176
                {
 
177
                        XmlElement elem = doc.CreateElement (null, "ItemGroup", MSBuildProject.Schema);
 
178
                        doc.DocumentElement.AppendChild (elem);
 
179
                        return GetItemGroup (elem);
 
180
                }
 
181
                
 
182
                public MSBuildItem AddNewItem (string name, string include)
 
183
                {
 
184
                        XmlElement elem = (XmlElement) doc.DocumentElement.SelectSingleNode ("tns:ItemGroup/" + name, XmlNamespaceManager);
 
185
                        if (elem != null) {
 
186
                                MSBuildItemGroup grp = GetItemGroup ((XmlElement) elem.ParentNode);
 
187
                                return grp.AddNewItem (name, include);
 
188
                        } else {
 
189
                                MSBuildItemGroup grp = AddNewItemGroup ();
 
190
                                return grp.AddNewItem (name, include);
 
191
                        }
 
192
                }
 
193
                
 
194
                public string GetProjectExtensions (string section)
 
195
                {
 
196
                        XmlElement elem = doc.DocumentElement.SelectSingleNode ("tns:ProjectExtensions/tns:" + section, XmlNamespaceManager) as XmlElement;
 
197
                        if (elem != null)
 
198
                                return elem.InnerXml;
 
199
                        else
 
200
                                return string.Empty;
 
201
                }
 
202
                
 
203
                public void SetProjectExtensions (string section, string value)
 
204
                {
 
205
                        XmlElement elem = doc.DocumentElement ["ProjectExtensions", MSBuildProject.Schema];
 
206
                        if (elem == null) {
 
207
                                elem = doc.CreateElement (null, "ProjectExtensions", MSBuildProject.Schema);
 
208
                                doc.DocumentElement.AppendChild (elem);
 
209
                        }
 
210
                        XmlElement sec = elem [section];
 
211
                        if (sec == null) {
 
212
                                sec = doc.CreateElement (null, section, MSBuildProject.Schema);
 
213
                                elem.AppendChild (sec);
 
214
                        }
 
215
                        sec.InnerXml = value;
 
216
                }
 
217
 
 
218
                public void RemoveProjectExtensions (string section)
 
219
                {
 
220
                        XmlElement elem = doc.DocumentElement.SelectSingleNode ("tns:ProjectExtensions/tns:" + section, XmlNamespaceManager) as XmlElement;
 
221
                        if (elem != null) {
 
222
                                XmlElement parent = (XmlElement) elem.ParentNode;
 
223
                                parent.RemoveChild (elem);
 
224
                                if (!parent.HasChildNodes)
 
225
                                        parent.ParentNode.RemoveChild (parent);
 
226
                        }
 
227
                }
 
228
                
 
229
                public void RemoveItem (MSBuildItem item)
 
230
                {
 
231
                        elemCache.Remove (item.Element);
 
232
                        XmlElement parent = (XmlElement) item.Element.ParentNode;
 
233
                        item.Element.ParentNode.RemoveChild (item.Element);
 
234
                        if (parent.ChildNodes.Count == 0) {
 
235
                                elemCache.Remove (parent);
 
236
                                parent.ParentNode.RemoveChild (parent);
 
237
                        }
 
238
                }
 
239
                
 
240
                internal MSBuildItem GetItem (XmlElement elem)
 
241
                {
 
242
                        MSBuildObject ob;
 
243
                        if (elemCache.TryGetValue (elem, out ob))
 
244
                                return (MSBuildItem) ob;
 
245
                        MSBuildItem it = new MSBuildItem (elem);
 
246
                        elemCache [elem] = it;
 
247
                        return it;
 
248
                }
 
249
                
 
250
                MSBuildPropertyGroup GetGroup (XmlElement elem)
 
251
                {
 
252
                        MSBuildObject ob;
 
253
                        if (elemCache.TryGetValue (elem, out ob))
 
254
                                return (MSBuildPropertyGroup) ob;
 
255
                        MSBuildPropertyGroup it = new MSBuildPropertyGroup (elem);
 
256
                        elemCache [elem] = it;
 
257
                        return it;
 
258
                }
 
259
                
 
260
                MSBuildItemGroup GetItemGroup (XmlElement elem)
 
261
                {
 
262
                        MSBuildObject ob;
 
263
                        if (elemCache.TryGetValue (elem, out ob))
 
264
                                return (MSBuildItemGroup) ob;
 
265
                        MSBuildItemGroup it = new MSBuildItemGroup (this, elem);
 
266
                        elemCache [elem] = it;
 
267
                        return it;
 
268
                }
 
269
        }
 
270
        
 
271
        public class MSBuildObject
 
272
        {
 
273
                XmlElement elem;
 
274
                
 
275
                public MSBuildObject (XmlElement elem)
 
276
                {
 
277
                        this.elem = elem;
 
278
                }
 
279
                
 
280
                public XmlElement Element {
 
281
                        get { return elem; }
 
282
                }
 
283
                
 
284
                protected XmlElement AddChildElement (string name)
 
285
                {
 
286
                        XmlElement e = elem.OwnerDocument.CreateElement (null, name, MSBuildProject.Schema);
 
287
                        elem.AppendChild (e);
 
288
                        return e;
 
289
                }
 
290
                
 
291
                public string Condition {
 
292
                        get {
 
293
                                return Element.GetAttribute ("Condition");
 
294
                        }
 
295
                        set {
 
296
                                if (string.IsNullOrEmpty (value))
 
297
                                        Element.RemoveAttribute ("Condition");
 
298
                                else
 
299
                                        Element.SetAttribute ("Condition", value);
 
300
                        }
 
301
                }
 
302
        }
 
303
        
 
304
        class MSBuildProperty: MSBuildObject
 
305
        {
 
306
                public MSBuildProperty (XmlElement elem): base (elem)
 
307
                {
 
308
                }
 
309
                
 
310
                public string Name {
 
311
                        get { return Element.Name; }
 
312
                }
 
313
                
 
314
                public string Value {
 
315
                        get {
 
316
                                return Element.InnerXml; 
 
317
                        }
 
318
                        set {
 
319
                                Element.InnerXml = value;
 
320
                        }
 
321
                }
 
322
        }
 
323
        
 
324
        class MSBuildPropertyGroup: MSBuildObject
 
325
        {
 
326
                Dictionary<string,MSBuildProperty> properties = new Dictionary<string,MSBuildProperty> ();
 
327
                
 
328
                public MSBuildPropertyGroup (XmlElement elem): base (elem)
 
329
                {
 
330
                }
 
331
                
 
332
                public MSBuildProperty GetProperty (string name)
 
333
                {
 
334
                        MSBuildProperty prop;
 
335
                        if (properties.TryGetValue (name, out prop))
 
336
                                return prop;
 
337
                        XmlElement propElem = Element [name, MSBuildProject.Schema];
 
338
                        if (propElem != null) {
 
339
                                prop = new MSBuildProperty (propElem);
 
340
                                properties [name] = prop;
 
341
                                return prop;
 
342
                        }
 
343
                        else
 
344
                                return null;
 
345
                }
 
346
                
 
347
                public IEnumerable<MSBuildProperty> Properties {
 
348
                        get {
 
349
                                foreach (XmlNode node in Element.ChildNodes) {
 
350
                                        XmlElement pelem = node as XmlElement;
 
351
                                        if (pelem == null)
 
352
                                                continue;
 
353
                                        MSBuildProperty prop;
 
354
                                        if (properties.TryGetValue (pelem.Name, out prop))
 
355
                                                yield return prop;
 
356
                                        else {
 
357
                                                prop = new MSBuildProperty (pelem);
 
358
                                                properties [pelem.Name] = prop;
 
359
                                                yield return prop;
 
360
                                        }
 
361
                                }
 
362
                        }
 
363
                }
 
364
                
 
365
                public void SetPropertyValue (string name, string value)
 
366
                {
 
367
                        MSBuildProperty prop = GetProperty (name);
 
368
                        if (prop == null) {
 
369
                                XmlElement pelem = AddChildElement (name);
 
370
                                prop = new MSBuildProperty (pelem);
 
371
                                properties [name] = prop;
 
372
                        }
 
373
                        prop.Value = value;
 
374
                }
 
375
                
 
376
                public string GetPropertyValue (string name)
 
377
                {
 
378
                        MSBuildProperty prop = GetProperty (name);
 
379
                        if (prop == null)
 
380
                                return null;
 
381
                        else
 
382
                                return prop.Value;
 
383
                }
 
384
                
 
385
                public void RemoveProperty (string name)
 
386
                {
 
387
                        MSBuildProperty prop = GetProperty (name);
 
388
                        if (prop != null) {
 
389
                                properties.Remove (name);
 
390
                                Element.RemoveChild (prop.Element);
 
391
                        }
 
392
                }
 
393
 
 
394
                public void RemoveAllProperties ()
 
395
                {
 
396
                        List<XmlNode> toDelete = new List<XmlNode> ();
 
397
                        foreach (XmlNode node in Element.ChildNodes) {
 
398
                                if (node is XmlElement)
 
399
                                        toDelete.Add (node);
 
400
                        }
 
401
                        foreach (XmlNode node in toDelete)
 
402
                                Element.RemoveChild (node);
 
403
                        properties.Clear ();
 
404
                }
 
405
 
 
406
                public static MSBuildPropertyGroup Merge (MSBuildPropertyGroup g1, MSBuildPropertyGroup g2)
 
407
                {
 
408
                        XmlElement elem = g1.Element.OwnerDocument.CreateElement (null, "PropertyGroup", MSBuildProject.Schema);
 
409
                        MSBuildPropertyGroup grp = new MSBuildPropertyGroup (elem);
 
410
                        foreach (MSBuildProperty prop in g1.Properties)
 
411
                                grp.SetPropertyValue (prop.Name, prop.Value);
 
412
                        foreach (MSBuildProperty prop in g2.Properties)
 
413
                                grp.SetPropertyValue (prop.Name, prop.Value);
 
414
                        return grp;
 
415
                }
 
416
 
 
417
                public void UnMerge (MSBuildPropertyGroup baseGrp)
 
418
                {
 
419
                        foreach (MSBuildProperty prop in baseGrp.Properties) {
 
420
                                MSBuildProperty thisProp = GetProperty (prop.Name);
 
421
                                if (thisProp != null && prop.Value == thisProp.Value)
 
422
                                        RemoveProperty (prop.Name);
 
423
                        }
 
424
                }
 
425
 
 
426
                public override string ToString()
 
427
                {
 
428
                        string s = "[MSBuildPropertyGroup:";
 
429
                        foreach (MSBuildProperty prop in Properties)
 
430
                                s += " " + prop.Name + "=" + prop.Value;
 
431
                        return s + "]";
 
432
                }
 
433
 
 
434
        }
 
435
        
 
436
        class MSBuildItem: MSBuildObject
 
437
        {
 
438
                public MSBuildItem (XmlElement elem): base (elem)
 
439
                {
 
440
                }
 
441
                
 
442
                public string Include {
 
443
                        get { return Element.GetAttribute ("Include"); }
 
444
                        set { Element.SetAttribute ("Include", value); }
 
445
                }
 
446
                
 
447
                public string Name {
 
448
                        get { return Element.Name; }
 
449
                }
 
450
                
 
451
                public bool HasMetadata (string name)
 
452
                {
 
453
                        return Element [name, MSBuildProject.Schema] != null;
 
454
                }
 
455
                
 
456
                public void SetMetadata (string name, string value)
 
457
                {
 
458
                        SetMetadata (name, value, true);
 
459
                }
 
460
                
 
461
                public void SetMetadata (string name, string value, bool isLiteral)
 
462
                {
 
463
                        XmlElement elem = Element [name, MSBuildProject.Schema];
 
464
                        if (elem == null) {
 
465
                                elem = AddChildElement (name);
 
466
                                Element.AppendChild (elem);
 
467
                        }
 
468
                        elem.InnerXml = value;
 
469
                }
 
470
                
 
471
                public void UnsetMetadata (string name)
 
472
                {
 
473
                        XmlElement elem = Element [name, MSBuildProject.Schema];
 
474
                        if (elem != null)
 
475
                                Element.RemoveChild (elem);
 
476
                }
 
477
                
 
478
                public string GetMetadata (string name)
 
479
                {
 
480
                        XmlElement elem = Element [name, MSBuildProject.Schema];
 
481
                        if (elem != null)
 
482
                                return elem.InnerXml;
 
483
                        else
 
484
                                return null;
 
485
                }
 
486
        }
 
487
        
 
488
        class MSBuildItemGroup: MSBuildObject
 
489
        {
 
490
                MSBuildProject parent;
 
491
                
 
492
                internal MSBuildItemGroup (MSBuildProject parent, XmlElement elem): base (elem)
 
493
                {
 
494
                        this.parent = parent;
 
495
                }
 
496
                
 
497
                public MSBuildItem AddNewItem (string name, string include)
 
498
                {
 
499
                        XmlElement elem = AddChildElement (name);
 
500
                        MSBuildItem it = parent.GetItem (elem);
 
501
                        it.Include = include;
 
502
                        return it;
 
503
                }
 
504
                
 
505
                public IEnumerable<MSBuildItem> Items {
 
506
                        get {
 
507
                                foreach (XmlNode node in Element.ChildNodes) {
 
508
                                        XmlElement elem = node as XmlElement;
 
509
                                        if (elem != null)
 
510
                                                yield return parent.GetItem (elem);
 
511
                                }
 
512
                        }
 
513
                }
 
514
        }
 
515
}