2006-02-01 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web / SiteMapProvider.cs
1 //
2 // System.Web.SiteMapProvider
3 //
4 // Authors:
5 //      Ben Maurer (bmaurer@users.sourceforge.net)
6 //      Lluis Sanchez Gual (lluis@novell.com)
7 //
8 // (C) 2003 Ben Maurer
9 // (C) 2005 Novell, Inc (http://www.novell.com)
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 #if NET_2_0
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Text;
37 using System.Configuration.Provider;
38 using System.Web.Util;
39 using System.Globalization;
40
41 namespace System.Web {
42         public abstract class SiteMapProvider : ProviderBase {
43                 
44                 bool enableLocalization;
45                 SiteMapProvider parentProvider;
46                 SiteMapProvider rootProviderCache;
47                 bool securityTrimming;
48                 object resolveLock = new Object();
49                 bool resolving;
50                 
51                 protected virtual void AddNode (SiteMapNode node)
52                 {
53                         AddNode (node, null);
54                 }
55                 
56                 internal protected virtual void AddNode (SiteMapNode node, SiteMapNode parentNode)
57                 {
58                         if (node == null)
59                                 throw new ArgumentNullException ("node");
60                 }
61
62                 public virtual SiteMapNode FindSiteMapNode (HttpContext context)
63                 {
64                         if (context == null)
65                                 throw new ArgumentNullException ("context");
66                         
67                         SiteMapNode ret = this.FindSiteMapNode (context.Request.RawUrl);
68                         if (ret == null)
69                                 ret = this.FindSiteMapNode (context.Request.Path);
70                         return ret;
71                 }
72
73                 public abstract SiteMapNode FindSiteMapNode (string rawUrl);
74                 
75                 public virtual SiteMapNode FindSiteMapNodeFromKey (string key)
76                 {
77                         if (key == null)
78                                 throw new ArgumentNullException ("key");
79                         
80                         return null;
81                 }
82
83                 public abstract SiteMapNodeCollection GetChildNodes (SiteMapNode node);
84                 
85                 public abstract SiteMapNode GetParentNode (SiteMapNode node);
86                 
87                 public virtual SiteMapNode GetCurrentNodeAndHintAncestorNodes (int upLevel)
88                 {
89                         if (upLevel < -1) throw new ArgumentOutOfRangeException ("upLevel");
90
91                         return CurrentNode;
92                 }
93                 
94                 public virtual SiteMapNode GetCurrentNodeAndHintNeighborhoodNodes (int upLevel, int downLevel)
95                 {
96                         if (upLevel < -1) throw new ArgumentOutOfRangeException ("upLevel");
97                         if (downLevel < -1) throw new ArgumentOutOfRangeException ("downLevel");
98                         
99                         return CurrentNode;
100                 }
101                 
102                 public virtual SiteMapNode GetParentNodeRelativeToCurrentNodeAndHintDownFromParent (int walkupLevels, int relativeDepthFromWalkup)
103                 {
104                         if (walkupLevels < 0) throw new ArgumentOutOfRangeException ("walkupLevels");
105                         if (relativeDepthFromWalkup < 0) throw new ArgumentOutOfRangeException ("relativeDepthFromWalkup");
106                         
107                         SiteMapNode node = GetCurrentNodeAndHintAncestorNodes (walkupLevels);
108                         for (int n=0; n<walkupLevels && node != null; n++)
109                                 node = GetParentNode (node);
110                                 
111                         if (node == null) return null;
112
113                         HintNeighborhoodNodes (node, 0, relativeDepthFromWalkup);
114                         return node;
115                 }
116                 
117                 public virtual SiteMapNode GetParentNodeRelativeToNodeAndHintDownFromParent (SiteMapNode node, int walkupLevels, int relativeDepthFromWalkup)
118                 {
119                         if (walkupLevels < 0) throw new ArgumentOutOfRangeException ("walkupLevels");
120                         if (relativeDepthFromWalkup < 0) throw new ArgumentOutOfRangeException ("relativeDepthFromWalkup");
121                         if (node == null) throw new ArgumentNullException ("node");
122                         
123                         HintAncestorNodes (node, walkupLevels);
124                         for (int n=0; n<walkupLevels && node != null; n++)
125                                 node = GetParentNode (node);
126                                 
127                         if (node == null) return null;
128                         
129                         HintNeighborhoodNodes (node, 0, relativeDepthFromWalkup);
130                         return node;
131                 }
132                 
133                 protected internal abstract SiteMapNode GetRootNodeCore ();
134                 
135                 protected static SiteMapNode GetRootNodeCoreFromProvider (SiteMapProvider provider)
136                 {
137                         return provider.GetRootNodeCore ();
138                 }
139                 
140                 public virtual void HintAncestorNodes (SiteMapNode node, int upLevel)
141                 {
142                         if (upLevel < -1) throw new ArgumentOutOfRangeException ("upLevel");
143                         if (node == null) throw new ArgumentNullException ("node");
144                 }
145                 
146                 public virtual void HintNeighborhoodNodes (SiteMapNode node, int upLevel, int downLevel)
147                 {
148                         if (upLevel < -1) throw new ArgumentOutOfRangeException ("upLevel");
149                         if (downLevel < -1) throw new ArgumentOutOfRangeException ("downLevel");
150                         if (node == null) throw new ArgumentNullException ("node");
151                 }
152                 
153                 public virtual void RemoveNode (SiteMapNode node)
154                 {
155                         if (node == null)
156                                 throw new ArgumentNullException("node");
157                 }
158
159                 public override void Initialize (string name, NameValueCollection attributes)
160                 {
161                         base.Initialize (name, attributes);
162                         if (attributes["securityTrimmingEnabled"] != null)
163                                 securityTrimming = (bool) Convert.ChangeType (attributes ["securityTrimmingEnabled"], typeof(bool));
164                 }
165                 
166                 [MonoTODO]
167                 public virtual bool IsAccessibleToUser (HttpContext context, SiteMapNode node)
168                 {
169                         return true;
170                 }
171                 
172                 public virtual SiteMapNode CurrentNode {
173                         get {
174                                 if (HttpContext.Current != null) {
175                                         SiteMapNode ret = ResolveSiteMapNode (HttpContext.Current);
176                                         if (ret != null) return ret;
177                                         return FindSiteMapNode (HttpContext.Current);
178                                 } else
179                                         return null;
180                         }
181                 }
182                 
183                 public virtual SiteMapProvider ParentProvider {
184                         get { return parentProvider; }
185                         set { parentProvider = value; }
186                 }
187                 
188                 public virtual SiteMapProvider RootProvider {
189                         get {
190                                 lock (this) {
191                                         if (rootProviderCache == null) {
192                                                 SiteMapProvider current = this;
193                                                 while (current.ParentProvider != null)
194                                                         current = current.ParentProvider;
195                                                 
196                                                 rootProviderCache = current;
197                                         }
198                                 }
199                                 return rootProviderCache;
200                         }
201                 }
202                 
203                 protected SiteMapNode ResolveSiteMapNode (HttpContext context)
204                 {
205                         SiteMapResolveEventArgs args = new SiteMapResolveEventArgs (context, this);
206                         if (SiteMapResolve != null) {
207                                 lock (resolveLock) {
208                                         if (resolving) return null;
209                                         resolving = true;
210                                         SiteMapNode r = SiteMapResolve (this, args);
211                                         resolving = false;
212                                         return r;
213                                 }
214                         }
215                         else
216                                 return null;
217                 }
218                 
219                 public bool EnableLocalization {
220                         get { return enableLocalization; }
221                         set { enableLocalization = value; }
222                 }
223                 
224                 public bool SecurityTrimmingEnabled {
225                         get { return securityTrimming; }
226                 }
227
228                 public virtual SiteMapNode RootNode {
229                         get {
230                                 SiteMapNode node = GetRootNodeCore ();
231                                 if (IsAccessibleToUser (HttpContext.Current, node))
232                                         return node;
233                                 else
234                                         return null;
235                         }
236                 }
237         
238                 public event SiteMapResolveEventHandler SiteMapResolve;
239         }
240 }
241 #endif
242