2 // System.Web.UI.WebControls.SiteMapDataSource.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
7 // (C) 2004 Novell, Inc (http://www.novell.com)
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
33 using System.Collections;
36 using System.Web.Util;
37 using System.ComponentModel;
38 using System.Collections.Generic;
40 namespace System.Web.UI.WebControls
42 [PersistChildrenAttribute (false)]
43 [DesignerAttribute ("System.Web.UI.Design.WebControls.SiteMapDataSourceDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44 [ParseChildrenAttribute (true)]
46 public class SiteMapDataSource : HierarchicalDataSourceControl, IDataSource, IListSource
48 static string[] emptyNames = new string[] { "DefaultView" };
50 SiteMapProvider provider;
52 public virtual ICollection GetViewNames ()
57 IList IListSource.GetList () {
61 bool IListSource.ContainsListCollection {
62 get { return ContainsListCollection; }
65 public virtual IList GetList ()
67 return ListSourceHelper.GetList (this);
70 [BrowsableAttribute (false)]
71 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
72 public virtual bool ContainsListCollection {
73 get { return ListSourceHelper.ContainsListCollection (this); }
76 DataSourceView IDataSource.GetView (string viewName) {
77 return GetView (viewName);
80 ICollection IDataSource.GetViewNames () {
81 return GetViewNames ();
84 event EventHandler IDataSource.DataSourceChanged {
85 add { ((IHierarchicalDataSource)this).DataSourceChanged += value; }
86 remove { ((IHierarchicalDataSource)this).DataSourceChanged -= value; }
89 [BrowsableAttribute (false)]
90 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
91 public SiteMapProvider Provider {
93 if (provider == null) {
94 if (this.SiteMapProvider.Length == 0) {
95 provider = SiteMap.Provider;
97 throw new HttpException ("There is no default provider configured for the site.");
99 provider = SiteMap.Providers [this.SiteMapProvider];
100 if (provider == null)
101 throw new HttpException ("SiteMap provider '" + this.SiteMapProvider + "' not found.");
108 OnDataSourceChanged (EventArgs.Empty);
112 [DefaultValueAttribute ("")]
113 public virtual string SiteMapProvider {
114 get { return ViewState.GetString ("SiteMapProvider", ""); }
116 ViewState ["SiteMapProvider"] = value;
117 OnDataSourceChanged (EventArgs.Empty);
121 [DefaultValueAttribute ("")]
122 [EditorAttribute ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
123 [UrlPropertyAttribute]
124 public virtual string StartingNodeUrl {
125 get { return ViewState.GetString ("StartingNodeUrl", ""); }
127 ViewState ["StartingNodeUrl"] = value;
128 OnDataSourceChanged (EventArgs.Empty);
133 public virtual int StartingNodeOffset {
134 get { return ViewState.GetInt ("StartingNodeOffset", 0); }
136 ViewState ["StartingNodeOffset"] = value;
137 OnDataSourceChanged (EventArgs.Empty);
141 [DefaultValueAttribute (false)]
142 public virtual bool StartFromCurrentNode {
143 get { return ViewState.GetBool ("StartFromCurrentNode", false); }
145 ViewState ["StartFromCurrentNode"] = value;
146 OnDataSourceChanged (EventArgs.Empty);
150 [DefaultValueAttribute (true)]
151 public virtual bool ShowStartingNode {
152 get { return ViewState.GetBool ("ShowStartingNode", true); }
154 ViewState ["ShowStartingNode"] = value;
155 OnDataSourceChanged (EventArgs.Empty);
159 public virtual DataSourceView GetView (string viewName)
161 SiteMapNode node = GetStartNode (viewName);
163 return new SiteMapDataSourceView (this, viewName, SiteMapNodeCollection.EmptyList);
164 else if (ShowStartingNode)
165 return new SiteMapDataSourceView (this, viewName, node);
167 return new SiteMapDataSourceView (this, viewName, node.ChildNodes);
170 protected override HierarchicalDataSourceView GetHierarchicalView (string viewPath)
172 SiteMapNode node = GetStartNode (viewPath);
174 return new SiteMapHierarchicalDataSourceView (SiteMapNodeCollection.EmptyList);
175 else if (ShowStartingNode || node == null)
176 return new SiteMapHierarchicalDataSourceView (node);
178 return new SiteMapHierarchicalDataSourceView (node.ChildNodes);
181 [MonoTODO ("handle StartNodeOffsets > 0")]
182 SiteMapNode GetStartNode (string viewPath)
184 SiteMapNode starting_node;
186 if (viewPath != null && viewPath.Length != 0) {
187 string url = MapUrl (StartingNodeUrl);
188 return Provider.FindSiteMapNode (url);
189 } else if (StartFromCurrentNode) {
190 if (StartingNodeUrl.Length != 0)
191 throw new InvalidOperationException ("StartingNodeUrl can't be set if StartFromCurrentNode is set to true.");
192 starting_node = SiteMap.CurrentNode;
193 } else if (StartingNodeUrl.Length != 0) {
194 string url = MapUrl (StartingNodeUrl);
195 SiteMapNode node = Provider.FindSiteMapNode (url);
196 if (node == null) throw new ArgumentException ("Can't find a site map node for the url: " + StartingNodeUrl);
198 starting_node = node;
200 starting_node = Provider.RootNode;
202 if (starting_node == null)
206 if (StartingNodeOffset < 0) {
207 for (i = StartingNodeOffset; i < 0; i ++) {
208 if (starting_node.ParentNode == null)
210 starting_node = starting_node.ParentNode;
212 } else if (StartingNodeOffset > 0) {
213 List<SiteMapNode> pathCurrentToStartingNode = new List<SiteMapNode> ();
214 SiteMapNode tmpNode = Provider.CurrentNode;
215 while (tmpNode != null && tmpNode != starting_node) {
216 pathCurrentToStartingNode.Insert (0, tmpNode);
217 tmpNode = tmpNode.ParentNode;
219 if (tmpNode == starting_node &&
220 StartingNodeOffset <= pathCurrentToStartingNode.Count) {
221 // The requested node is in the same subtree as the starting_node
222 // try to advance on this path.
223 starting_node = pathCurrentToStartingNode [StartingNodeOffset - 1];
227 return starting_node;
230 string MapUrl (string url)
232 if (String.IsNullOrEmpty (url))
234 if (UrlUtils.IsRelativeUrl (url))
235 return UrlUtils.Combine (HttpRuntime.AppDomainAppVirtualPath, url);
237 return UrlUtils.ResolveVirtualPathFromAppAbsolute (url);