// addins-provider.cs
//
// A provider to display Mono.Addins extension models
//
// Author:
// Lluis Sanchez Gual
//
// Copyright (c) 2007 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
using System;
using System.Diagnostics;
using System.Text;
using System.IO;
using System.Xml;
namespace Monodoc
{
//
// The simple provider generates the information source
//
public class AddinsProvider : Provider
{
string file;
public AddinsProvider (string xmlModelFile)
{
file = xmlModelFile;
if (!File.Exists (file))
throw new FileNotFoundException (String.Format ("The file `{0}' does not exist", file));
}
public override void PopulateTree (Tree tree)
{
string fileId = tree.tree.HelpSource.PackFile (file);
XmlDocument doc = new XmlDocument ();
doc.Load (file);
foreach (XmlElement addin in doc.SelectNodes ("Addins/Addin")) {
string addinId = addin.GetAttribute ("fullId");
Node newNode = tree.CreateNode (addin.GetAttribute ("name"), "addin:" + fileId + "#" + addinId);
foreach (XmlElement node in addin.SelectNodes ("ExtensionPoint")) {
string target = "extension-point:" + fileId + "#" + addinId + "#" + node.GetAttribute ("path");
Node newExt = newNode.CreateNode (node.GetAttribute ("name"), target);
foreach (XmlElement en in node.SelectNodes ("ExtensionNode")) {
string nid = en.GetAttribute ("id");
string nname = en.GetAttribute ("name");
newExt.CreateNode (nname, "extension-node:" + fileId + "#" + addinId + "#" + nid);
}
}
}
}
public override void CloseTree (HelpSource hs, Tree tree)
{
}
}
//
// The HelpSource is used during the rendering phase.
//
public class AddinsHelpSource : HelpSource
{
public AddinsHelpSource (string base_file, bool create) : base (base_file, create)
{
}
protected const string AddinPrefix = "addin:";
protected const string ExtensionPrefix = "extension-point:";
protected const string ExtensionNodePrefix = "extension-node:";
public override string GetText (string url, out Node match_node)
{
match_node = null;
string c = GetCachedText (url);
if (c != null)
return c;
if (url.StartsWith (AddinPrefix))
return GetAddinTextFromUrl (url);
else if (url.StartsWith (ExtensionPrefix))
return GetExtensionTextFromUrl (url);
else if (url.StartsWith (ExtensionNodePrefix))
return GetExtensionNodeTextFromUrl (url);
return null;
}
protected string GetAddinTextFromUrl (string url)
{
// Remove "addin:" prefix including any help-source id on the front.
url = url.Substring (AddinPrefix.Length);
int i = url.IndexOf ('#');
if (i == -1) {
Message (TraceLevel.Warning, "Warning, NULL url!");
return "Invalid url";
}
string fileId = url.Substring (0, i);
string addinId = url.Substring (i+1);
XmlElement addin = GetAddin (fileId, addinId);
if (addin == null)
return "Add-in not found: " + addinId + "";
StringBuilder sb = new StringBuilder ("");
sb.Append ("").Append (addin.GetAttribute ("name")).Append ("
");
XmlElement docs = (XmlElement) addin.SelectSingleNode ("Description");
if (docs != null)
sb.Append (docs.InnerText);
sb.Append ("");
sb.AppendFormat ("Id | {0} |
", addin.GetAttribute ("addinId"));
sb.AppendFormat ("Namespace | {0} |
", addin.GetAttribute ("namespace"));
sb.AppendFormat ("Version | {0} |
", addin.GetAttribute ("version"));
sb.Append ("
");
sb.Append ("Extension Points:
");
sb.Append ("");
foreach (XmlElement ep in addin.SelectNodes ("ExtensionPoint")) {
sb.AppendFormat ("- {3}
", fileId, addinId, ep.GetAttribute ("path"), ep.GetAttribute ("name"));
}
sb.Append ("
");
sb.Append ("");
return sb.ToString ();
}
protected string GetExtensionTextFromUrl (string url)
{
// Remove "addin:" prefix including any help-source id on the front.
url = url.Substring (ExtensionPrefix.Length);
int i = url.IndexOf ('#');
if (i == -1) {
Message (TraceLevel.Warning, "Warning, NULL url!");
return "Invalid url";
}
string fileId = url.Substring (0, i);
int j = url.IndexOf ('#', i+1);
string addinId = url.Substring (i+1, j-i-1);
string path = url.Substring (j+1);
XmlElement addin = GetAddin (fileId, addinId);
if (addin == null)
return "Add-in not found: " + addinId + "";
XmlElement ext = (XmlElement) addin.SelectSingleNode ("ExtensionPoint[@path='" + path + "']");
if (ext == null)
return "Extension point not found: " + path + "";
StringBuilder sb = new StringBuilder ("");
sb.Append ("").Append (ext.GetAttribute ("name")).Append ("
");
path = path.Replace ("/", " / ");
sb.Append ("Path: ").Append (path).Append ("
");
XmlElement desc = (XmlElement) ext.SelectSingleNode ("Description");
if (desc != null)
sb.Append (desc.InnerText);
sb.Append ("Extension Nodes:
");
sb.Append ("");
foreach (XmlElement en in ext.SelectNodes ("ExtensionNode")) {
string nid = en.GetAttribute ("id");
string nname = en.GetAttribute ("name");
string sdesc = "";
desc = (XmlElement) en.SelectSingleNode ("Description");
if (desc != null)
sdesc = desc.InnerText;
sb.AppendFormat ("{3} | {4} |
", fileId, addinId, nid, nname, sdesc);
}
sb.Append ("
");
sb.Append ("");
return sb.ToString ();
}
protected string GetExtensionNodeTextFromUrl (string url)
{
// Remove "addin:" prefix including any help-source id on the front.
url = url.Substring (ExtensionNodePrefix.Length);
int i = url.IndexOf ('#');
if (i == -1) {
Message (TraceLevel.Warning, "Warning, NULL url!");
return "Invalid url";
}
string fileId = url.Substring (0, i);
int j = url.IndexOf ('#', i+1);
string addinId = url.Substring (i+1, j-i-1);
string nodeId = url.Substring (j+1);
XmlElement addin = GetAddin (fileId, addinId);
if (addin == null)
return "Add-in not found: " + addinId + "";
XmlElement node = (XmlElement) addin.SelectSingleNode ("ExtensionNodeType[@id='" + nodeId + "']");
if (node == null)
return "Extension point not found: " + nodeId + "";
StringBuilder sb = new StringBuilder ("");
sb.Append ("").Append (node.GetAttribute ("name")).Append ("
");
XmlElement desc = (XmlElement) node.SelectSingleNode ("Description");
if (desc != null)
sb.Append (desc.InnerText);
sb.Append ("Attributes:
");
sb.Append ("");
sb.Append ("Name | ");
sb.Append ("Type | ");
sb.Append ("Required | ");
sb.Append ("Localizable | ");
sb.Append ("Description | ");
sb.Append ("
");
sb.Append ("id | ");
sb.Append ("System.String | ");
sb.Append (" | ");
sb.Append (" | ");
sb.Append ("Identifier of the node. | ");
sb.Append ("
");
foreach (XmlElement at in node.SelectNodes ("Attributes/Attribute")) {
sb.Append ("");
sb.AppendFormat ("{0} | ", at.GetAttribute ("name"));
sb.AppendFormat ("{0} | ", at.GetAttribute ("type"));
if (at.GetAttribute ("required") == "True")
sb.Append ("Yes | ");
else
sb.Append (" | ");
if (at.GetAttribute ("localizable") == "True")
sb.Append ("Yes | ");
else
sb.Append (" | ");
string sdesc = "";
desc = (XmlElement) at.SelectSingleNode ("Description");
if (desc != null)
sdesc = desc.InnerText;
sb.AppendFormat ("{0} | ", sdesc);
sb.Append ("
");
}
sb.Append ("
");
XmlNodeList children = node.SelectNodes ("ChildNodes/ExtensionNode");
if (children.Count > 0) {
sb.Append ("Child Nodes:
");
sb.Append ("");
foreach (XmlElement en in children) {
string nid = en.GetAttribute ("id");
string nname = en.GetAttribute ("name");
string sdesc = "";
desc = (XmlElement) en.SelectSingleNode ("Description");
if (desc != null)
sdesc = desc.InnerText;
sb.AppendFormat ("{3} | {4} |
", fileId, addinId, nid, nname, sdesc);
}
sb.Append ("
");
}
sb.Append ("");
return sb.ToString ();
}
XmlElement GetAddin (string fileId, string addinId)
{
Stream s = GetHelpStream (fileId);
StreamReader file;
using (file = new StreamReader (s)) {
XmlDocument doc = new XmlDocument ();
doc.Load (file);
XmlElement addin = (XmlElement) doc.SelectSingleNode ("Addins/Addin[@fullId='" + addinId + "']");
if (addin != null)
return addin;
else
return null;
}
}
}
}