Standardized Mainsoft ConstraintCollection tests.
[mono.git] / mcs / class / System.Web / System.Web / StaticSiteMapProvider.cs
1 //
2 // System.Web.StaticSiteMapProvider.cs
3 //
4 // Authors:
5 //      Lluis Sanchez Gual (lluis@novell.com)
6 //      Ben Maurer (bmaurer@users.sourceforge.net)
7 //
8 // (C) 2003 Ben Maurer
9 // (C) 2005 Novell, Inc (http://www.novell.com)
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
32 #if NET_2_0
33 using System.Collections;
34 using System.Collections.Specialized;
35 using System.Text;
36 using System.Configuration.Provider;
37 using System.Web.Util;
38 using System.Globalization;
39
40 namespace System.Web
41 {
42         public abstract class StaticSiteMapProvider : SiteMapProvider
43         {
44                 Hashtable nodeToParent;
45                 Hashtable nodeToChildren;
46                 Hashtable urlToNode;
47                 Hashtable keyToNode;
48                 
49                 internal protected override 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                                         if (UrlUtils.IsRelativeUrl (url))
58                                                 url = UrlUtils.Combine (HttpRuntime.AppDomainAppVirtualPath, url);
59                                         else
60                                                 url = UrlUtils.ResolveVirtualPathFromAppAbsolute (url);
61                                         
62                                         if (FindSiteMapNode (url) != null)
63                                                 throw new InvalidOperationException ();
64                                 
65                                         UrlToNode [url] = node;
66                                 }
67                                 
68                                 if (FindSiteMapNodeFromKey (node.Key) != null)
69                                         throw new InvalidOperationException (string.Format ("A node with key {0} already exists.",node.Key));
70                                 KeyToNode [node.Key] = node;
71                                 
72                                 if (parentNode != null) {
73                                         NodeToParent [node] = parentNode;
74                                         if (NodeToChildren [parentNode] == null)
75                                                 NodeToChildren [parentNode] = new SiteMapNodeCollection ();
76                                         
77                                         ((SiteMapNodeCollection) NodeToChildren [parentNode]).Add (node);
78                                 }
79                         }
80                 }
81                 
82                 Hashtable NodeToParent {
83                         get {
84                                 lock (this) {
85                                         if (nodeToParent == null)
86                                                 nodeToParent = new Hashtable ();
87                                 }
88                                 return nodeToParent;
89                         }
90                 }
91                 
92                 Hashtable NodeToChildren {
93                         get {
94                                 lock (this) {
95                                         if (nodeToChildren == null)
96                                                 nodeToChildren = new Hashtable ();
97                                 }
98                                 return nodeToChildren;
99                         }
100                 }
101                 
102                 Hashtable UrlToNode {
103                         get {
104                                 lock (this) {
105                                         if (urlToNode == null) {
106                                                 urlToNode = new Hashtable (
107                                                         CaseInsensitiveHashCodeProvider.DefaultInvariant,
108                                                         CaseInsensitiveComparer.DefaultInvariant
109                                                 );
110                                         }
111                                 }
112                                 return urlToNode;
113                         }
114                 }
115                 
116                 Hashtable KeyToNode {
117                         get {
118                                 lock (this) {
119                                         if (keyToNode == null)
120                                                 keyToNode = new Hashtable ();
121                                 }
122                                 return keyToNode;
123                         }
124                 }
125                 
126                 protected virtual void Clear ()
127                 {
128                         lock (this) {
129                                 if (urlToNode != null)
130                                         urlToNode.Clear ();
131                                 if (nodeToChildren != null)
132                                         nodeToChildren.Clear ();
133                                 if (nodeToParent != null)
134                                         nodeToParent.Clear ();
135                                 if (keyToNode != null)
136                                         keyToNode.Clear ();
137                         }
138                 }
139
140                 public override SiteMapNode FindSiteMapNode (string rawUrl)
141                 {
142                         if (rawUrl == null)
143                                 throw new ArgumentNullException ("rawUrl");
144                         
145                         if (rawUrl.Length > 0) {
146                                 this.BuildSiteMap();
147                                 rawUrl = UrlUtils.ResolveVirtualPathFromAppAbsolute (rawUrl);
148                                 SiteMapNode node = (SiteMapNode) UrlToNode [rawUrl];
149                                 if (node != null && IsAccessibleToUser (HttpContext.Current, node))
150                                         return node;
151                         }
152                         return null;
153                 }
154
155                 public override SiteMapNodeCollection GetChildNodes (SiteMapNode node)
156                 {
157                         if (node == null)
158                                 throw new ArgumentNullException ("node");
159                         
160                         this.BuildSiteMap();
161                         SiteMapNodeCollection col = (SiteMapNodeCollection) NodeToChildren [node];
162                         if (col == null) return SiteMapNodeCollection.EmptyCollection;
163                         
164                         SiteMapNodeCollection ret = null;
165                         for (int n=0; n<col.Count; n++) {
166                                 if (!IsAccessibleToUser (HttpContext.Current, col[n])) {
167                                         if (ret == null) {
168                                                 ret = new SiteMapNodeCollection ();
169                                                 for (int m=0; m<n; m++)
170                                                         ret.Add (col[m]);
171                                         }
172                                 } else if (ret != null)
173                                         ret.Add (col[n]);
174                         }
175                         
176                         if (ret != null) {
177                                 if (ret.Count > 0)
178                                         return SiteMapNodeCollection.ReadOnly (ret);
179                         } else
180                                 return SiteMapNodeCollection.ReadOnly (col);
181                         
182                         return null;
183                 }
184                 
185                 public override SiteMapNode GetParentNode (SiteMapNode node)
186                 {
187                         if (node == null)
188                                 throw new ArgumentNullException ("node");
189                         this.BuildSiteMap();
190                         SiteMapNode parent = (SiteMapNode) NodeToParent [node];
191                         return parent != null && IsAccessibleToUser (HttpContext.Current, parent) ? parent : null;
192                 }
193                 
194                 public override void RemoveNode (SiteMapNode node)
195                 {
196                         if (node == null)
197                                 throw new ArgumentNullException("node");
198                         
199                         lock (this) {
200                                 SiteMapNode parent = (SiteMapNode) NodeToParent [node];
201                                 if (NodeToParent.Contains (node))
202                                         NodeToParent.Remove (node);
203                                 
204                                 if (node.Url != null && node.Url.Length > 0 && UrlToNode.Contains (node.Url))
205                                         UrlToNode.Remove (node.Url);
206                                 
207                                 if (parent != null) {
208                                         SiteMapNodeCollection siblings = (SiteMapNodeCollection) NodeToChildren [node];
209                                         if (siblings != null && siblings.Contains (node))
210                                                 siblings.Remove (node);
211                                 }
212                         }
213                 }
214                 
215                 public override SiteMapNode FindSiteMapNodeFromKey (string key)
216                 {
217                         if (key == null)
218                                 throw new ArgumentNullException ("key");
219                         
220                         SiteMapNode ret = (SiteMapNode) KeyToNode [key];
221                         return ret != null && IsAccessibleToUser (HttpContext.Current, ret) ? ret : null;
222                 }
223
224                 public abstract SiteMapNode BuildSiteMap ();
225         }
226 }
227 #endif
228