2004-11-18 Lluis Sanchez Gual <lluis@novell.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 //
7 // (C) 2003 Ben Maurer
8 //
9
10 //
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:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
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.
29 //
30
31 #if NET_2_0
32 using System.Collections;
33 using System.Collections.Specialized;
34 using System.Text;
35 using System.Configuration.Provider;
36 using System.Web.Util;
37 using System.Globalization;
38
39 namespace System.Web {
40         public abstract class SiteMapProvider : ProviderBase {
41                 
42                 bool enableLocalization;
43                 
44                 public void AddNode (SiteMapNode node)
45                 {
46                         AddNode (node, null);
47                 }
48                 
49                 public void AddNode (SiteMapNode node, SiteMapNode parentNode)
50                 {
51                         if (node == null)
52                                 throw new ArgumentNullException ("node");
53                         
54                         lock (this) {
55                                 string url = node.Url;
56                                 if (url != null && url.Length > 0) {
57                                         
58                                         
59                                                 if (UrlUtils.IsRelativeUrl (url))
60                                                         url = UrlUtils.Combine (HttpRuntime.AppDomainAppVirtualPath, url);
61                                                 else
62                                                         url = UrlUtils.ResolveVirtualPathFromAppAbsolute (url);
63                                                 
64                                                 if (FindSiteMapNode (url) != null)
65                                                         throw new InvalidOperationException ();
66                                         
67                                         UrlToNode [url] = node;
68                                 }
69                                 
70                                 if (parentNode != null) {
71                                         NodeToParent [node] = parentNode;
72                                         if (NodeToChildren [parentNode] == null)
73                                                 NodeToChildren [parentNode] = new SiteMapNodeCollection ();
74                                         
75                                         ((SiteMapNodeCollection) NodeToChildren [parentNode]).Add (node);
76                                 }
77                         }
78                 }
79                 
80                 Hashtable nodeToParent;
81                 Hashtable NodeToParent {
82                         get {
83                                 if (nodeToParent == null) {
84                                         lock (this) {
85                                                 if (nodeToParent == null)
86                                                         nodeToParent = new Hashtable ();
87                                         }
88                                 }
89                                 return nodeToParent;
90                         }
91                 }
92                 
93                 Hashtable nodeToChildren;
94                 Hashtable NodeToChildren {
95                         get {
96                                 if (nodeToChildren == null) {
97                                         lock (this) {
98                                                 if (nodeToChildren == null)
99                                                         nodeToChildren = new Hashtable ();
100                                         }
101                                 }
102                                 return nodeToChildren;
103                         }
104                 }
105                 
106                 Hashtable urlToNode;
107                 Hashtable UrlToNode {
108                         get {
109                                 if (urlToNode == null) {
110                                         lock (this) {
111                                                 if (urlToNode == null) {
112                                                         urlToNode = new Hashtable (
113                                                                 new CaseInsensitiveHashCodeProvider (),
114                                                                 new CaseInsensitiveComparer ()
115                                                         );
116                                                 }
117                                         }
118                                 }
119                                 return urlToNode;
120                         }
121                 }
122                 
123                 protected virtual void Clear ()
124                 {
125                         lock (this) {
126                                 if (urlToNode != null)
127                                         urlToNode.Clear ();
128                                 if (nodeToChildren != null)
129                                         nodeToChildren.Clear ();
130                                 if (nodeToParent != null)
131                                         nodeToParent.Clear ();
132                         }
133                 }
134
135                 public virtual SiteMapNode FindSiteMapNode (string rawUrl)
136                 {
137                         if (rawUrl == null)
138                                 throw new ArgumentNullException ("rawUrl");
139                         
140                         if (rawUrl.Length > 0) {
141                                 this.BuildSiteMap();
142                                 rawUrl = UrlUtils.ResolveVirtualPathFromAppAbsolute (rawUrl);
143                                 return (SiteMapNode) UrlToNode [rawUrl];
144                         }
145                         return null;
146                 }
147                 
148                 public virtual SiteMapNodeCollection GetChildNodes (SiteMapNode node)
149                 {
150                         if (node == null)
151                                 throw new ArgumentNullException ("node");
152                         
153                         this.BuildSiteMap();
154                         SiteMapNodeCollection ret = (SiteMapNodeCollection) NodeToChildren [node];
155                         
156                         if (ret != null)
157                                 return SiteMapNodeCollection.ReadOnly (ret);
158                         
159                         return null;
160                 }
161                 
162                 public virtual SiteMapNode GetParentNode(SiteMapNode node) {
163                         if (node == null)
164                                 throw new ArgumentNullException ("node");
165                         this.BuildSiteMap();
166                         return (SiteMapNode) NodeToParent [node];
167                 }
168                 
169                 public void RemoveNode (SiteMapNode node)
170                 {
171         
172                         if (node == null)
173                                 throw new ArgumentNullException("node");
174                         
175                         lock (this) {
176                                 SiteMapNode parent = (SiteMapNode) NodeToParent [node];
177                                 if (NodeToParent.Contains (node))
178                                         NodeToParent.Remove (node);
179                                 
180                                 if (node.Url != null && node.Url.Length > 0 && UrlToNode.Contains (node.Url))
181                                         UrlToNode.Remove (node.Url);
182                                 
183                                 if (parent != null) {
184                                         SiteMapNodeCollection siblings = (SiteMapNodeCollection) NodeToChildren [node];
185                                         if (siblings != null && siblings.Contains (node))
186                                                 siblings.Remove (node);
187                                 }
188                         }
189                 }
190
191                 public override void Initialize (string name, NameValueCollection attributes)
192                 { 
193                         if (attributes != null)
194                                 description = attributes ["description"];
195                 
196                 }
197                 
198                 public virtual SiteMapNode CurrentNode {
199                         get {
200                                 SiteMapNode ret;
201                                 
202                                 if (HttpContext.Current != null) {
203                                         ret = this.FindSiteMapNode (HttpContext.Current.Request.RawUrl);
204                                         if (ret == null)
205                                                 ret = this.FindSiteMapNode (HttpContext.Current.Request.Path);
206
207                                         return ret;
208                                 }
209                                 
210                                 return null;
211                         }
212                 }
213                 
214                 string description;
215                 public virtual string Description {
216                         get { return description != null ? description : "SiteMapProvider"; }
217                 }
218                 
219                 SiteMapProvider parentProvider;
220                 public virtual SiteMapProvider ParentProvider {
221                         get { return parentProvider; }
222                         set { parentProvider = value; }
223                 }
224                 
225                 SiteMapProvider rootProviderCache;
226                 public virtual SiteMapProvider RootProvider {
227                         get {
228                                 if (rootProviderCache == null) {
229                                         lock (this) {
230                                                 if (rootProviderCache == null) {
231                                                         SiteMapProvider current = this;
232                                                         while (current.ParentProvider != null)
233                                                                 current = current.ParentProvider;
234                                                         
235                                                         rootProviderCache = current;
236                                                 }
237                                         }
238                                 }
239                                 return rootProviderCache;
240                         }
241                 }
242                 
243                 public bool EnableLocalization {
244                         get { return enableLocalization; }
245                         set { enableLocalization = value; }
246                 }
247
248                 public abstract SiteMapNode BuildSiteMap ();
249                 public abstract SiteMapNode RootNode { get; }
250         
251         }
252 }
253 #endif
254