// 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 ("", addin.GetAttribute ("addinId")); sb.AppendFormat ("", addin.GetAttribute ("namespace")); sb.AppendFormat ("", addin.GetAttribute ("version")); sb.Append ("
Id{0}
Namespace{0}
Version{0}

"); sb.Append ("

Extension Points:

"); 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 ("", fileId, addinId, nid, nname, sdesc); } sb.Append ("
{3}{4}
"); 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 (""); sb.Append (""); sb.Append (""); sb.Append (""); sb.Append (""); sb.Append (""); sb.Append (""); sb.Append (""); sb.Append (""); sb.Append (""); sb.Append (""); sb.Append (""); foreach (XmlElement at in node.SelectNodes ("Attributes/Attribute")) { sb.Append (""); sb.AppendFormat ("", at.GetAttribute ("name")); sb.AppendFormat ("", at.GetAttribute ("type")); if (at.GetAttribute ("required") == "True") sb.Append (""); else sb.Append (""); if (at.GetAttribute ("localizable") == "True") sb.Append (""); else sb.Append (""); string sdesc = ""; desc = (XmlElement) at.SelectSingleNode ("Description"); if (desc != null) sdesc = desc.InnerText; sb.AppendFormat ("", sdesc); sb.Append (""); } sb.Append ("
NameTypeRequiredLocalizableDescription
idSystem.StringIdentifier of the node.
{0}{0}YesYes{0}
"); 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 ("", fileId, addinId, nid, nname, sdesc); } sb.Append ("
{3}{4}
"); } 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; } } } }