2
// ModuleDescription.cs
7
// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
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:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
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.
30
using System.Collections;
33
using System.Xml.Serialization;
34
using System.Collections.Specialized;
35
using Mono.Addins.Serialization;
37
namespace Mono.Addins.Description
40
/// A module definition.
43
/// Optional modules can be used to declare extensions which will be registered only if some
44
/// specified add-in dependencies can be satisfied.
46
public class ModuleDescription: ObjectDescription
48
StringCollection assemblies;
49
StringCollection dataFiles;
50
StringCollection ignorePaths;
51
DependencyCollection dependencies;
52
ExtensionCollection extensions;
54
// Used only at run time
55
internal RuntimeAddin RuntimeAddin;
57
internal ModuleDescription (XmlElement element)
63
/// Initializes a new instance of the <see cref="Mono.Addins.Description.ModuleDescription"/> class.
65
public ModuleDescription ()
70
/// Checks if this module depends on the specified add-in.
73
/// <c>true</c> if there is a dependency.
75
/// <param name='addinId'>
76
/// Identifier of the add-in
78
public bool DependsOnAddin (string addinId)
80
AddinDescription desc = Parent as AddinDescription;
82
throw new InvalidOperationException ();
84
foreach (Dependency dep in Dependencies) {
85
AddinDependency adep = dep as AddinDependency;
86
if (adep == null) continue;
87
if (Addin.GetFullId (desc.Namespace, adep.AddinId, adep.Version) == addinId)
94
/// Gets the list of paths to be ignored by the add-in scanner.
96
public StringCollection IgnorePaths {
98
if (ignorePaths == null)
99
ignorePaths = new StringCollection ();
105
/// Gets all external files
111
/// External files are data files and assemblies explicitly referenced in the Runtime section of the add-in manifest.
113
public StringCollection AllFiles {
115
StringCollection col = new StringCollection ();
116
foreach (string s in Assemblies)
119
foreach (string d in DataFiles)
127
/// Gets the list of external assemblies used by this module.
129
public StringCollection Assemblies {
131
if (assemblies == null) {
135
assemblies = new StringCollection ();
142
/// Gets the list of external data files used by this module
144
public StringCollection DataFiles {
146
if (dataFiles == null) {
150
dataFiles = new StringCollection ();
157
/// Gets the dependencies of this module
159
public DependencyCollection Dependencies {
161
if (dependencies == null) {
162
dependencies = new DependencyCollection (this);
163
if (Element != null) {
164
XmlNodeList elems = Element.SelectNodes ("Dependencies/*");
166
foreach (XmlNode node in elems) {
167
XmlElement elem = node as XmlElement;
168
if (elem == null) continue;
170
if (elem.Name == "Addin") {
171
AddinDependency dep = new AddinDependency (elem);
172
dependencies.Add (dep);
173
} else if (elem.Name == "Assembly") {
174
AssemblyDependency dep = new AssemblyDependency (elem);
175
dependencies.Add (dep);
185
/// Gets the extensions of this module
187
public ExtensionCollection Extensions {
189
if (extensions == null) {
190
extensions = new ExtensionCollection (this);
191
if (Element != null) {
192
foreach (XmlElement elem in Element.SelectNodes ("Extension"))
193
extensions.Add (new Extension (elem));
201
/// Adds an extension node to the module.
204
/// The extension node.
206
/// <param name='path'>
207
/// Path that identifies the extension point.
209
/// <param name='nodeName'>
213
/// This method creates a new Extension object for the provided path if none exist.
215
public ExtensionNodeDescription AddExtensionNode (string path, string nodeName)
217
ExtensionNodeDescription node = new ExtensionNodeDescription (nodeName);
218
GetExtension (path).ExtensionNodes.Add (node);
223
/// Gets an extension instance.
226
/// The extension instance.
228
/// <param name='path'>
229
/// Path that identifies the extension point that the extension extends.
232
/// This method creates a new Extension object for the provided path if none exist.
234
public Extension GetExtension (string path)
236
foreach (Extension e in Extensions) {
240
Extension ex = new Extension (path);
245
internal override void SaveXml (XmlElement parent)
247
CreateElement (parent, "Module");
249
if (assemblies != null || dataFiles != null || ignorePaths != null) {
250
XmlElement runtime = GetRuntimeElement ();
252
while (runtime.FirstChild != null)
253
runtime.RemoveChild (runtime.FirstChild);
255
if (assemblies != null) {
256
foreach (string s in assemblies) {
257
XmlElement asm = Element.OwnerDocument.CreateElement ("Import");
258
asm.SetAttribute ("assembly", s);
259
runtime.AppendChild (asm);
262
if (dataFiles != null) {
263
foreach (string s in dataFiles) {
264
XmlElement asm = Element.OwnerDocument.CreateElement ("Import");
265
asm.SetAttribute ("file", s);
266
runtime.AppendChild (asm);
269
if (ignorePaths != null) {
270
foreach (string s in ignorePaths) {
271
XmlElement asm = Element.OwnerDocument.CreateElement ("ScanExclude");
272
asm.SetAttribute ("path", s);
273
runtime.AppendChild (asm);
276
runtime.AppendChild (Element.OwnerDocument.CreateTextNode ("\n"));
279
// Save dependency information
281
if (dependencies != null) {
282
XmlElement deps = GetDependenciesElement ();
283
dependencies.SaveXml (deps);
284
deps.AppendChild (Element.OwnerDocument.CreateTextNode ("\n"));
286
if (extensions != null)
287
extensions.SaveXml (Element);
292
/// Adds an add-in reference (there is a typo in the method name)
294
/// <param name='id'>
295
/// Identifier of the add-in.
297
/// <param name='version'>
298
/// Version of the add-in.
300
public void AddAssemblyReference (string id, string version)
302
XmlElement deps = GetDependenciesElement ();
303
if (deps.SelectSingleNode ("Addin[@id='" + id + "']") != null)
306
XmlElement dep = Element.OwnerDocument.CreateElement ("Addin");
307
dep.SetAttribute ("id", id);
308
dep.SetAttribute ("version", version);
309
deps.AppendChild (dep);
312
XmlElement GetDependenciesElement ()
314
XmlElement de = Element ["Dependencies"];
318
de = Element.OwnerDocument.CreateElement ("Dependencies");
319
Element.AppendChild (de);
323
XmlElement GetRuntimeElement ()
325
XmlElement de = Element ["Runtime"];
329
de = Element.OwnerDocument.CreateElement ("Runtime");
330
Element.AppendChild (de);
334
void InitCollections ()
336
dataFiles = new StringCollection ();
337
assemblies = new StringCollection ();
339
XmlNodeList elems = Element.SelectNodes ("Runtime/*");
340
foreach (XmlElement elem in elems) {
341
if (elem.LocalName == "Import") {
342
string asm = elem.GetAttribute ("assembly");
343
if (asm.Length > 0) {
344
assemblies.Add (asm);
346
string file = elem.GetAttribute ("file");
348
dataFiles.Add (file);
350
} else if (elem.LocalName == "ScanExclude") {
351
string path = elem.GetAttribute ("path");
353
IgnorePaths.Add (path);
358
internal override void Verify (string location, StringCollection errors)
360
Dependencies.Verify (location + "Module/", errors);
361
Extensions.Verify (location + "Module/", errors);
364
internal override void Write (BinaryXmlWriter writer)
366
writer.WriteValue ("Assemblies", Assemblies);
367
writer.WriteValue ("DataFiles", DataFiles);
368
writer.WriteValue ("Dependencies", Dependencies);
369
writer.WriteValue ("Extensions", Extensions);
370
writer.WriteValue ("IgnorePaths", ignorePaths);
373
internal override void Read (BinaryXmlReader reader)
375
assemblies = (StringCollection) reader.ReadValue ("Assemblies", new StringCollection ());
376
dataFiles = (StringCollection) reader.ReadValue ("DataFiles", new StringCollection ());
377
dependencies = (DependencyCollection) reader.ReadValue ("Dependencies", new DependencyCollection (this));
378
extensions = (ExtensionCollection) reader.ReadValue ("Extensions", new ExtensionCollection (this));
379
ignorePaths = (StringCollection) reader.ReadValue ("IgnorePaths", new StringCollection ());