Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / tools / monkeydoc / Monkeydoc / providers / addins-provider.cs
1 // addins-provider.cs
2 //
3 // A provider to display Mono.Addins extension models
4 //
5 // Author:
6 //   Lluis Sanchez Gual <lluis@novell.com>
7 //
8 // Copyright (c) 2007 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 // THE SOFTWARE.
27 //
28 //
29
30 using System;
31 using System.Diagnostics;
32 using System.Text;
33 using System.IO;
34 using System.Xml;
35
36 namespace Monodoc
37
38
39         //
40         // The simple provider generates the information source
41         //
42         public class AddinsProvider : Provider
43         {
44                 string file;
45                 
46                 public AddinsProvider (string xmlModelFile)
47                 {
48                         file = xmlModelFile;
49                         
50                         if (!File.Exists (file))
51                                 throw new FileNotFoundException (String.Format ("The file `{0}' does not exist", file));
52                 }
53
54                 public override void PopulateTree (Tree tree)
55                 {
56                         string fileId = tree.tree.HelpSource.PackFile (file);
57                         XmlDocument doc = new XmlDocument ();
58                         doc.Load (file);
59                         
60                         foreach (XmlElement addin in doc.SelectNodes ("Addins/Addin")) {
61
62                                 string addinId = addin.GetAttribute ("fullId");
63                                 Node newNode = tree.CreateNode (addin.GetAttribute ("name"), "addin:" + fileId + "#" + addinId);
64
65                                 foreach (XmlElement node in addin.SelectNodes ("ExtensionPoint")) {
66                                         string target = "extension-point:" + fileId + "#" + addinId + "#" + node.GetAttribute ("path");
67                                         Node newExt = newNode.CreateNode (node.GetAttribute ("name"), target);
68                         
69                                         foreach (XmlElement en in node.SelectNodes ("ExtensionNode")) {
70                                                 string nid = en.GetAttribute ("id");
71                                                 string nname = en.GetAttribute ("name");
72                                                 newExt.CreateNode (nname, "extension-node:" + fileId + "#" + addinId + "#" + nid);
73                                         }
74                                 }
75                         }
76                 }
77
78
79                 public override void CloseTree (HelpSource hs, Tree tree)
80                 {
81                 }
82         }
83
84         //
85         // The HelpSource is used during the rendering phase.
86         //
87
88         public class AddinsHelpSource : HelpSource
89         {
90                 public AddinsHelpSource (string base_file, bool create) : base (base_file, create) 
91                 {
92                 }
93                 
94                 protected const string AddinPrefix = "addin:";
95                 protected const string ExtensionPrefix = "extension-point:";
96                 protected const string ExtensionNodePrefix = "extension-node:";
97                 
98                 public override string GetText (string url, out Node match_node)
99                 {
100                         match_node = null;
101
102                         string c = GetCachedText (url);
103                         if (c != null)
104                                 return c;
105
106                         if (url.StartsWith (AddinPrefix))
107                                 return GetAddinTextFromUrl (url);
108                         else if (url.StartsWith (ExtensionPrefix))
109                                 return GetExtensionTextFromUrl (url);
110                         else if (url.StartsWith (ExtensionNodePrefix))
111                                 return GetExtensionNodeTextFromUrl (url);
112
113                         return null;
114                 }
115                 
116                 protected string GetAddinTextFromUrl (string url)
117                 {
118                         // Remove "addin:" prefix including any help-source id on the front.
119                         url = url.Substring (AddinPrefix.Length);
120                         int i = url.IndexOf ('#');
121
122                         if (i == -1) {
123                                 Message (TraceLevel.Warning, "Warning, NULL url!");
124                                 return "<html>Invalid url</html>";
125                         }
126                         
127                         string fileId = url.Substring (0, i);
128                         string addinId = url.Substring (i+1);
129
130                         XmlElement addin = GetAddin (fileId, addinId);
131                         if (addin == null)
132                                 return "<html>Add-in not found: " + addinId + "</html>";
133                         
134                         StringBuilder sb = new StringBuilder ("<html>");
135                         sb.Append ("<h1>").Append (addin.GetAttribute ("name")).Append ("</h1>");
136                         XmlElement docs = (XmlElement) addin.SelectSingleNode ("Description");
137                         if (docs != null)
138                                 sb.Append (docs.InnerText);
139
140                         sb.Append ("<p><table border=\"1\" cellpadding=\"4\" cellspacing=\"0\">");
141                         sb.AppendFormat ("<tr><td><b>Id</b></td><td>{0}</td></tr>", addin.GetAttribute ("addinId"));
142                         sb.AppendFormat ("<tr><td><b>Namespace</b></td><td>{0}</td></tr>", addin.GetAttribute ("namespace"));
143                         sb.AppendFormat ("<tr><td><b>Version</b></td><td>{0}</td></tr>", addin.GetAttribute ("version"));
144                         sb.Append ("</table></p>");
145                         sb.Append ("<p><b>Extension Points</b>:</p>");
146                         sb.Append ("<ul>");
147                         
148                         foreach (XmlElement ep in addin.SelectNodes ("ExtensionPoint")) {
149                                 sb.AppendFormat ("<li><a href=\"extension-point:{0}#{1}#{2}\">{3}</li>", fileId, addinId, ep.GetAttribute ("path"), ep.GetAttribute ("name"));
150                         }
151                         sb.Append ("</ul>");
152                         
153                         sb.Append ("</html>");
154                         return sb.ToString ();
155                 }
156                 
157                 protected string GetExtensionTextFromUrl (string url)
158                 {
159                         // Remove "addin:" prefix including any help-source id on the front.
160                         url = url.Substring (ExtensionPrefix.Length);
161                         int i = url.IndexOf ('#');
162
163                         if (i == -1) {
164                                 Message (TraceLevel.Warning, "Warning, NULL url!");
165                                 return "<html>Invalid url</html>";
166                         }
167                         
168                         string fileId = url.Substring (0, i);
169                         
170                         int j = url.IndexOf ('#', i+1);
171                         string addinId = url.Substring (i+1, j-i-1);
172                         string path = url.Substring (j+1);
173
174                         XmlElement addin = GetAddin (fileId, addinId);
175                         if (addin == null)
176                                 return "<html>Add-in not found: " + addinId + "</html>";
177                         
178                         XmlElement ext = (XmlElement) addin.SelectSingleNode ("ExtensionPoint[@path='" + path + "']");
179                         if (ext == null)
180                                 return "<html>Extension point not found: " + path + "</html>";
181                         
182                         StringBuilder sb = new StringBuilder ("<html>");
183                         sb.Append ("<h1>").Append (ext.GetAttribute ("name")).Append ("</h1>");
184
185                         path = path.Replace ("/", " <b>/</b> ");
186                         sb.Append ("<p><b>Path</b>: ").Append (path).Append ("</p>");
187                         XmlElement desc = (XmlElement) ext.SelectSingleNode ("Description");
188                         if (desc != null)
189                                 sb.Append (desc.InnerText);
190
191                         sb.Append ("<p><b>Extension Nodes</b>:</p>");
192                         sb.Append ("<table border=\"1\" cellpadding=\"4\" cellspacing=\"0\">");
193                         
194                         foreach (XmlElement en in ext.SelectNodes ("ExtensionNode")) {
195                                 string nid = en.GetAttribute ("id");
196                                 string nname = en.GetAttribute ("name"); 
197                                 string sdesc = "";
198                                 desc = (XmlElement) en.SelectSingleNode ("Description");
199                                 if (desc != null)
200                                         sdesc = desc.InnerText;
201                                 
202                                 sb.AppendFormat ("<tr><td><a href=\"extension-node:{0}#{1}#{2}\">{3}</td><td>{4}</td></tr>", fileId, addinId, nid, nname, sdesc);
203                         }
204                         sb.Append ("</table>");
205                         
206                         sb.Append ("</html>");
207                         return sb.ToString ();
208                 }
209                 
210                 protected string GetExtensionNodeTextFromUrl (string url)
211                 {
212                         // Remove "addin:" prefix including any help-source id on the front.
213                         url = url.Substring (ExtensionNodePrefix.Length);
214                         int i = url.IndexOf ('#');
215
216                         if (i == -1) {
217                                 Message (TraceLevel.Warning, "Warning, NULL url!");
218                                 return "<html>Invalid url</html>";
219                         }
220                         
221                         string fileId = url.Substring (0, i);
222                         
223                         int j = url.IndexOf ('#', i+1);
224                         string addinId = url.Substring (i+1, j-i-1);
225                         string nodeId = url.Substring (j+1);
226
227                         XmlElement addin = GetAddin (fileId, addinId);
228                         if (addin == null)
229                                 return "<html>Add-in not found: " + addinId + "</html>";
230                         
231                         XmlElement node = (XmlElement) addin.SelectSingleNode ("ExtensionNodeType[@id='" + nodeId + "']");
232                         if (node == null)
233                                 return "<html>Extension point not found: " + nodeId + "</html>";
234                         
235                         StringBuilder sb = new StringBuilder ("<html>");
236                         sb.Append ("<h1>").Append (node.GetAttribute ("name")).Append ("</h1>");
237                         XmlElement desc = (XmlElement) node.SelectSingleNode ("Description");
238                         if (desc != null)
239                                 sb.Append (desc.InnerText);
240
241                         sb.Append ("<p><b>Attributes</b>:</p>");
242                         sb.Append ("<table border=\"1\" cellpadding=\"4\" cellspacing=\"0\"><tr>");
243                         sb.Append ("<td><b>Name</b></td>");
244                         sb.Append ("<td><b>Type</b></td>");
245                         sb.Append ("<td><b>Required</b></td>");
246                         sb.Append ("<td><b>Localizable</b></td>");
247                         sb.Append ("<td><b>Description</b></td>");
248                         sb.Append ("<tr>");
249                         sb.Append ("<td>id</td>");
250                         sb.Append ("<td>System.String</td>");
251                         sb.Append ("<td></td>");
252                         sb.Append ("<td></td>");
253                         sb.Append ("<td>Identifier of the node.</td>");
254                         sb.Append ("</tr>");
255                         
256                         foreach (XmlElement at in node.SelectNodes ("Attributes/Attribute")) {
257                                 sb.Append ("<tr>");
258                                 sb.AppendFormat ("<td>{0}</td>", at.GetAttribute ("name"));
259                                 sb.AppendFormat ("<td>{0}</td>", at.GetAttribute ("type"));
260                                 if (at.GetAttribute ("required") == "True")
261                                         sb.Append ("<td>Yes</td>");
262                                 else
263                                         sb.Append ("<td></td>");
264                                 if (at.GetAttribute ("localizable") == "True")
265                                         sb.Append ("<td>Yes</td>");
266                                 else
267                                         sb.Append ("<td></td>");
268                                 string sdesc = "";
269                                 desc = (XmlElement) at.SelectSingleNode ("Description");
270                                 if (desc != null)
271                                         sdesc = desc.InnerText;
272                                 
273                                 sb.AppendFormat ("<td>{0}</td>", sdesc);
274                                 sb.Append ("</tr>");
275                         }
276                         sb.Append ("</table>");
277
278                         XmlNodeList children = node.SelectNodes ("ChildNodes/ExtensionNode");
279                         if (children.Count > 0) {
280                                 sb.Append ("<p><b>Child Nodes</b>:</p>");
281                                 sb.Append ("<table border=\"1\" cellpadding=\"4\" cellspacing=\"0\">");
282                                 
283                                 foreach (XmlElement en in children) {
284                                         string nid = en.GetAttribute ("id");
285                                         string nname = en.GetAttribute ("name"); 
286                                         string sdesc = "";
287                                         desc = (XmlElement) en.SelectSingleNode ("Description");
288                                         if (desc != null)
289                                                 sdesc = desc.InnerText;
290                                         
291                                         sb.AppendFormat ("<tr><td><a href=\"extension-node:{0}#{1}#{2}\">{3}</td><td>{4}</td></tr>", fileId, addinId, nid, nname, sdesc);
292                                 }
293                                 sb.Append ("</table>");
294                         }
295                         
296                         sb.Append ("</html>");
297                         return sb.ToString ();
298                 }
299                 
300                 XmlElement GetAddin (string fileId, string addinId)
301                 {
302                         Stream s = GetHelpStream (fileId);
303                         StreamReader file;
304                         using (file = new StreamReader (s)) {
305                                 XmlDocument doc = new XmlDocument ();
306                                 doc.Load (file);
307                                 XmlElement addin = (XmlElement) doc.SelectSingleNode ("Addins/Addin[@fullId='" + addinId + "']");
308                                 if (addin != null)
309                                         return addin;
310                                 else
311                                         return null;
312                         }
313                 }
314         }
315 }