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
37
public class Extension: ObjectDescription, IComparable
40
ExtensionNodeDescriptionCollection nodes;
46
public Extension (string path)
51
// Returns the object extended by this Extension. It can be an ExtensionPoint or
52
// an ExtensionNodeDescription.
53
public ObjectDescription GetExtendedObject ()
55
AddinDescription desc = ParentAddinDescription;
58
ExtensionPoint ep = FindExtensionPoint (desc, path);
59
if (ep == null && desc.OwnerDatabase != null) {
60
foreach (Dependency dep in desc.MainModule.Dependencies) {
61
AddinDependency adep = dep as AddinDependency;
62
if (adep == null) continue;
63
Addin ad = desc.OwnerDatabase.GetInstalledAddin (adep.FullAddinId);
64
if (ad != null && ad.Description != null) {
65
ep = FindExtensionPoint (ad.Description, path);
72
string subp = path.Substring (ep.Path.Length).Trim ('/');
74
return ep; // The extension is directly extending the extension point
76
// The extension is extending a node of the extension point
78
return desc.FindExtensionNode (path, true);
83
public ExtensionNodeTypeCollection GetAllowedNodeTypes ()
85
ObjectDescription ob = GetExtendedObject ();
86
ExtensionPoint ep = ob as ExtensionPoint;
88
return ep.NodeSet.GetAllowedNodeTypes ();
90
ExtensionNodeDescription node = ob as ExtensionNodeDescription;
92
ExtensionNodeType nt = node.GetNodeType ();
94
return nt.GetAllowedNodeTypes ();
96
return new ExtensionNodeTypeCollection ();
99
ExtensionPoint FindExtensionPoint (AddinDescription desc, string path)
101
foreach (ExtensionPoint ep in desc.ExtensionPoints) {
102
if (ep.Path == path || path.StartsWith (ep.Path + "/"))
108
internal override void Verify (string location, StringCollection errors)
110
VerifyNotEmpty (location + "Extension", errors, path, "path");
111
ExtensionNodes.Verify (location + "Extension (" + path + ")/", errors);
113
foreach (ExtensionNodeDescription cnode in ExtensionNodes)
114
VerifyNode (location, cnode, errors);
117
void VerifyNode (string location, ExtensionNodeDescription node, StringCollection errors)
119
string id = node.GetAttribute ("id");
122
if (node.NodeName == "Condition" && node.GetAttribute ("id").Length == 0) {
123
errors.Add (location + node.NodeName + id + ": Missing 'id' attribute in Condition element.");
125
if (node.NodeName == "ComplexCondition") {
126
if (node.ChildNodes.Count > 0) {
127
VerifyConditionNode (location, node.ChildNodes[0], errors);
128
for (int n=1; n<node.ChildNodes.Count; n++)
129
VerifyNode (location + node.NodeName + id + "/", node.ChildNodes[n], errors);
132
errors.Add (location + "ComplexCondition: Missing child condition in ComplexCondition element.");
134
foreach (ExtensionNodeDescription cnode in node.ChildNodes)
135
VerifyNode (location + node.NodeName + id + "/", cnode, errors);
138
void VerifyConditionNode (string location, ExtensionNodeDescription node, StringCollection errors)
140
string nodeName = node.NodeName;
141
if (nodeName != "Or" && nodeName != "And" && nodeName != "Condition") {
142
errors.Add (location + "ComplexCondition: Invalid condition element: " + nodeName);
145
foreach (ExtensionNodeDescription cnode in node.ChildNodes)
146
VerifyConditionNode (location, cnode, errors);
149
public Extension (XmlElement element)
152
path = element.GetAttribute ("path");
157
set { path = value; }
160
internal override void SaveXml (XmlElement parent)
162
if (Element == null) {
163
Element = parent.OwnerDocument.CreateElement ("Extension");
164
parent.AppendChild (Element);
166
Element.SetAttribute ("path", path);
168
nodes.SaveXml (Element);
171
public ExtensionNodeDescriptionCollection ExtensionNodes {
174
nodes = new ExtensionNodeDescriptionCollection (this);
175
if (Element != null) {
176
foreach (XmlNode node in Element.ChildNodes) {
177
XmlElement e = node as XmlElement;
179
nodes.Add (new ExtensionNodeDescription (e));
187
int IComparable.CompareTo (object obj)
189
Extension other = (Extension) obj;
190
return Path.CompareTo (other.Path);
193
internal override void Write (BinaryXmlWriter writer)
195
writer.WriteValue ("path", path);
196
writer.WriteValue ("Nodes", ExtensionNodes);
199
internal override void Read (BinaryXmlReader reader)
201
path = reader.ReadStringValue ("path");
202
nodes = (ExtensionNodeDescriptionCollection) reader.ReadValue ("Nodes", new ExtensionNodeDescriptionCollection (this));