~ubuntu-branches/ubuntu/maverick/monodevelop/maverick

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MD1/CmbxFileFormat.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-07-05 13:00:05 UTC
  • mfrom: (1.2.8 upstream) (1.3.9 experimental)
  • Revision ID: james.westby@ubuntu.com-20100705130005-d6hp4k5gcn1xkj8c
Tags: 2.4+dfsg-1ubuntu1
* debian/patches/remove_support_for_moonlight.patch,
  debian/patches/dont_add_moonlight_to_core_addins.patch,
  debian/control:
  + Enable support for Moonlight
* debian/rules:
  + Ensure Moonlight addin isn't shipped in main MonoDevelop package by
    mistake

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// CmbxFileFormat.cs
 
3
//
 
4
// Author:
 
5
//   Lluis Sanchez Gual
 
6
//
 
7
// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
 
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
 
 
29
using System;
 
30
using System.Collections;
 
31
using System.Collections.Generic;
 
32
using System.Collections.ObjectModel;
 
33
using System.Collections.Specialized;
 
34
using System.IO;
 
35
using System.Xml;
 
36
using MonoDevelop.Core;
 
37
using MonoDevelop.Projects;
 
38
using MonoDevelop.Core.Serialization;
 
39
 
 
40
namespace MonoDevelop.Projects.Formats.MD1
 
41
{
 
42
        interface ICombineReader {
 
43
                object ReadCombine (XmlReader reader);
 
44
        }
 
45
        
 
46
        class CombineReaderV2: XmlConfigurationReader, ICombineReader
 
47
        {
 
48
                DataSerializer serializer;
 
49
                ArrayList entries = new ArrayList ();
 
50
                IProgressMonitor monitor;
 
51
                Type objectType;
 
52
                string baseFile;
 
53
                
 
54
                public CombineReaderV2 (DataSerializer serializer, IProgressMonitor monitor, Type objectType)
 
55
                {
 
56
                        this.serializer = serializer;
 
57
                        this.objectType = objectType;
 
58
                        baseFile = serializer.SerializationContext.BaseFile;
 
59
                        this.monitor = monitor;
 
60
                }
 
61
                
 
62
                public object ReadCombine (XmlReader reader)
 
63
                {
 
64
                        DataItem data = (DataItem) Read (reader);
 
65
                        
 
66
                        // Both combine and SolutionFolder use the same element name, but the types are different
 
67
                        if (data.Name == "Combine" && objectType == typeof(SolutionFolder))
 
68
                                data.Name = "SolutionFolder";
 
69
                        
 
70
                        SolutionFolder folder;
 
71
                        IExtendedDataItem obj = (IExtendedDataItem) serializer.CreateInstance (objectType, data);
 
72
                        Solution sol = obj as Solution;
 
73
                        if (sol != null) {
 
74
                                folder = sol.RootFolder;
 
75
                                sol.ConvertToFormat (MD1ProjectService.FileFormat, false);
 
76
                                sol.FileName = serializer.SerializationContext.BaseFile;
 
77
                                folder.ExtendedProperties ["FileName"] = serializer.SerializationContext.BaseFile;
 
78
                        }
 
79
                        else {
 
80
                                folder = (SolutionFolder) obj;
 
81
                                obj.ExtendedProperties ["FileName"] = serializer.SerializationContext.BaseFile;
 
82
                        }
 
83
                        
 
84
                        // The folder entries must be added before deserializing the folder
 
85
                        // since other folder members depend on it
 
86
                        
 
87
                        foreach (SolutionItem ce in entries)
 
88
                                folder.Items.Add (ce);
 
89
                        
 
90
                        serializer.Deserialize (obj, data);
 
91
                        
 
92
                        if (sol != null) {
 
93
                                CreateSolutionConfigurations (sol);
 
94
                                LoadStartupMode (sol);
 
95
                        }
 
96
                        
 
97
                        
 
98
                        return obj;
 
99
                }
 
100
                
 
101
                protected override DataNode ReadChild (XmlReader reader, DataItem parent)
 
102
                {
 
103
                        if (reader.LocalName == "Entries") {
 
104
                                if (reader.IsEmptyElement) { reader.Skip(); return null; }
 
105
                                string basePath = Path.GetDirectoryName (baseFile);
 
106
                                reader.ReadStartElement ();
 
107
                                
 
108
                                ArrayList files = new ArrayList ();
 
109
                                while (MoveToNextElement (reader)) {
 
110
                                        string nodefile = reader.GetAttribute ("filename");
 
111
                                        nodefile = FileService.RelativeToAbsolutePath (basePath, nodefile);
 
112
                                        files.Add (nodefile);
 
113
                                        reader.Skip ();
 
114
                                }
 
115
                                
 
116
                                monitor.BeginTask (GettextCatalog.GetString ("Loading solution: {0}", baseFile), files.Count);
 
117
                                try {
 
118
                                        foreach (string nodefile in files) {
 
119
                                                try {
 
120
                                                        if (Path.GetExtension (nodefile).ToLower () == ".mds") {
 
121
                                                                entries.Add (ReadSolutionFolder (nodefile, monitor));
 
122
                                                        }
 
123
                                                        else {
 
124
                                                                SolutionEntityItem entry = (SolutionEntityItem) Services.ProjectService.ReadSolutionItem (monitor, nodefile);
 
125
                                                                entries.Add (entry);
 
126
                                                        }
 
127
                                                } catch (Exception ex) {
 
128
                                                        UnknownSolutionItem entry = new UnknownSolutionItem ();
 
129
                                                        entry.FileName = nodefile;
 
130
                                                        entry.LoadError = ex.Message;
 
131
                                                        entries.Add (entry);
 
132
                                                        monitor.ReportError (GettextCatalog.GetString ("Could not load item: {0}", nodefile), ex);
 
133
                                                }
 
134
                                                monitor.Step (1);
 
135
                                        }
 
136
                                } finally {
 
137
                                        monitor.EndTask ();
 
138
                                }
 
139
                                
 
140
                                reader.ReadEndElement ();
 
141
                                return null;
 
142
                        }
 
143
                        
 
144
                        return base.ReadChild (reader, parent);
 
145
                }
 
146
                
 
147
                void CreateSolutionConfigurations (Solution sol)
 
148
                {
 
149
                        CombineConfigurationSet configs = (CombineConfigurationSet) sol.ExtendedProperties ["Configurations"];
 
150
                        foreach (CombineConfiguration config in configs.Configurations) {
 
151
                                SolutionConfiguration sconf = config.SolutionConfiguration ?? new SolutionConfiguration (config.Name);
 
152
                                sol.Configurations.Add (sconf);
 
153
                        }
 
154
                        
 
155
                        foreach (SolutionEntityItem item in sol.GetAllSolutionItems<SolutionEntityItem> ()) {
 
156
                                
 
157
                                List<IExtendedDataItem> chain = new List<IExtendedDataItem> ();
 
158
                                SolutionItem it = item;
 
159
                                while (it != null) {
 
160
                                        chain.Insert (0, it);
 
161
                                        it = it.ParentFolder;
 
162
                                }
 
163
                                chain [0] = sol;
 
164
                                
 
165
                                foreach (SolutionConfiguration sconfig in sol.Configurations) {
 
166
                                        SolutionConfigurationEntry se = sconfig.AddItem (item);
 
167
                                        string itemConfig = FindItemConfiguration (chain, sconfig.Id);
 
168
                                        if (itemConfig != null) {
 
169
                                                se.Build = true;
 
170
                                                se.ItemConfiguration = itemConfig;
 
171
                                        }
 
172
                                        else
 
173
                                                se.Build = false;
 
174
                                }
 
175
                        }
 
176
                        
 
177
                        sol.DefaultConfigurationId = configs.Active;
 
178
                }
 
179
                
 
180
                void LoadStartupMode (Solution sol)
 
181
                {
 
182
                        // Recursively look for startup items. If there is more than one,
 
183
                        // it means it is a multi startup solution.
 
184
                        List<SolutionEntityItem> items = new List<SolutionEntityItem> ();
 
185
                        FindStartupItems (sol, sol.RootFolder, items);
 
186
                        
 
187
                        if (items.Count == 1) {
 
188
                                sol.SingleStartup = true;
 
189
                                sol.StartupItem = items [0];
 
190
                        } else if (items.Count > 1) {
 
191
                                sol.SingleStartup = false;
 
192
                                sol.MultiStartupItems.AddRange (items);
 
193
                        }
 
194
                }
 
195
                
 
196
                void FindStartupItems (Solution sol, SolutionFolder folder, List<SolutionEntityItem> items)
 
197
                {
 
198
                        CombineStartupMode startupMode = (CombineStartupMode) folder.ExtendedProperties ["StartMode"];
 
199
                        if (startupMode != null) {
 
200
                                if (startupMode.SingleStartup) {
 
201
                                        SolutionItem it = FindItemByName (folder, startupMode.StartEntryName);
 
202
                                        if (it is SolutionFolder)
 
203
                                                FindStartupItems (sol, (SolutionFolder)it, items);
 
204
                                        else if (it is SolutionEntityItem)
 
205
                                                items.Add ((SolutionEntityItem) it);
 
206
                                        return;
 
207
                                } else {
 
208
                                        foreach (CombineStartupEntry cse in startupMode.Entries) {
 
209
                                                if (cse.Type == "Execute") {
 
210
                                                        SolutionItem it = FindItemByName (folder, cse.Entry);
 
211
                                                        if (it is SolutionFolder)
 
212
                                                                FindStartupItems (sol, (SolutionFolder)it, items);
 
213
                                                        else if (it is SolutionEntityItem)
 
214
                                                                items.Add ((SolutionEntityItem) it);
 
215
                                                }
 
216
                                        }
 
217
                                }
 
218
                        }
 
219
                }
 
220
                
 
221
                SolutionItem FindItemByName (SolutionFolder folder, string name)
 
222
                {
 
223
                        foreach (SolutionItem it in folder.Items)
 
224
                                if (it.Name == name)
 
225
                                        return it;
 
226
                        return null;
 
227
                }
 
228
                
 
229
                string FindItemConfiguration (List<IExtendedDataItem> chain, string configId)
 
230
                {
 
231
                        for (int n=0; n < chain.Count - 1; n++) {
 
232
                                CombineConfigurationSet configs = (CombineConfigurationSet) chain[n].ExtendedProperties ["Configurations"];
 
233
                                if (configs == null)
 
234
                                        return null;
 
235
                                SolutionItem item = (SolutionItem) chain [n+1];
 
236
                                CombineConfiguration combineConfig = configs.GetConfig (configId);
 
237
                                if (combineConfig == null) {
 
238
                                        monitor.ReportWarning ("Configuration '" + configId + "' not found in solution item '" + item.Name + "'.");
 
239
                                        return null;
 
240
                                }
 
241
                                string mappedConfigId = combineConfig.GetMappedConfig (item.Name);
 
242
                                if (mappedConfigId == null)
 
243
                                        return null;
 
244
                                if (mappedConfigId != string.Empty)
 
245
                                        configId = mappedConfigId;
 
246
                        }
 
247
                        return configId;
 
248
                }
 
249
        
 
250
                object ReadSolutionFolder (string file, IProgressMonitor monitor)
 
251
                {
 
252
                        XmlTextReader reader = new XmlTextReader (new StreamReader (file));
 
253
                        reader.MoveToContent ();
 
254
                        
 
255
                        string version = reader.GetAttribute ("version");
 
256
                        if (version == null)
 
257
                                version = reader.GetAttribute ("fileversion");
 
258
                        
 
259
                        DataSerializer serializer = new DataSerializer (MD1ProjectService.DataContext, file);
 
260
                        
 
261
                        try {
 
262
                                if (version != "2.0")
 
263
                                        throw new MD1UnknownProjectVersion (file, version);
 
264
                                ICombineReader combineReader = new CombineReaderV2 (serializer, monitor, typeof(SolutionFolder));
 
265
                                return combineReader.ReadCombine (reader);
 
266
                        } catch (Exception ex) {
 
267
                                monitor.ReportError (GettextCatalog.GetString ("Could not load solution: {0}", file), ex);
 
268
                                throw;
 
269
                        } finally {
 
270
                                reader.Close ();
 
271
                        }
 
272
                }
 
273
                
 
274
                protected override XmlConfigurationReader GetChildReader (MonoDevelop.Core.Serialization.DataItem parent)
 
275
                {
 
276
                        // Don't reuse this serializer for children, since it has solution-specific serialization code
 
277
                        return XmlConfigurationReader.DefaultReader;
 
278
                }
 
279
 
 
280
        }
 
281
        
 
282
        class CombineWriterV2: XmlConfigurationWriter
 
283
        {
 
284
                SolutionFolder folder;
 
285
                DataSerializer serializer;
 
286
                IProgressMonitor monitor;
 
287
                Type objectType;
 
288
                
 
289
                public CombineWriterV2 (DataSerializer serializer, IProgressMonitor monitor, Type objectType)
 
290
                {
 
291
                        this.serializer = serializer;
 
292
                        this.monitor = monitor;
 
293
                        this.objectType = objectType;
 
294
                }
 
295
 
 
296
                public void WriteCombine (XmlWriter writer, object item)
 
297
                {
 
298
                        if (item is Solution) {
 
299
                                Solution sol = (Solution) item;
 
300
                                folder = sol.RootFolder;
 
301
                                CreateCombineConfigurations (sol.RootFolder);
 
302
                                CreateStartupModes (sol);
 
303
                        }
 
304
                        else
 
305
                                folder = (SolutionFolder) item;
 
306
                        
 
307
                        DataItem data = (DataItem) serializer.Serialize (item, objectType);
 
308
                        
 
309
                        // Both combine and SolutionFolder use the same element name, but the types are different
 
310
                        if (data.Name == "SolutionFolder" && objectType == typeof(SolutionFolder))
 
311
                                data.Name = "Combine";
 
312
                        
 
313
                        Write (writer, data);
 
314
                }
 
315
                
 
316
                void CreateStartupModes (Solution sol)
 
317
                {
 
318
                        // Initialize the startup modes
 
319
                        ReadOnlyCollection<SolutionFolder> folders = sol.GetAllSolutionItems<SolutionFolder> ();
 
320
                        foreach (SolutionFolder folder in folders) {
 
321
                                CombineStartupMode startupMode = new CombineStartupMode ();
 
322
                                startupMode.SingleStartup = true;
 
323
                                startupMode.StartEntryName = null;
 
324
                                foreach (SolutionItem it in folder.Items)
 
325
                                        startupMode.AddEntry (it.Name);
 
326
                                folder.ExtendedProperties ["StartMode"] = startupMode;
 
327
                        }
 
328
                        
 
329
                        // Get the list of startup items
 
330
                        IEnumerable<SolutionEntityItem> items;
 
331
                        if (sol.SingleStartup)
 
332
                                items = new SolutionEntityItem [] { sol.StartupItem };
 
333
                        else
 
334
                                items = sol.MultiStartupItems;
 
335
 
 
336
                        // Setup the startup modes
 
337
                        foreach (SolutionEntityItem it in items) {
 
338
                                if (it == null)
 
339
                                        continue;
 
340
                                SolutionFolder folder = it.ParentFolder;
 
341
                                SolutionItem prevItem = it;
 
342
                                while (folder != null) {
 
343
                                        CombineStartupMode startupMode = (CombineStartupMode) folder.ExtendedProperties ["StartMode"];
 
344
                                        if (startupMode.SingleStartup) {
 
345
                                                // If a start entry is already set, convert to multi startup mode
 
346
                                                if (startupMode.StartEntryName == null)
 
347
                                                        startupMode.StartEntryName = prevItem.Name;
 
348
                                                else if (startupMode.StartEntryName != prevItem.Name) {
 
349
                                                        startupMode.SingleStartup = false;
 
350
                                                        startupMode.MakeExecutable (startupMode.StartEntryName);
 
351
                                                        startupMode.MakeExecutable (prevItem.Name);
 
352
                                                }
 
353
                                        } else {
 
354
                                                // Already multi startup, just add the new item
 
355
                                                startupMode.MakeExecutable (prevItem.Name);
 
356
                                        }
 
357
                                        prevItem = folder;
 
358
                                        folder = folder.ParentFolder;
 
359
                                }
 
360
                        }
 
361
                        
 
362
                        // Set the startup item for folders which don't have one
 
363
                        foreach (SolutionFolder folder in folders) {
 
364
                                CombineStartupMode startupMode = (CombineStartupMode) folder.ExtendedProperties ["StartMode"];
 
365
                                if (startupMode.SingleStartup && startupMode.StartEntryName == null) {
 
366
                                        if (folder.Items.Count > 0)
 
367
                                                startupMode.StartEntryName = folder.Items [0].Name;
 
368
                                }
 
369
                        }
 
370
                }
 
371
                
 
372
                void CreateCombineConfigurations (SolutionFolder folder)
 
373
                {
 
374
                        IDictionary extendedProperties = folder.ExtendedProperties;
 
375
                        
 
376
                        CombineConfigurationSet configs = CreateCombineConfigurationSet (folder.ParentSolution, folder.IsRoot);
 
377
                        configs.Active = folder.ParentSolution.DefaultConfigurationId;
 
378
                        
 
379
                        extendedProperties ["Configurations"] = configs;
 
380
 
 
381
                        foreach (SolutionItem it in folder.Items) {
 
382
                                
 
383
                                if (it is SolutionFolder) {
 
384
                                        foreach (SolutionConfiguration conf in folder.ParentSolution.Configurations) {
 
385
                                                CombineConfiguration cc = configs.GetConfig (conf.Id);
 
386
                                                CombineConfigurationEntry ce = new CombineConfigurationEntry (it.Name, true, conf.Id);
 
387
                                                cc.Entries.Add (ce);
 
388
                                        }
 
389
                                        CreateCombineConfigurations ((SolutionFolder) it);
 
390
                                }
 
391
                                else if (it is SolutionEntityItem) {
 
392
                                        SolutionEntityItem sit = (SolutionEntityItem) it;
 
393
                                        foreach (SolutionConfiguration conf in folder.ParentSolution.Configurations) {
 
394
                                                CombineConfiguration cc = configs.GetConfig (conf.Id);
 
395
                                                SolutionConfigurationEntry sce = conf.GetEntryForItem (sit);
 
396
                                                CombineConfigurationEntry ce = null;
 
397
                                                if (sce == null)
 
398
                                                        ce = new CombineConfigurationEntry (it.Name, true, conf.Id);
 
399
                                                else
 
400
                                                        ce = new CombineConfigurationEntry (it.Name, sce.Build, sce.ItemConfiguration);                                         
 
401
                                                cc.Entries.Add (ce);
 
402
                                        }
 
403
                                }
 
404
                        }
 
405
                }
 
406
                
 
407
                CombineConfigurationSet CreateCombineConfigurationSet (Solution sol, bool isRoot)
 
408
                {
 
409
                        CombineConfigurationSet cset = new CombineConfigurationSet ();
 
410
                        foreach (SolutionConfiguration conf in sol.Configurations) {
 
411
                                CombineConfiguration cc = new CombineConfiguration ();
 
412
                                cc.Name = conf.Id;
 
413
                                if (isRoot)
 
414
                                        cc.SolutionConfiguration = conf;
 
415
                                cset.Configurations.Add (cc);
 
416
                        }
 
417
                        return cset;
 
418
                }
 
419
                
 
420
                protected override void WriteChildren (XmlWriter writer, DataItem item)
 
421
                {
 
422
                        base.WriteChildren (writer, item);
 
423
 
 
424
                        writer.WriteStartElement ("Entries");
 
425
                        foreach (SolutionItem entry in folder.Items) {
 
426
                                writer.WriteStartElement ("Entry");
 
427
                                
 
428
                                string baseDir = Path.GetDirectoryName (serializer.SerializationContext.BaseFile);
 
429
                                string fname = null;
 
430
                                
 
431
                                if (entry is SolutionFolder) {
 
432
                                        SolutionFolder cfolder = (SolutionFolder) entry;
 
433
                                        fname = cfolder.ExtendedProperties ["FileName"] as string;
 
434
                                        if (fname == null) {
 
435
                                                // Guess a good file name for the mds file.
 
436
                                                if (Directory.Exists (Path.Combine (baseDir, cfolder.Name)))
 
437
                                                        fname = Path.Combine (Path.Combine (baseDir, cfolder.Name), cfolder.Name + ".mds");
 
438
                                                else
 
439
                                                        fname = Path.Combine (baseDir, cfolder.Name + ".mds");
 
440
                                        }
 
441
                                }
 
442
                                else if (entry is SolutionEntityItem) {
 
443
                                        fname = ((SolutionEntityItem)entry).FileName;
 
444
                                }
 
445
                                if (fname == null)
 
446
                                        throw new InvalidOperationException ("Don't know how to save item of type " + entry.GetType ());
 
447
                                
 
448
                                string relfname = FileService.AbsoluteToRelativePath (baseDir, fname);
 
449
                                writer.WriteAttributeString ("filename", relfname);
 
450
                                writer.WriteEndElement ();
 
451
                                if (entry is SolutionEntityItem)
 
452
                                        ((SolutionEntityItem)entry).Save (monitor);
 
453
                                else
 
454
                                        WriteSolutionFolder ((SolutionFolder) entry, fname, monitor);
 
455
                        }
 
456
                        writer.WriteEndElement ();
 
457
                }
 
458
                
 
459
                void WriteSolutionFolder (SolutionFolder folder, string file, IProgressMonitor monitor)
 
460
                {
 
461
                        StreamWriter sw = new StreamWriter (file);
 
462
                        try {
 
463
                                monitor.BeginTask (GettextCatalog.GetString ("Saving solution: {0}", file), 1);
 
464
                                XmlTextWriter tw = new XmlTextWriter (sw);
 
465
                                tw.Formatting = Formatting.Indented;
 
466
                                DataSerializer serializer = new DataSerializer (MD1ProjectService.DataContext, file);
 
467
                                CombineWriterV2 combineWriter = new CombineWriterV2 (serializer, monitor, typeof(SolutionFolder));
 
468
                                combineWriter.WriteCombine (tw, folder);
 
469
                        } catch (Exception ex) {
 
470
                                monitor.ReportError (GettextCatalog.GetString ("Could not save solution: {0}", file), ex);
 
471
                                throw;
 
472
                        } finally {
 
473
                                monitor.EndTask ();
 
474
                                sw.Close ();
 
475
                        }
 
476
                }
 
477
                
 
478
                protected override XmlConfigurationWriter GetChildWriter (MonoDevelop.Core.Serialization.DataNode data)
 
479
                {
 
480
                        // Don't reuse this serializer for children, since it has solution-specific serialization code
 
481
                        return XmlConfigurationWriter.DefaultWriter;
 
482
                }
 
483
 
 
484
        }
 
485
}