Author: lluis
Date: 2005-05-26 12:16:09 -0400 (Thu, 26 May 2005)
New Revision: 45060

Added:
   trunk/mcs/class/System.Web/System.Web/StaticSiteMapProvider.cs
Modified:
   trunk/mcs/class/System.Web/System.Web/ChangeLog
   trunk/mcs/class/System.Web/System.Web/SiteMap.cs
   trunk/mcs/class/System.Web/System.Web/SiteMapNode.cs
   trunk/mcs/class/System.Web/System.Web/SiteMapNodeCollection.cs
   trunk/mcs/class/System.Web/System.Web/SiteMapProvider.cs
   trunk/mcs/class/System.Web/System.Web/SiteMapProviderCollection.cs
   trunk/mcs/class/System.Web/System.Web/XmlSiteMapProvider.cs
Log:
2005-05-26  Lluis Sanchez Gual <[EMAIL PROTECTED]>

        * SiteMapNodeCollection.cs: Implemented missing methods. The collection
        does not inherit from CollectionBase any more.
        * SiteMapNode.cs: Track api changes.
        * SiteMapProvider.cs: Moved several methods to the new
        StaticSiteMapProvider class. Other fixes.
        * XmlSiteMapProvider.cs: Watch changes in the xml files. Other fixes.
        * SiteMapProviderCollection.cs: Minor fixes.
        * SiteMap.cs: Added missing event. Avoid double check lock.
        * StaticSiteMapProvider.cs: New class that implements some of the
        funtionality of SiteMapProvider.


Modified: trunk/mcs/class/System.Web/System.Web/ChangeLog
===================================================================
--- trunk/mcs/class/System.Web/System.Web/ChangeLog     2005-05-26 16:03:34 UTC 
(rev 45059)
+++ trunk/mcs/class/System.Web/System.Web/ChangeLog     2005-05-26 16:16:09 UTC 
(rev 45060)
@@ -1,3 +1,16 @@
+2005-05-26  Lluis Sanchez Gual <[EMAIL PROTECTED]>
+
+       * SiteMapNodeCollection.cs: Implemented missing methods. The collection
+       does not inherit from CollectionBase any more.
+       * SiteMapNode.cs: Track api changes.
+       * SiteMapProvider.cs: Moved several methods to the new
+       StaticSiteMapProvider class. Other fixes.
+       * XmlSiteMapProvider.cs: Watch changes in the xml files. Other fixes.
+       * SiteMapProviderCollection.cs: Minor fixes.
+       * SiteMap.cs: Added missing event. Avoid double check lock.
+       * StaticSiteMapProvider.cs: New class that implements some of the
+       funtionality of SiteMapProvider.
+
 2005-05-25  Ben Maurer  <[EMAIL PROTECTED]>
 
        * MimeTypes.cs: Remove extra spaces, they were typos. Fixes 75049.
@@ -376,7 +389,7 @@
        * HttpContext.cs: reverting Pedro's patch and sending mail with test
        to mono-devel.
 
-2004-06-09  Pedro Mart�z Juli�<[EMAIL PROTECTED]>
+2004-06-09  Pedro Martnez Juli  <[EMAIL PROTECTED]>
 
        * HttpContext: User property returns its own "user" value because
        the context can walk through different Threads. When "User" property
@@ -440,7 +453,7 @@
 2004-06-01  Gonzalo Paniagua Javier <[EMAIL PROTECTED]>
 
        * HttpWorkerRequest.cs: the hashtables are now case-insensitive. Thanks
-       to Markus Kr�ner.
+       to Markus Krutner.
 
 2004-05-31  Gonzalo Paniagua Javier <[EMAIL PROTECTED]>
 
@@ -1664,7 +1677,7 @@
 
        * HttpServerUtility.cs: Fix build breaker.
 
-2002-03-28  Wictor Wil� <[EMAIL PROTECTED]>
+2002-03-28  Wictor Wiln  <[EMAIL PROTECTED]>
 
        * HttpServerUtils.cs : Added some more functionality
        

Modified: trunk/mcs/class/System.Web/System.Web/SiteMap.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web/SiteMap.cs    2005-05-26 16:03:34 UTC 
(rev 45059)
+++ trunk/mcs/class/System.Web/System.Web/SiteMap.cs    2005-05-26 16:16:09 UTC 
(rev 45060)
@@ -35,7 +35,7 @@
 using System.Configuration.Provider;
 
 namespace System.Web {
-       public sealed class SiteMap {
+       public abstract class SiteMap {
        
                internal SiteMap ()
                {
@@ -44,16 +44,14 @@
                [MonoTODO ("Get everything from the config")]
                private static void Init ()
                {
-                       if (provider == null) {
-                               lock (locker) {
-                                       if (provider == null) {
-                                               providers = new 
SiteMapProviderCollection ();
-                                               provider = new 
XmlSiteMapProvider ();
-                                               NameValueCollection attributes 
= new NameValueCollection ();
-                                               attributes.Add ("siteMapFile", 
"app.sitemap");
-                                               
((ProviderBase)provider).Initialize ("AspNetXmlSiteMapProvider", attributes);
-                                               providers.Add 
((ProviderBase)provider);
-                                       }
+                       lock (locker) {
+                               if (provider == null) {
+                                       providers = new 
SiteMapProviderCollection ();
+                                       provider = new XmlSiteMapProvider ();
+                                       NameValueCollection attributes = new 
NameValueCollection ();
+                                       attributes.Add ("siteMapFile", 
"Web.sitemap");
+                                       ((ProviderBase)provider).Initialize 
("AspNetXmlSiteMapProvider", attributes);
+                                       providers.Add ((ProviderBase)provider);
                                }
                        }
                }
@@ -78,6 +76,11 @@
                        }
                }
                
+               public event SiteMapResolveEventHandler SiteMapResolve {
+                       add { Provider.SiteMapResolve += value; }
+                       remove { Provider.SiteMapResolve -= value; }
+               }
+               
                static SiteMapProvider provider;
                static SiteMapProviderCollection providers;
                static object locker = new object ();

Modified: trunk/mcs/class/System.Web/System.Web/SiteMapNode.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web/SiteMapNode.cs        2005-05-26 
16:03:34 UTC (rev 45059)
+++ trunk/mcs/class/System.Web/System.Web/SiteMapNode.cs        2005-05-26 
16:16:09 UTC (rev 45060)
@@ -41,14 +41,16 @@
        
                private SiteMapNode () {}
                
-               public SiteMapNode (SiteMapProvider provider, string key) : 
this (provider, key, null, null, null, null, null, null) {}
-               public SiteMapNode (SiteMapProvider provider, string key, 
string url) : this (provider, key, url, null, null, null, null, null) {}
-               public SiteMapNode (SiteMapProvider provider, string key, 
string url, string title) : this (provider, key, url, title, null, null, null, 
null) {}
-               public SiteMapNode (SiteMapProvider provider, string key, 
string url, string title, string description) : this (provider, key, url, 
title, description, null, null, null) {}
-               public SiteMapNode (SiteMapProvider provider, string key, 
string url, string title, string description, IList roles, NameValueCollection 
attributes, NameValueCollection resourceKeys)
+               public SiteMapNode (SiteMapProvider provider, string key) : 
this (provider, key, null, null, null, null, null, null, null) {}
+               public SiteMapNode (SiteMapProvider provider, string key, 
string url) : this (provider, key, url, null, null, null, null, null, null) {}
+               public SiteMapNode (SiteMapProvider provider, string key, 
string url, string title) : this (provider, key, url, title, null, null, null, 
null, null) {}
+               public SiteMapNode (SiteMapProvider provider, string key, 
string url, string title, string description) : this (provider, key, url, 
title, description, null, null, null, null) {}
+               public SiteMapNode (SiteMapProvider provider, string key, 
string url, string title, string description, IList roles, NameValueCollection 
attributes, NameValueCollection explicitResourceKeys, string 
implicitResourceKey)
                {
                        if (provider == null)
                                throw new ArgumentNullException ("provider");
+                       if (key == null)
+                               throw new ArgumentNullException ("key");
                        
                        this.provider = provider;
                        this.key = key;
@@ -57,7 +59,8 @@
                        this.description = description;
                        this.roles = roles;
                        this.attributes = attributes;
-                       this.resourceKeys = resourceKeys;
+                       this.resourceKeys = explicitResourceKeys;
+                       this.implicitResourceKey = implicitResourceKey;
                }
 
                public SiteMapDataSourceView GetDataSourceView 
(SiteMapDataSource owner, string viewName)
@@ -70,10 +73,9 @@
                        return new SiteMapHierarchicalDataSourceView (this);
                }
                
-               [MonoTODO]
                public bool IsAccessibleToUser (System.Web.HttpContext ctx)
                {
-                       throw new NotImplementedException ();
+                       return provider.IsAccessibleToUser (ctx, this);
                }
                
                public override string ToString()
@@ -81,7 +83,9 @@
                        return Title;
                }
 
-               public virtual bool HasChildNodes { get { return ChildNodes != 
null && ChildNodes.Count != 0; } }
+               public virtual bool HasChildNodes {
+                       get { return ChildNodes != null && ChildNodes.Count != 
0; }
+               }
 
                public SiteMapNodeCollection GetAllNodes ()
                {
@@ -161,10 +165,15 @@
                        }
                }
                
-               [MonoTODO ("set")]
                public virtual SiteMapNodeCollection ChildNodes {
-                       get { return provider.GetChildNodes (this); } 
-                       set { CheckWritable (); }
+                       get {
+                               if (childNodes != null) return childNodes;
+                               return provider.GetChildNodes (this);
+                       } 
+                       set {
+                               CheckWritable ();
+                               childNodes = value;
+                       }
                }
 
                public virtual SiteMapNode RootNode { get { return 
provider.RootProvider.RootNode; }  }
@@ -179,7 +188,7 @@
                }
                
                [MonoTODO]
-               protected string GetExplicitResourceString (string 
attributeName, bool b)
+               protected string GetExplicitResourceString (string 
attributeName, string defaultValue, bool throwIfNotFound)
                {
                        return null;
                }
@@ -196,13 +205,18 @@
                        get {
                                string val = null;
                                if (provider.EnableLocalization) {
-                                       val = GetExplicitResourceString (key, 
true);
+                                       val = GetExplicitResourceString (key, 
null, true);
                                        if (val == null) val = 
GetImplicitResourceString (key);
                                }
                                if (val != null) return null;
                                if (attributes != null) return attributes [key];
                                return null;
                        }
+                       set {
+                               CheckWritable ();
+                               if (attributes == null) attributes = new 
NameValueCollection ();
+                               attributes [key] = value;
+                       }
                }
                
                object ICloneable.Clone ()
@@ -275,6 +289,7 @@
                        set { CheckWritable (); attributes = value; }
                }
                
+               [Localizable (true)]
                public virtual string Description {
                        get { return description != null ? description : ""; }
                        set { CheckWritable (); description = value; }
@@ -344,6 +359,8 @@
                bool readOnly;
                string resourceKey;
                SiteMapNode parent;
+               string implicitResourceKey;
+               SiteMapNodeCollection childNodes;
                #endregion
                
        }

Modified: trunk/mcs/class/System.Web/System.Web/SiteMapNodeCollection.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web/SiteMapNodeCollection.cs      
2005-05-26 16:03:34 UTC (rev 45059)
+++ trunk/mcs/class/System.Web/System.Web/SiteMapNodeCollection.cs      
2005-05-26 16:16:09 UTC (rev 45060)
@@ -3,8 +3,10 @@
 //
 // Authors:
 //     Ben Maurer ([EMAIL PROTECTED])
+//     Lluis Sanchez Gual ([EMAIL PROTECTED])
 //
 //  (C) 2003 Ben Maurer
+//  (C) 2005 Novell, Inc (http://www.novell.com)
 //
 
 //
@@ -33,14 +35,83 @@
 using System.Collections.Specialized;
 using System.Text;
 using System.Web.UI;
+using System.Web.UI.WebControls;
 
-namespace System.Web {
-       public class SiteMapNodeCollection : CollectionBase, 
IHierarchicalEnumerable {
-               public SiteMapNodeCollection () {}
-               public SiteMapNodeCollection (SiteMapNode value) { Add (value); 
}
-               public SiteMapNodeCollection (SiteMapNode[] values) { 
AddRangeInternal (values); }
-               public SiteMapNodeCollection (SiteMapNodeCollection values) { 
AddRangeInternal (values); }
+namespace System.Web
+{
+       public class SiteMapNodeCollection : IList, IHierarchicalEnumerable
+       {
+               ArrayList list;
+               internal static SiteMapNodeCollection EmptyList;
                
+               static SiteMapNodeCollection ()
+               {
+                       EmptyList = new SiteMapNodeCollection ();
+                       EmptyList.list = ArrayList.ReadOnly (new ArrayList ());
+               }
+               
+               public SiteMapNodeCollection ()
+               {
+               }
+               
+               public SiteMapNodeCollection (int capacity)
+               {
+                       list = new ArrayList (capacity);
+               }
+               
+               public SiteMapNodeCollection (SiteMapNode value)
+               {
+                       Add (value);
+               }
+               
+               public SiteMapNodeCollection (SiteMapNode[] values)
+               {
+                       AddRangeInternal (values);
+               }
+               
+               public SiteMapNodeCollection (SiteMapNodeCollection values)
+               {
+                       AddRangeInternal (values);
+               }
+               
+               internal static SiteMapNodeCollection EmptyCollection {
+                       get { return EmptyList; }
+               }
+               
+               ArrayList List {
+                       get {
+                               if (list == null) list = new ArrayList ();
+                               return list;
+                       }
+               }
+               
+               public virtual int Count {
+                       get { return list == null ? 0 : list.Count; }
+               }
+               
+               public virtual bool IsSynchronized {
+                       get { return false; }
+               }
+               
+               public virtual object SyncRoot {
+                       get { return this; }
+               }
+               
+               public virtual IEnumerator GetEnumerator ()
+               {
+                       return list != null ? list.GetEnumerator () : 
Type.EmptyTypes.GetEnumerator ();
+               }
+               
+               public virtual void Clear ()
+               {
+                       if (list != null) list.Clear ();
+               }
+               
+               public virtual void RemoveAt (int index)
+               {
+                       List.RemoveAt (index);
+               }
+               
                public virtual int Add (SiteMapNode value)
                {
                        if (value == null)
@@ -50,22 +121,22 @@
                
                public virtual void AddRange (System.Web.SiteMapNode[] value)
                {
-                       this.OnAddRange (value);
                        this.AddRangeInternal (value);
                }
                
                public virtual void AddRange (SiteMapNodeCollection value)
                {
-                       this.OnAddRange (value);
                        this.AddRangeInternal (value);
                }
                
-               private void AddRangeInternal (IList value)
+               internal virtual void AddRangeInternal (IList value)
                {
                        if (value == null)
                                throw new ArgumentNullException ("value");
-                       this.InnerList.AddRange (value);
+
+                       List.AddRange (value);
                }
+
                public bool Contains (SiteMapNode value)
                {
                        return this.List.Contains (value);
@@ -76,11 +147,6 @@
                        this.List.CopyTo (array, index);
                }
                
-//             public SiteMapDataSourceView GetDataSourceView ()
-//             {
-//                     return new SiteMapDataSourceView (this);
-//             }
-               
                public int IndexOf (SiteMapNode value)
                {
                        return this.List.IndexOf (value);
@@ -91,20 +157,20 @@
                        this.List.Insert (index, value);
                }
                
-               protected virtual void OnAddRange (IList value)
+               protected virtual void OnValidate (object value)
                {
-               }
-               
-               protected override void OnValidate (object value)
-               {
-                       base.OnValidate (value);
-                       if (value as SiteMapNode == null)
+                       if (!(value is SiteMapNode))
                                throw new ArgumentException ("Invalid type");
                }
-               
+
                public static SiteMapNodeCollection ReadOnly 
(SiteMapNodeCollection collection)
                {
-                       return new ReadOnlySiteMapNodeCollection (collection);
+                       SiteMapNodeCollection col = new SiteMapNodeCollection 
();
+                       if (collection.list != null)
+                               col.list = ArrayList.ReadOnly (collection.list);
+                       else
+                               col.list = ArrayList.ReadOnly (new ArrayList 
());
+                       return col;
                }
                
                public virtual void Remove (SiteMapNode value)
@@ -112,11 +178,21 @@
                        this.List.Remove (value);
                }
                
-               IHierarchyData 
System.Web.UI.IHierarchicalEnumerable.GetHierarchyData (object enumeratedItem)
+               public virtual IHierarchyData GetHierarchyData (object 
enumeratedItem)
                {
                        return enumeratedItem as IHierarchyData;
                }
                
+               public SiteMapDataSourceView GetDataSourceView 
(SiteMapDataSource owner, string viewName)
+               {
+                       return new SiteMapDataSourceView (owner, viewName, 
this);
+               }
+               
+               public SiteMapHierarchicalDataSourceView 
GetHierarchicalDataSourceView ()
+               {
+                       return new SiteMapHierarchicalDataSourceView (this);
+               }
+               
                public virtual SiteMapNode this [int index] {
                        get { return (SiteMapNode) this.List [index]; }
                        set { this.List [index] = value; }
@@ -127,21 +203,46 @@
                }
 
                public virtual bool IsReadOnly {
-                       get { return List.IsReadOnly; }
+                       get { return list != null && list.IsReadOnly; }
                }
-
-               private class ReadOnlySiteMapNodeCollection : 
SiteMapNodeCollection {
-                       
-                       internal ReadOnlySiteMapNodeCollection 
(SiteMapNodeCollection collection) : base (collection) {}
-
-                       protected override void OnAddRange (IList value) { 
throw new NotSupportedException ("Readonly collection"); }
-                       protected override void OnClear () { throw new 
NotSupportedException ("Readonly collection"); }
-                       protected override void OnInsert (int index, object 
value) { throw new NotSupportedException ("Readonly collection"); }
-                       protected override void OnRemove (int index, object 
value) { throw new NotSupportedException ("Readonly collection"); }
-                       protected override void OnSet (int index, object 
oldValue, object newValue) { throw new NotSupportedException ("Readonly 
collection"); }
-                       public override bool IsReadOnly { get { return true; } }
+               
+               object IList.this [int index] {
+                       get { return List [index]; }
+                       set { OnValidate (value); List [index] = value; }
                }
-                
+               
+               int IList.Add (object value)
+               {
+                       OnValidate (value);
+                       return List.Add (value);
+               }
+               
+               bool IList.Contains (object value)
+               {
+                       return List.Contains (value);
+               }
+               
+               int IList.IndexOf (object value)
+               {
+                       return List.IndexOf (value);
+               }
+               
+               void IList.Insert (int index, object value)
+               {
+                       OnValidate (value);
+                       List.Insert (index, value);
+               }
+               
+               void IList.Remove (object value)
+               {
+                       OnValidate (value);
+                       List.Remove (value);
+               }
+               
+               void ICollection.CopyTo (Array array, int index)
+               {
+                       List.CopyTo (array, index);
+               }
        }
 }
 #endif

Modified: trunk/mcs/class/System.Web/System.Web/SiteMapProvider.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web/SiteMapProvider.cs    2005-05-26 
16:03:34 UTC (rev 45059)
+++ trunk/mcs/class/System.Web/System.Web/SiteMapProvider.cs    2005-05-26 
16:16:09 UTC (rev 45060)
@@ -3,8 +3,10 @@
 //
 // Authors:
 //     Ben Maurer ([EMAIL PROTECTED])
+//     Lluis Sanchez Gual ([EMAIL PROTECTED])
 //
 // (C) 2003 Ben Maurer
+// (C) 2005 Novell, Inc (http://www.novell.com)
 //
 
 //
@@ -40,214 +42,200 @@
        public abstract class SiteMapProvider : ProviderBase {
                
                bool enableLocalization;
+               SiteMapProvider parentProvider;
+               SiteMapProvider rootProviderCache;
+               bool securityTrimming;
+               object resolveLock = new Object();
+               bool resolving;
                
-               public void AddNode (SiteMapNode node)
+               protected virtual void AddNode (SiteMapNode node)
                {
                        AddNode (node, null);
                }
                
-               public void AddNode (SiteMapNode node, SiteMapNode parentNode)
+               internal protected virtual void AddNode (SiteMapNode node, 
SiteMapNode parentNode)
                {
                        if (node == null)
                                throw new ArgumentNullException ("node");
+               }
+
+               public virtual SiteMapNode FindSiteMapNode (HttpContext context)
+               {
+                       if (context == null)
+                               throw new ArgumentNullException ("context");
                        
-                       lock (this) {
-                               string url = node.Url;
-                               if (url != null && url.Length > 0) {
-                                       
-                                       
-                                               if (UrlUtils.IsRelativeUrl 
(url))
-                                                       url = UrlUtils.Combine 
(HttpRuntime.AppDomainAppVirtualPath, url);
-                                               else
-                                                       url = 
UrlUtils.ResolveVirtualPathFromAppAbsolute (url);
-                                               
-                                               if (FindSiteMapNode (url) != 
null)
-                                                       throw new 
InvalidOperationException ();
-                                       
-                                       UrlToNode [url] = node;
-                               }
-                               
-                               if (parentNode != null) {
-                                       NodeToParent [node] = parentNode;
-                                       if (NodeToChildren [parentNode] == null)
-                                               NodeToChildren [parentNode] = 
new SiteMapNodeCollection ();
-                                       
-                                       ((SiteMapNodeCollection) NodeToChildren 
[parentNode]).Add (node);
-                               }
-                       }
+                       SiteMapNode ret = this.FindSiteMapNode 
(context.Request.RawUrl);
+                       if (ret == null)
+                               ret = this.FindSiteMapNode 
(context.Request.Path);
+                       return ret;
                }
+
+               public abstract SiteMapNode FindSiteMapNode (string rawUrl);
                
-               Hashtable nodeToParent;
-               Hashtable NodeToParent {
-                       get {
-                               if (nodeToParent == null) {
-                                       lock (this) {
-                                               if (nodeToParent == null)
-                                                       nodeToParent = new 
Hashtable ();
-                                       }
-                               }
-                               return nodeToParent;
-                       }
+               public virtual SiteMapNode FindSiteMapNodeFromKey (string key)
+               {
+                       if (key == null)
+                               throw new ArgumentNullException ("key");
+                       
+                       return null;
                }
+
+               public abstract SiteMapNodeCollection GetChildNodes 
(SiteMapNode node);
                
-               Hashtable nodeToChildren;
-               Hashtable NodeToChildren {
-                       get {
-                               if (nodeToChildren == null) {
-                                       lock (this) {
-                                               if (nodeToChildren == null)
-                                                       nodeToChildren = new 
Hashtable ();
-                                       }
-                               }
-                               return nodeToChildren;
-                       }
-               }
+               public abstract SiteMapNode GetParentNode (SiteMapNode node);
                
-               Hashtable urlToNode;
-               Hashtable UrlToNode {
-                       get {
-                               if (urlToNode == null) {
-                                       lock (this) {
-                                               if (urlToNode == null) {
-                                                       urlToNode = new 
Hashtable (
-                                                               
CaseInsensitiveHashCodeProvider.DefaultInvariant,
-                                                               
CaseInsensitiveComparer.DefaultInvariant
-                                                       );
-                                               }
-                                       }
-                               }
-                               return urlToNode;
-                       }
+               public virtual SiteMapNode GetCurrentNodeAndHintAncestorNodes 
(int upLevel)
+               {
+                       if (upLevel < -1) throw new ArgumentOutOfRangeException 
("upLevel");
+
+                       return CurrentNode;
                }
                
-               protected virtual void Clear ()
+               public virtual SiteMapNode 
GetCurrentNodeAndHintNeighborhoodNodes (int upLevel, int downLevel)
                {
-                       lock (this) {
-                               if (urlToNode != null)
-                                       urlToNode.Clear ();
-                               if (nodeToChildren != null)
-                                       nodeToChildren.Clear ();
-                               if (nodeToParent != null)
-                                       nodeToParent.Clear ();
-                       }
+                       if (upLevel < -1) throw new ArgumentOutOfRangeException 
("upLevel");
+                       if (downLevel < -1) throw new 
ArgumentOutOfRangeException ("downLevel");
+                       
+                       return CurrentNode;
                }
-
-               public virtual SiteMapNode FindSiteMapNode (string rawUrl)
+               
+               public virtual SiteMapNode 
GetParentNodeRelativeToCurrentNodeAndHintDownFromParent (int walkupLevels, int 
relativeDepthFromWalkup)
                {
-                       if (rawUrl == null)
-                               throw new ArgumentNullException ("rawUrl");
+                       if (walkupLevels < 0) throw new 
ArgumentOutOfRangeException ("walkupLevels");
+                       if (relativeDepthFromWalkup < 0) throw new 
ArgumentOutOfRangeException ("relativeDepthFromWalkup");
                        
-                       if (rawUrl.Length > 0) {
-                               this.BuildSiteMap();
-                               rawUrl = 
UrlUtils.ResolveVirtualPathFromAppAbsolute (rawUrl);
-                               return (SiteMapNode) UrlToNode [rawUrl];
-                       }
-                       return null;
+                       SiteMapNode node = GetCurrentNodeAndHintAncestorNodes 
(walkupLevels);
+                       for (int n=0; n<walkupLevels && node != null; n++)
+                               node = GetParentNode (node);
+                               
+                       if (node == null) return null;
+
+                       HintNeighborhoodNodes (node, 0, 
relativeDepthFromWalkup);
+                       return node;
                }
                
-               public virtual SiteMapNodeCollection GetChildNodes (SiteMapNode 
node)
+               public virtual SiteMapNode 
GetParentNodeRelativeToNodeAndHintDownFromParent (SiteMapNode node, int 
walkupLevels, int relativeDepthFromWalkup)
                {
-                       if (node == null)
-                               throw new ArgumentNullException ("node");
+                       if (walkupLevels < 0) throw new 
ArgumentOutOfRangeException ("walkupLevels");
+                       if (relativeDepthFromWalkup < 0) throw new 
ArgumentOutOfRangeException ("relativeDepthFromWalkup");
+                       if (node == null) throw new ArgumentNullException 
("node");
                        
-                       this.BuildSiteMap();
-                       SiteMapNodeCollection ret = (SiteMapNodeCollection) 
NodeToChildren [node];
+                       HintAncestorNodes (node, walkupLevels);
+                       for (int n=0; n<walkupLevels && node != null; n++)
+                               node = GetParentNode (node);
+                               
+                       if (node == null) return null;
                        
-                       if (ret != null)
-                               return SiteMapNodeCollection.ReadOnly (ret);
-                       
-                       return null;
+                       HintNeighborhoodNodes (node, 0, 
relativeDepthFromWalkup);
+                       return node;
                }
                
-               public virtual SiteMapNode GetParentNode(SiteMapNode node) {
-                       if (node == null)
-                               throw new ArgumentNullException ("node");
-                       this.BuildSiteMap();
-                       return (SiteMapNode) NodeToParent [node];
+               protected internal abstract SiteMapNode GetRootNodeCore ();
+               
+               protected static SiteMapNode GetRootNodeCoreFromProvider 
(SiteMapProvider provider)
+               {
+                       return provider.GetRootNodeCore ();
                }
                
-               public void RemoveNode (SiteMapNode node)
+               public virtual void HintAncestorNodes (SiteMapNode node, int 
upLevel)
                {
-       
+                       if (upLevel < -1) throw new ArgumentOutOfRangeException 
("upLevel");
+                       if (node == null) throw new ArgumentNullException 
("node");
+               }
+               
+               public virtual void HintNeighborhoodNodes (SiteMapNode node, 
int upLevel, int downLevel)
+               {
+                       if (upLevel < -1) throw new ArgumentOutOfRangeException 
("upLevel");
+                       if (downLevel < -1) throw new 
ArgumentOutOfRangeException ("downLevel");
+                       if (node == null) throw new ArgumentNullException 
("node");
+               }
+               
+               public virtual void RemoveNode (SiteMapNode node)
+               {
                        if (node == null)
                                throw new ArgumentNullException("node");
-                       
-                       lock (this) {
-                               SiteMapNode parent = (SiteMapNode) NodeToParent 
[node];
-                               if (NodeToParent.Contains (node))
-                                       NodeToParent.Remove (node);
-                               
-                               if (node.Url != null && node.Url.Length > 0 && 
UrlToNode.Contains (node.Url))
-                                       UrlToNode.Remove (node.Url);
-                               
-                               if (parent != null) {
-                                       SiteMapNodeCollection siblings = 
(SiteMapNodeCollection) NodeToChildren [node];
-                                       if (siblings != null && 
siblings.Contains (node))
-                                               siblings.Remove (node);
-                               }
-                       }
                }
 
                public override void Initialize (string name, 
NameValueCollection attributes)
-               { 
-                       if (attributes != null)
-                               description = attributes ["description"];
+               {
+                       base.Initialize (name, attributes);
+                       if (attributes["securityTrimmingEnabled"] != null)
+                               securityTrimming = (bool) Convert.ChangeType 
(attributes ["securityTrimmingEnabled"], typeof(bool));
+               }
                
+               [MonoTODO]
+               public virtual bool IsAccessibleToUser (HttpContext context, 
SiteMapNode node)
+               {
+                       return true;
                }
                
                public virtual SiteMapNode CurrentNode {
                        get {
-                               SiteMapNode ret;
-                               
                                if (HttpContext.Current != null) {
-                                       ret = this.FindSiteMapNode 
(HttpContext.Current.Request.RawUrl);
-                                       if (ret == null)
-                                               ret = this.FindSiteMapNode 
(HttpContext.Current.Request.Path);
-
-                                       return ret;
-                               }
-                               
-                               return null;
+                                       SiteMapNode ret = ResolveSiteMapNode 
(HttpContext.Current);
+                                       if (ret != null) return ret;
+                                       return FindSiteMapNode 
(HttpContext.Current);
+                               } else
+                                       return null;
                        }
                }
                
-               string description;
-               public virtual string Description {
-                       get { return description != null ? description : 
"SiteMapProvider"; }
-               }
-               
-               SiteMapProvider parentProvider;
                public virtual SiteMapProvider ParentProvider {
                        get { return parentProvider; }
                        set { parentProvider = value; }
                }
                
-               SiteMapProvider rootProviderCache;
                public virtual SiteMapProvider RootProvider {
                        get {
-                               if (rootProviderCache == null) {
-                                       lock (this) {
-                                               if (rootProviderCache == null) {
-                                                       SiteMapProvider current 
= this;
-                                                       while 
(current.ParentProvider != null)
-                                                               current = 
current.ParentProvider;
-                                                       
-                                                       rootProviderCache = 
current;
-                                               }
+                               lock (this) {
+                                       if (rootProviderCache == null) {
+                                               SiteMapProvider current = this;
+                                               while (current.ParentProvider 
!= null)
+                                                       current = 
current.ParentProvider;
+                                               
+                                               rootProviderCache = current;
                                        }
                                }
                                return rootProviderCache;
                        }
                }
                
+               protected SiteMapNode ResolveSiteMapNode (HttpContext context)
+               {
+                       SiteMapResolveEventArgs args = new 
SiteMapResolveEventArgs (context, this);
+                       if (SiteMapResolve != null) {
+                               lock (resolveLock) {
+                                       if (resolving) return null;
+                                       resolving = true;
+                                       SiteMapNode r = SiteMapResolve (this, 
args);
+                                       resolving = false;
+                                       return r;
+                               }
+                       }
+                       else
+                               return null;
+               }
+               
                public bool EnableLocalization {
                        get { return enableLocalization; }
                        set { enableLocalization = value; }
                }
+               
+               public bool SecurityTrimmingEnabled {
+                       get { return securityTrimming; }
+               }
 
-               public abstract SiteMapNode BuildSiteMap ();
-               public abstract SiteMapNode RootNode { get; }
+               public virtual SiteMapNode RootNode {
+                       get {
+                               SiteMapNode node = GetRootNodeCore ();
+                               if (IsAccessibleToUser (HttpContext.Current, 
node))
+                                       return node;
+                               else
+                                       return null;
+                       }
+               }
        
+               public event SiteMapResolveEventHandler SiteMapResolve;
        }
 }
 #endif

Modified: trunk/mcs/class/System.Web/System.Web/SiteMapProviderCollection.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web/SiteMapProviderCollection.cs  
2005-05-26 16:03:34 UTC (rev 45059)
+++ trunk/mcs/class/System.Web/System.Web/SiteMapProviderCollection.cs  
2005-05-26 16:16:09 UTC (rev 45060)
@@ -3,8 +3,10 @@
 //
 // Authors:
 //     Ben Maurer ([EMAIL PROTECTED])
+//     Lluis Sanchez Gual ([EMAIL PROTECTED])
 //
-// (C) 2003 Ben Maurer
+//  (C) 2003 Ben Maurer
+//  (C) 2005 Novell, Inc (http://www.novell.com)
 //
 
 //
@@ -36,7 +38,7 @@
 using System.Web.UI;
 
 namespace System.Web {
-       public class SiteMapProviderCollection : ProviderCollection
+       public sealed class SiteMapProviderCollection : ProviderCollection
        {
                public SiteMapProviderCollection () {}
                
@@ -44,22 +46,27 @@
                {
                        if (provider == null)
                                throw new ArgumentNullException ("provider");
-                       if ((provider as SiteMapProvider) == null)
+                       if (!(provider is SiteMapProvider))
                                throw new 
InvalidOperationException(String.Format ("{0} must implement {1} to act as a 
site map provider", provider.GetType (), typeof (SiteMapProvider)));
-                       
+                       if (this [provider.Name] != null)
+                               throw new ArgumentException ("Duplicate site 
map providers");
                        base.Add (provider);
                }
                
-               public virtual void AddArray (ProviderBase[] providerArray)
-               {                       
-                       foreach (ProviderBase p in providerArray) {
-                               if (this [p.Name] != null)
-                                       throw new ArgumentException ("Duplicate 
site map providers");
+               public void Add (SiteMapProvider provider)
+               {
+                       Add ((ProviderBase)provider);
+               }
+               
+               public void AddArray (SiteMapProvider[] providerArray)
+               {
+                       foreach (SiteMapProvider p in providerArray)
                                Add (p);
-                       }
                }
                
-               public new SiteMapProvider this [string name] { get { return 
(SiteMapProvider) base [name]; } }
+               public new SiteMapProvider this [string name] {
+                       get { return (SiteMapProvider) base [name]; }
+               }
        }
 }
 #endif

Added: trunk/mcs/class/System.Web/System.Web/StaticSiteMapProvider.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web/StaticSiteMapProvider.cs      
2005-05-26 16:03:34 UTC (rev 45059)
+++ trunk/mcs/class/System.Web/System.Web/StaticSiteMapProvider.cs      
2005-05-26 16:16:09 UTC (rev 45060)
@@ -0,0 +1,228 @@
+//
+// System.Web.StaticSiteMapProvider.cs
+//
+// Authors:
+//     Lluis Sanchez Gual ([EMAIL PROTECTED])
+//     Ben Maurer ([EMAIL PROTECTED])
+//
+// (C) 2003 Ben Maurer
+// (C) 2005 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.
+//
+
+
+#if NET_2_0
+using System.Collections;
+using System.Collections.Specialized;
+using System.Text;
+using System.Configuration.Provider;
+using System.Web.Util;
+using System.Globalization;
+
+namespace System.Web
+{
+       public abstract class StaticSiteMapProvider : SiteMapProvider
+       {
+               Hashtable nodeToParent;
+               Hashtable nodeToChildren;
+               Hashtable urlToNode;
+               Hashtable keyToNode;
+               
+               internal protected override void AddNode (SiteMapNode node, 
SiteMapNode parentNode)
+               {
+                       if (node == null)
+                               throw new ArgumentNullException ("node");
+                       
+                       lock (this) {
+                               string url = node.Url;
+                               if (url != null && url.Length > 0) {
+                                       if (UrlUtils.IsRelativeUrl (url))
+                                               url = UrlUtils.Combine 
(HttpRuntime.AppDomainAppVirtualPath, url);
+                                       else
+                                               url = 
UrlUtils.ResolveVirtualPathFromAppAbsolute (url);
+                                       
+                                       if (FindSiteMapNode (url) != null)
+                                               throw new 
InvalidOperationException ();
+                               
+                                       UrlToNode [url] = node;
+                               }
+                               
+                               if (FindSiteMapNodeFromKey (node.Key) != null)
+                                       throw new InvalidOperationException 
(string.Format ("A node with key {0} already exists.",node.Key));
+                               KeyToNode [node.Key] = node;
+                               
+                               if (parentNode != null) {
+                                       NodeToParent [node] = parentNode;
+                                       if (NodeToChildren [parentNode] == null)
+                                               NodeToChildren [parentNode] = 
new SiteMapNodeCollection ();
+                                       
+                                       ((SiteMapNodeCollection) NodeToChildren 
[parentNode]).Add (node);
+                               }
+                       }
+               }
+               
+               Hashtable NodeToParent {
+                       get {
+                               lock (this) {
+                                       if (nodeToParent == null)
+                                               nodeToParent = new Hashtable ();
+                               }
+                               return nodeToParent;
+                       }
+               }
+               
+               Hashtable NodeToChildren {
+                       get {
+                               lock (this) {
+                                       if (nodeToChildren == null)
+                                               nodeToChildren = new Hashtable 
();
+                               }
+                               return nodeToChildren;
+                       }
+               }
+               
+               Hashtable UrlToNode {
+                       get {
+                               lock (this) {
+                                       if (urlToNode == null) {
+                                               urlToNode = new Hashtable (
+                                                       
CaseInsensitiveHashCodeProvider.DefaultInvariant,
+                                                       
CaseInsensitiveComparer.DefaultInvariant
+                                               );
+                                       }
+                               }
+                               return urlToNode;
+                       }
+               }
+               
+               Hashtable KeyToNode {
+                       get {
+                               lock (this) {
+                                       if (keyToNode == null)
+                                               keyToNode = new Hashtable ();
+                               }
+                               return keyToNode;
+                       }
+               }
+               
+               protected virtual void Clear ()
+               {
+                       lock (this) {
+                               if (urlToNode != null)
+                                       urlToNode.Clear ();
+                               if (nodeToChildren != null)
+                                       nodeToChildren.Clear ();
+                               if (nodeToParent != null)
+                                       nodeToParent.Clear ();
+                               if (keyToNode != null)
+                                       keyToNode.Clear ();
+                       }
+               }
+
+               public override SiteMapNode FindSiteMapNode (string rawUrl)
+               {
+                       if (rawUrl == null)
+                               throw new ArgumentNullException ("rawUrl");
+                       
+                       if (rawUrl.Length > 0) {
+                               this.BuildSiteMap();
+                               rawUrl = 
UrlUtils.ResolveVirtualPathFromAppAbsolute (rawUrl);
+                               SiteMapNode node = (SiteMapNode) UrlToNode 
[rawUrl];
+                               if (node != null && IsAccessibleToUser 
(HttpContext.Current, node))
+                                       return node;
+                       }
+                       return null;
+               }
+
+               public override SiteMapNodeCollection GetChildNodes 
(SiteMapNode node)
+               {
+                       if (node == null)
+                               throw new ArgumentNullException ("node");
+                       
+                       this.BuildSiteMap();
+                       SiteMapNodeCollection col = (SiteMapNodeCollection) 
NodeToChildren [node];
+                       if (col == null) return 
SiteMapNodeCollection.EmptyCollection;
+                       
+                       SiteMapNodeCollection ret = null;
+                       for (int n=0; n<col.Count; n++) {
+                               if (!IsAccessibleToUser (HttpContext.Current, 
col[n])) {
+                                       if (ret == null) {
+                                               ret = new SiteMapNodeCollection 
();
+                                               for (int m=0; m<n; m++)
+                                                       ret.Add (col[m]);
+                                       }
+                               } else if (ret != null)
+                                       ret.Add (col[n]);
+                       }
+                       
+                       if (ret != null) {
+                               if (ret.Count > 0)
+                                       return SiteMapNodeCollection.ReadOnly 
(ret);
+                       } else
+                               return SiteMapNodeCollection.ReadOnly (col);
+                       
+                       return null;
+               }
+               
+               public override SiteMapNode GetParentNode (SiteMapNode node)
+               {
+                       if (node == null)
+                               throw new ArgumentNullException ("node");
+                       this.BuildSiteMap();
+                       SiteMapNode parent = (SiteMapNode) NodeToParent [node];
+                       return parent != null && IsAccessibleToUser 
(HttpContext.Current, parent) ? parent : null;
+               }
+               
+               public override void RemoveNode (SiteMapNode node)
+               {
+                       if (node == null)
+                               throw new ArgumentNullException("node");
+                       
+                       lock (this) {
+                               SiteMapNode parent = (SiteMapNode) NodeToParent 
[node];
+                               if (NodeToParent.Contains (node))
+                                       NodeToParent.Remove (node);
+                               
+                               if (node.Url != null && node.Url.Length > 0 && 
UrlToNode.Contains (node.Url))
+                                       UrlToNode.Remove (node.Url);
+                               
+                               if (parent != null) {
+                                       SiteMapNodeCollection siblings = 
(SiteMapNodeCollection) NodeToChildren [node];
+                                       if (siblings != null && 
siblings.Contains (node))
+                                               siblings.Remove (node);
+                               }
+                       }
+               }
+               
+               public override SiteMapNode FindSiteMapNodeFromKey (string key)
+               {
+                       if (key == null)
+                               throw new ArgumentNullException ("key");
+                       
+                       SiteMapNode ret = (SiteMapNode) KeyToNode [key];
+                       return ret != null && IsAccessibleToUser 
(HttpContext.Current, ret) ? ret : null;
+               }
+
+               public abstract SiteMapNode BuildSiteMap ();
+       }
+}
+#endif
+

Modified: trunk/mcs/class/System.Web/System.Web/XmlSiteMapProvider.cs
===================================================================
--- trunk/mcs/class/System.Web/System.Web/XmlSiteMapProvider.cs 2005-05-26 
16:03:34 UTC (rev 45059)
+++ trunk/mcs/class/System.Web/System.Web/XmlSiteMapProvider.cs 2005-05-26 
16:16:09 UTC (rev 45060)
@@ -3,8 +3,10 @@
 //
 // Authors:
 //     Ben Maurer ([EMAIL PROTECTED])
+//     Lluis Sanchez Gual ([EMAIL PROTECTED])
 //
 // (C) 2003 Ben Maurer
+// (C) 2005 Novell, Inc (http://www.novell.com)
 //
 
 //
@@ -37,10 +39,15 @@
 using System.Web.Util;
 using System.IO;
 
-namespace System.Web {
-       public class XmlSiteMapProvider : SiteMapProvider, IDisposable {
+namespace System.Web
+{
+       public class XmlSiteMapProvider : StaticSiteMapProvider, IDisposable
+       {
                static readonly char [] seperators = { ';', ',' };
                bool building;
+               string file;
+               SiteMapNode root = null;
+               FileSystemWatcher watcher;
                
                public override SiteMapNode BuildSiteMap ()
                {
@@ -52,15 +59,23 @@
                                return null;
                        
                        lock (this) {
-                               building = true;
-                               if (root != null)
-                                       return root;
-                               XmlDocument d = new XmlDocument ();
-                               d.Load (file);
-                               
-                               root = BuildSiteMapRecursive 
(d.SelectSingleNode ("/siteMap/siteMapNode"));
-                               AddNode (root);
-                               building = false;
+                               try {
+                                       building = true;
+                                       if (root != null)
+                                               return root;
+                                       XmlDocument d = new XmlDocument ();
+                                       d.Load (file);
+                                       
+                                       XmlNode nod = d.DocumentElement 
["siteMapNode"];
+                                       if (nod == null)
+                                               throw new HttpException 
("Invalid site map file: " + Path.GetFileName (file));
+                                               
+                                       root = BuildSiteMapRecursive (nod);
+                                               
+                                       AddNode (root);
+                               } finally {
+                                       building = false;
+                               }
                                return root;
                        }
                }
@@ -78,7 +93,6 @@
                [MonoTODO]
                SiteMapNode BuildSiteMapRecursive (XmlNode xmlNode)
                {
-
                        if (xmlNode.Name != "siteMapNode")
                                throw new ConfigurationException ("incorrect 
element name", xmlNode);
                        
@@ -98,7 +112,7 @@
                                string roles = GetOptionalAttribute (xmlNode, 
"roles");
                                
                                ArrayList keywordsList = new ArrayList ();
-                               if (keywords != null) {
+                               if (keywords != null && keywords.Length > 0) {
                                        foreach (string s in keywords.Split 
(seperators)) {
                                                string ss = s.Trim ();
                                                if (ss.Length > 0)
@@ -107,7 +121,7 @@
                                }
                                
                                ArrayList rolesList = new ArrayList ();
-                               if (roles != null) {
+                               if (roles != null && roles.Length > 0) {
                                        foreach (string s in roles.Split 
(seperators)) {
                                                string ss = s.Trim ();
                                                if (ss.Length > 0)
@@ -115,10 +129,10 @@
                                        }
                                }
                                
-                               SiteMapNode node = new SiteMapNode (this, null, 
url, title, description,
+                               SiteMapNode node = new SiteMapNode (this, url, 
url, title, description,
                                        /*ArrayList.ReadOnly (keywordsList), 
*/ArrayList.ReadOnly (rolesList), null,
-                                       null); // TODO what do they want for 
attributes
-                               
+                                       null, null); // TODO what do they want 
for attributes
+                                       
                                foreach (XmlNode child in xmlNode.ChildNodes) {
                                        if (child.NodeType != 
XmlNodeType.Element)
                                                continue;
@@ -135,10 +149,9 @@
                        root = null;
                }
 
-               [MonoTODO]
                public void Dispose ()
                {
-                       // what do i do?
+                       watcher.Dispose ();
                }
                
                [MonoTODO]
@@ -160,7 +173,20 @@
                                file = 
Path.Combine(HttpRuntime.AppDomainAppPath, file);
                        else
                                file = 
UrlUtils.ResolvePhysicalPathFromAppAbsolute (file);
+                               
+                       if (File.Exists (file)) {
+                               watcher = new FileSystemWatcher ();
+                               watcher.Path = Path.GetFullPath 
(Path.GetDirectoryName (file));
+                               watcher.Filter = Path.GetFileName (file);
+                               watcher.Changed += new FileSystemEventHandler 
(OnFileChanged);
+                               watcher.EnableRaisingEvents = true;
+                       }
                }
+               
+               void OnFileChanged (object sender, FileSystemEventArgs args)
+               {
+                       Clear ();
+               }
 
                public override SiteMapNode RootNode {
                        get {
@@ -169,8 +195,10 @@
                        }
                }
                
-               string file;
-               SiteMapNode root = null;
+               protected internal override SiteMapNode GetRootNodeCore ()
+               {
+                       return BuildSiteMap ();
+               }
        }
 
 }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to