Merge pull request #704 from jgagnon/master
[mono.git] / mcs / class / System.Web / System.Web / StaticSiteMapProvider.cs
index c3157d88dd0a036e720dc16abe37197b9c68bf21..e6765c148f86ea3480cd75b4912e0a8c3ba8f728 100644 (file)
@@ -30,9 +30,8 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-
-#if NET_2_0
 using System.Collections.Generic;
+using System.Web.Util;
 
 namespace System.Web
 {
@@ -42,7 +41,7 @@ namespace System.Web
                Dictionary<SiteMapNode, SiteMapNode> nodeToParent;
                Dictionary<SiteMapNode, SiteMapNodeCollection> nodeToChildren;
                Dictionary<string, SiteMapNode> urlToNode;
-                       
+               
                protected StaticSiteMapProvider ()
                {
                        keyToNode = new Dictionary<string, SiteMapNode> ();
@@ -51,32 +50,36 @@ namespace System.Web
                        urlToNode = new Dictionary<string, SiteMapNode> (StringComparer.InvariantCultureIgnoreCase);
                }
 
-               internal void AddNodeInternal (SiteMapNode node, SiteMapNode parentNode, bool callFind)
+               internal protected override void AddNode (SiteMapNode node, SiteMapNode parentNode)
                {
                        if (node == null)
                                throw new ArgumentNullException ("node");
 
                        lock (this_lock) {
-                               if (callFind && node.Provider == this && FindSiteMapNodeFromKey (node.Key) != null)
-                                       throw new InvalidOperationException (string.Format ("A node with key '{0}' already exists.",node.Key));
-
-                               if (!String.IsNullOrEmpty (node.Url)) {
-                                       string url = MapUrl (node.Url);
-                                       
-                                       if (callFind && FindSiteMapNode (url) != null)
+                               string nodeKey = node.Key;
+                               if (FindSiteMapNodeFromKey (nodeKey) != null && node.Provider == this)
+                                       throw new InvalidOperationException (string.Format ("A node with key '{0}' already exists.",nodeKey));
+
+                               string nodeUrl = node.Url;
+                               if (!String.IsNullOrEmpty (nodeUrl)) {
+                                       string url = MapUrl (nodeUrl);
+                                       SiteMapNode foundNode = FindSiteMapNode (url);
+                                       if (foundNode != null && String.Compare (foundNode.Url, url, RuntimeHelpers.StringComparison) == 0)
                                                throw new InvalidOperationException (String.Format (
                                                        "Multiple nodes with the same URL '{0}' were found. " + 
                                                        "StaticSiteMapProvider requires that sitemap nodes have unique URLs.",
                                                        node.Url
                                                ));
-                               
+
                                        urlToNode.Add (url, node);
                                }
+                               keyToNode.Add (nodeKey, node);
 
-                               keyToNode.Add (node.Key, node);
+                               if (node == RootNode)
+                                       return;
 
                                if (parentNode == null)
-                                       return;
+                                       parentNode = RootNode;
 
                                nodeToParent.Add (node, parentNode);
 
@@ -87,11 +90,6 @@ namespace System.Web
                                children.Add (node);
                        }
                }
-
-               internal protected override void AddNode (SiteMapNode node, SiteMapNode parentNode)
-               {
-                       AddNodeInternal (node, parentNode, true);
-               }
                
                protected virtual void Clear ()
                {
@@ -113,7 +111,12 @@ namespace System.Web
                        
                        BuildSiteMap();
                        SiteMapNode node;
-                       urlToNode.TryGetValue (MapUrl (rawUrl), out node);
+                       if (VirtualPathUtility.IsAppRelative (rawUrl))
+                               rawUrl = VirtualPathUtility.ToAbsolute (rawUrl, HttpRuntime.AppDomainAppVirtualPath, false);
+
+                       if (!urlToNode.TryGetValue (rawUrl, out node))
+                               return null;
+
                        return CheckAccessibility (node);
                }
 
@@ -205,14 +208,21 @@ namespace System.Web
                        return (node != null && IsAccessibleToUser (HttpContext.Current, node)) ? node : null;
                }
 
-               string MapUrl (string url)
+               internal string MapUrl (string url)
                {
+                       if (String.IsNullOrEmpty (url))
+                               return url;
+
+                       string appVPath = HttpRuntime.AppDomainAppVirtualPath;
+                       if (String.IsNullOrEmpty (appVPath))
+                               appVPath = "/";
+                       
                        if (VirtualPathUtility.IsAppRelative (url))
-                               return VirtualPathUtility.ToAbsolute (url);
+                               return VirtualPathUtility.ToAbsolute (url, appVPath, true);
                        else
-                               return url;
+                               return VirtualPathUtility.ToAbsolute (UrlUtils.Combine (appVPath, url), appVPath, true);
                }
        }
 }
-#endif
+