1: using System;
2: using System.Data;
3: using System.Configuration;
4: using System.Linq;
5: using System.Web;
6: using System.Web.Security;
7: using System.Web.UI;
8: using System.Web.UI.HtmlControls;
9: using System.Web.UI.WebControls;
10: using System.Web.UI.WebControls.WebParts;
11: using System.Xml;
12: using System.Xml.Linq;
13: using System.Collections.Specialized;
14:
15: public class DynamicSiteMapProvider : StaticSiteMapProvider
16: {
17: private string _siteMapFileName;
18: private SiteMapNode _rootNode = null;
19: private const string SiteMapNodeName = "siteMapNode";
20: private Ia.Cs.Xml xml;
21:
22: ////////////////////////////////////////////////////////////////////////////
23:
24: /// <summary publish="true">
25: /// Sitemap support class.
26: /// </summary>
27: /// <remarks>
28: /// Copyright © 2008-2013 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
29: ///
30: /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
31: /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
32: ///
33: /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
34: /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
35: ///
36: /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
37: ///
38: /// Copyright notice: This notice may not be removed or altered from any source distribution.
39: /// </remarks>
40:
41: ////////////////////////////////////////////////////////////////////////////
42:
43: /// <summary>
44: ///
45: /// </summary>
46: public DynamicSiteMapProvider()
47: {
48: xml = new Ia.Cs.Xml();
49: }
50:
51: ////////////////////////////////////////////////////////////////////////////
52:
53: /// <summary>
54: ///
55: /// </summary>
56: public override SiteMapNode RootNode
57: {
58: get { return BuildSiteMap(); }
59: }
60:
61: ////////////////////////////////////////////////////////////////////////////
62:
63: /// <summary>
64: ///
65: /// </summary>
66: public override void Initialize(string name, NameValueCollection attributes)
67: {
68: base.Initialize(name, attributes);
69: _siteMapFileName = attributes["siteMapFile"];
70: _siteMapFileName = _siteMapFileName.Replace("~/", "");
71: }
72:
73: ////////////////////////////////////////////////////////////////////////////
74:
75: /// <summary>
76: ///
77: /// </summary>
78: protected override SiteMapNode GetRootNodeCore()
79: {
80: return RootNode;
81: }
82:
83: ////////////////////////////////////////////////////////////////////////////
84:
85: /// <summary>
86: ///
87: /// </summary>
88: protected override void Clear()
89: {
90: lock (this)
91: {
92: _rootNode = null;
93: base.Clear();
94: }
95: }
96:
97: ////////////////////////////////////////////////////////////////////////////
98:
99: /// <summary>
100: ///
101: /// </summary>
102: public override SiteMapNode BuildSiteMap()
103: {
104: lock (this)
105: {
106: if (null == _rootNode)
107: {
108: Clear();
109:
110: // Load the sitemap's xml from the file.
111: XmlDocument siteMapXml = LoadSiteMapXml();
112:
113: // Create the first site map item from the top node in the xml.
114: XmlElement rootElement = (XmlElement)siteMapXml.GetElementsByTagName(SiteMapNodeName)[0];
115:
116: // Create an XmlNamespaceManager to resolve the default namespace.
117: XmlNamespaceManager nsmgr = new XmlNamespaceManager(siteMapXml.NameTable);
118: nsmgr.AddNamespace("bk", "http://schemas.microsoft.com/AspNet/SiteMap-File-1.0");
119:
120: XmlNode ref_xn;
121: //XmlElement root = doc.DocumentElement; siteMapNode title="About Us"
122: ref_xn = rootElement.SelectSingleNode("descendant::bk:siteMapNode[@title='Books']", nsmgr);
123:
124: // This is the key method - add the dynamic nodes to the xml
125: AddDynamicNodes(rootElement, ref_xn);
126:
127: // Now build up the site map structure from the xml
128: GenerateSiteMapNodes(rootElement);
129: }
130: }
131:
132: return _rootNode;
133: }
134:
135: ////////////////////////////////////////////////////////////////////////////
136:
137: /// <summary>
138: ///
139: /// </summary>
140: private XmlDocument LoadSiteMapXml()
141: {
142: XmlDocument siteMapXml = new XmlDocument();
143:
144: siteMapXml.Load(AppDomain.CurrentDomain.BaseDirectory + _siteMapFileName);
145:
146: return siteMapXml;
147: }
148:
149: ////////////////////////////////////////////////////////////////////////////
150:
151: /// <summary>
152: ///
153: /// </summary>
154: private void AddDynamicNodes(XmlElement rootElement, XmlNode ref_xn)
155: {
156: // below: build site map from data in this.xml file
157: string id, url, xpath;
158: XmlNode xn;
159: XmlElement xe;
160: DataTable dt;
161:
162: xpath = "";
163: xn = xml.ReturnXmlNode(@"app_data\this.xml");
164:
165: //rootElement.RemoveChild(rootElement.SelectSingleNode("siteMap/siteMapNode/siteMapNode[@title='Books']"));
166:
167: // below: collect type_id that exist in book table
168: dt = Ia.Cs.Db.OleDb.Select("SELECT DISTINCT type_id FROM ia_book");
169:
170: if (dt.Rows.Count > 0)
171: {
172: foreach (DataRow r in dt.Rows) xpath += "@id=" + r["type_id"].ToString() + " or ";
173:
174: if (xpath.Length > 0) xpath = xpath.Remove(xpath.Length - 4, 4);
175:
176: foreach (XmlNode n in xn.SelectNodes("/this/book/type[descendant-or-self::type[" + xpath + "]]"))
177: {
178: id = n.Attributes["id"].Value;
179:
180: if (n.Attributes["url"] != null) url = n.Attributes["url"].Value;
181: else if (n.ParentNode.Attributes["url"] != null) url = n.ParentNode.Attributes["url"].Value;
182: else if (n.ParentNode.ParentNode.Attributes["url"] != null) url = n.ParentNode.ParentNode.Attributes["url"].Value;
183: else url = "";
184:
185: if (id != "0")
186: {
187: xe = AddDynamicChildElement(rootElement, ref_xn, url + "?id=" + id, n.Attributes["name"].Value, ""/*n.Attributes["description"].Value*/);
188:
189: foreach (XmlNode o in n.SelectNodes("type[" + xpath + "]"))
190: {
191: id = o.Attributes["id"].Value;
192:
193: if (o.Attributes["url"] != null) url = o.Attributes["url"].Value;
194: else if (o.ParentNode.Attributes["url"] != null) url = o.ParentNode.Attributes["url"].Value;
195: else if (o.ParentNode.ParentNode.Attributes["url"] != null) url = o.ParentNode.ParentNode.Attributes["url"].Value;
196: else url = "";
197:
198: AddDynamicChildElement(xe, url + "?id=" + id, o.Attributes["name"].Value, ""/*n.Attributes["description"].Value*/);
199: }
200: }
201: }
202: }
203: }
204:
205: ////////////////////////////////////////////////////////////////////////////
206:
207: /// <summary>
208: ///
209: /// </summary>
210: private static XmlElement AddDynamicChildElement(XmlElement parentElement, XmlNode ref_xn, string url, string title, string description)
211: {
212: // Create new element from the parameters
213:
214: XmlElement childElement = parentElement.OwnerDocument.CreateElement(SiteMapNodeName);
215:
216: childElement.SetAttribute("url", url);
217:
218: childElement.SetAttribute("title", title);
219:
220: childElement.SetAttribute("description", description);
221:
222: // Add it to the parent
223: //parentElement.AppendChild(childElement);
224: parentElement.InsertAfter(childElement, ref_xn);
225:
226: return childElement;
227: }
228:
229: ////////////////////////////////////////////////////////////////////////////
230:
231: /// <summary>
232: ///
233: /// </summary>
234: private static XmlElement AddDynamicChildElement(XmlElement parentElement, string url, string title, string description)
235: {
236: // Create new element from the parameters
237:
238: XmlElement childElement = parentElement.OwnerDocument.CreateElement(SiteMapNodeName);
239:
240: childElement.SetAttribute("url", url);
241:
242: childElement.SetAttribute("title", title);
243:
244: childElement.SetAttribute("description", description);
245:
246: // Add it to the parent
247: parentElement.AppendChild(childElement);
248:
249: return childElement;
250: }
251:
252: ////////////////////////////////////////////////////////////////////////////
253:
254: /// <summary>
255: ///
256: /// </summary>
257: private void GenerateSiteMapNodes(XmlElement rootElement)
258: {
259: _rootNode = GetSiteMapNodeFromElement(rootElement);
260:
261: AddNode(_rootNode);
262:
263: CreateChildNodes(rootElement, _rootNode);
264: }
265:
266: ////////////////////////////////////////////////////////////////////////////
267:
268: /// <summary>
269: ///
270: /// </summary>
271: private void CreateChildNodes(XmlElement parentElement, SiteMapNode parentNode)
272: {
273: foreach (XmlNode xmlElement in parentElement.ChildNodes)
274: {
275: if (xmlElement.Name == SiteMapNodeName)
276: {
277: SiteMapNode childNode = GetSiteMapNodeFromElement((XmlElement)xmlElement);
278:
279: AddNode(childNode, parentNode);
280:
281: CreateChildNodes((XmlElement)xmlElement, childNode);
282: }
283: }
284: }
285:
286: ////////////////////////////////////////////////////////////////////////////
287:
288: /// <summary>
289: ///
290: /// </summary>
291: private SiteMapNode GetSiteMapNodeFromElement(XmlElement rootElement)
292: {
293: SiteMapNode newSiteMapNode;
294:
295: string url = rootElement.GetAttribute("url");
296:
297: string title = rootElement.GetAttribute("title");
298:
299: string description = rootElement.GetAttribute("description");
300:
301: // The key needs to be unique, so hash the url and title.
302:
303: newSiteMapNode = new SiteMapNode(this, (url + title).GetHashCode().ToString(), url, title, description);
304:
305: return newSiteMapNode;
306: }
307:
308: ////////////////////////////////////////////////////////////////////////////
309: ////////////////////////////////////////////////////////////////////////////
310: }