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.
32
using System.Collections.Specialized;
33
using Mono.Addins.Serialization;
35
namespace Mono.Addins.Description
38
/// An extension definition.
41
/// An Extension is a collection of nodes which have to be registered in an extension point.
42
/// The target extension point is specified in the <see cref="Mono.Addins.Description.Extension"/>.Path property.
44
public class Extension: ObjectDescription, IComparable
47
ExtensionNodeDescriptionCollection nodes;
50
/// Initializes a new instance of the <see cref="Mono.Addins.Description.Extension"/> class.
57
/// Initializes a new instance of the <see cref="Mono.Addins.Description.Extension"/> class.
59
/// <param name='path'>
60
/// Path that identifies the extension point being extended
62
public Extension (string path)
68
/// Gets the object extended by this extension
71
/// The extended object can be an <see cref="Mono.Addins.Description.ExtensionPoint"/> or
72
/// an <see cref="Mono.Addins.Description.ExtensionNodeDescription"/>.
75
/// This method only works when the add-in description to which the extension belongs has been
76
/// loaded from an add-in registry.
78
public ObjectDescription GetExtendedObject ()
80
AddinDescription desc = ParentAddinDescription;
83
ExtensionPoint ep = FindExtensionPoint (desc, path);
84
if (ep == null && desc.OwnerDatabase != null) {
85
foreach (Dependency dep in desc.MainModule.Dependencies) {
86
AddinDependency adep = dep as AddinDependency;
87
if (adep == null) continue;
88
Addin ad = desc.OwnerDatabase.GetInstalledAddin (ParentAddinDescription.Domain, adep.FullAddinId);
89
if (ad != null && ad.Description != null) {
90
ep = FindExtensionPoint (ad.Description, path);
97
string subp = path.Substring (ep.Path.Length).Trim ('/');
99
return ep; // The extension is directly extending the extension point
101
// The extension is extending a node of the extension point
103
return desc.FindExtensionNode (path, true);
109
/// Gets the node types allowed in this extension.
112
/// The allowed node types.
115
/// This method only works when the add-in description to which the extension belongs has been
116
/// loaded from an add-in registry.
118
public ExtensionNodeTypeCollection GetAllowedNodeTypes ()
120
ObjectDescription ob = GetExtendedObject ();
121
ExtensionPoint ep = ob as ExtensionPoint;
123
return ep.NodeSet.GetAllowedNodeTypes ();
125
ExtensionNodeDescription node = ob as ExtensionNodeDescription;
127
ExtensionNodeType nt = node.GetNodeType ();
129
return nt.GetAllowedNodeTypes ();
131
return new ExtensionNodeTypeCollection ();
134
ExtensionPoint FindExtensionPoint (AddinDescription desc, string path)
136
foreach (ExtensionPoint ep in desc.ExtensionPoints) {
137
if (ep.Path == path || path.StartsWith (ep.Path + "/"))
143
internal override void Verify (string location, StringCollection errors)
145
VerifyNotEmpty (location + "Extension", errors, path, "path");
146
ExtensionNodes.Verify (location + "Extension (" + path + ")/", errors);
148
foreach (ExtensionNodeDescription cnode in ExtensionNodes)
149
VerifyNode (location, cnode, errors);
152
void VerifyNode (string location, ExtensionNodeDescription node, StringCollection errors)
154
string id = node.GetAttribute ("id");
157
if (node.NodeName == "Condition" && node.GetAttribute ("id").Length == 0) {
158
errors.Add (location + node.NodeName + id + ": Missing 'id' attribute in Condition element.");
160
if (node.NodeName == "ComplexCondition") {
161
if (node.ChildNodes.Count > 0) {
162
VerifyConditionNode (location, node.ChildNodes[0], errors);
163
for (int n=1; n<node.ChildNodes.Count; n++)
164
VerifyNode (location + node.NodeName + id + "/", node.ChildNodes[n], errors);
167
errors.Add (location + "ComplexCondition: Missing child condition in ComplexCondition element.");
169
foreach (ExtensionNodeDescription cnode in node.ChildNodes)
170
VerifyNode (location + node.NodeName + id + "/", cnode, errors);
173
void VerifyConditionNode (string location, ExtensionNodeDescription node, StringCollection errors)
175
string nodeName = node.NodeName;
176
if (nodeName != "Or" && nodeName != "And" && nodeName != "Not" && nodeName != "Condition") {
177
errors.Add (location + "ComplexCondition: Invalid condition element: " + nodeName);
180
foreach (ExtensionNodeDescription cnode in node.ChildNodes)
181
VerifyConditionNode (location, cnode, errors);
185
/// Initializes a new instance of the <see cref="Mono.Addins.Description.Extension"/> class.
187
/// <param name='element'>
188
/// XML that describes the extension.
190
public Extension (XmlElement element)
193
path = element.GetAttribute ("path");
197
/// Gets or sets the path that identifies the extension point being extended.
204
set { path = value; }
207
internal override void SaveXml (XmlElement parent)
209
if (Element == null) {
210
Element = parent.OwnerDocument.CreateElement ("Extension");
211
parent.AppendChild (Element);
213
Element.SetAttribute ("path", path);
215
nodes.SaveXml (Element);
219
/// Gets the extension nodes.
222
/// The extension nodes.
224
public ExtensionNodeDescriptionCollection ExtensionNodes {
227
nodes = new ExtensionNodeDescriptionCollection (this);
228
if (Element != null) {
229
foreach (XmlNode node in Element.ChildNodes) {
230
XmlElement e = node as XmlElement;
232
nodes.Add (new ExtensionNodeDescription (e));
240
int IComparable.CompareTo (object obj)
242
Extension other = (Extension) obj;
243
return Path.CompareTo (other.Path);
246
internal override void Write (BinaryXmlWriter writer)
248
writer.WriteValue ("path", path);
249
writer.WriteValue ("Nodes", ExtensionNodes);
252
internal override void Read (BinaryXmlReader reader)
254
path = reader.ReadStringValue ("path");
255
nodes = (ExtensionNodeDescriptionCollection) reader.ReadValue ("Nodes", new ExtensionNodeDescriptionCollection (this));