2 // System.Web.StaticSiteMapProvider.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
6 // Ben Maurer (bmaurer@users.sourceforge.net)
9 // (C) 2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Collections;
34 using System.Collections.Specialized;
36 using System.Configuration.Provider;
37 using System.Web.Util;
38 using System.Globalization;
42 public abstract class StaticSiteMapProvider : SiteMapProvider
44 Hashtable nodeToParent;
45 Hashtable nodeToChildren;
49 internal protected override void AddNode (SiteMapNode node, SiteMapNode parentNode)
52 throw new ArgumentNullException ("node");
55 string url = node.Url;
56 if (url != null && url.Length > 0) {
59 if (FindSiteMapNode (url) != null)
60 throw new InvalidOperationException ();
62 UrlToNode [url] = node;
65 if (FindSiteMapNodeFromKey (node.Key) != null)
66 throw new InvalidOperationException (string.Format ("A node with key {0} already exists.",node.Key));
67 KeyToNode [node.Key] = node;
72 if (parentNode == null)
73 parentNode = RootNode;
75 NodeToParent [node] = parentNode;
76 if (NodeToChildren [parentNode] == null)
77 NodeToChildren [parentNode] = new SiteMapNodeCollection ();
79 ((SiteMapNodeCollection) NodeToChildren [parentNode]).Add (node);
83 Hashtable NodeToParent {
86 if (nodeToParent == null)
87 nodeToParent = new Hashtable ();
93 Hashtable NodeToChildren {
96 if (nodeToChildren == null)
97 nodeToChildren = new Hashtable ();
99 return nodeToChildren;
103 Hashtable UrlToNode {
106 if (urlToNode == null) {
107 urlToNode = new Hashtable (StringComparer.InvariantCultureIgnoreCase);
114 Hashtable KeyToNode {
117 if (keyToNode == null)
118 keyToNode = new Hashtable ();
124 protected virtual void Clear ()
127 if (urlToNode != null)
129 if (nodeToChildren != null)
130 nodeToChildren.Clear ();
131 if (nodeToParent != null)
132 nodeToParent.Clear ();
133 if (keyToNode != null)
138 public override SiteMapNode FindSiteMapNode (string rawUrl)
141 throw new ArgumentNullException ("rawUrl");
143 if (rawUrl.Length > 0) {
145 rawUrl = MapUrl (rawUrl);
146 SiteMapNode node = (SiteMapNode) UrlToNode [rawUrl];
147 if (node != null && IsAccessibleToUser (HttpContext.Current, node))
153 public override SiteMapNodeCollection GetChildNodes (SiteMapNode node)
156 throw new ArgumentNullException ("node");
159 SiteMapNodeCollection col = (SiteMapNodeCollection) NodeToChildren [node];
160 if (col == null) return SiteMapNodeCollection.EmptyCollection;
162 SiteMapNodeCollection ret = null;
163 for (int n=0; n<col.Count; n++) {
164 if (!IsAccessibleToUser (HttpContext.Current, col[n])) {
166 ret = new SiteMapNodeCollection ();
167 for (int m=0; m<n; m++)
170 } else if (ret != null)
176 return SiteMapNodeCollection.ReadOnly (ret);
178 return SiteMapNodeCollection.ReadOnly (col);
183 public override SiteMapNode GetParentNode (SiteMapNode node)
186 throw new ArgumentNullException ("node");
188 SiteMapNode parent = (SiteMapNode) NodeToParent [node];
189 return parent != null && IsAccessibleToUser (HttpContext.Current, parent) ? parent : null;
192 protected override void RemoveNode (SiteMapNode node)
195 throw new ArgumentNullException("node");
198 SiteMapNode parent = (SiteMapNode) NodeToParent [node];
199 if (NodeToParent.Contains (node))
200 NodeToParent.Remove (node);
202 if (node.Url != null && node.Url.Length > 0 && UrlToNode.Contains (node.Url))
203 UrlToNode.Remove (node.Url);
205 if (parent != null) {
206 SiteMapNodeCollection siblings = (SiteMapNodeCollection) NodeToChildren [node];
207 if (siblings != null && siblings.Contains (node))
208 siblings.Remove (node);
213 public override SiteMapNode FindSiteMapNodeFromKey (string key)
216 throw new ArgumentNullException ("key");
218 SiteMapNode ret = (SiteMapNode) KeyToNode [key];
219 return ret != null && IsAccessibleToUser (HttpContext.Current, ret) ? ret : null;
222 public abstract SiteMapNode BuildSiteMap ();
224 string MapUrl (string url)
226 if (HttpContext.Current == null)
229 if (UrlUtils.IsRelativeUrl (url))
230 return UrlUtils.Combine (HttpRuntime.AppDomainAppVirtualPath, url);
232 return UrlUtils.ResolveVirtualPathFromAppAbsolute (url);