1
// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.MonoRail
.Framework
.Routing
18 using System
.Collections
;
19 using System
.Collections
.Generic
;
20 using System
.Threading
;
26 public class RoutingRuleContainer
: IRoutingRuleContainer
28 private readonly List
<DecoratedRule
> rules
= new List
<DecoratedRule
>();
29 private readonly Dictionary
<string, IRoutingRule
> name2Rule
= new Dictionary
<string, IRoutingRule
>();
30 private readonly ReaderWriterLock locker
= new ReaderWriterLock();
33 /// Adds the specified rule.
35 /// <param name="rule">The rule.</param>
36 public void Add(IRoutingRule rule
)
39 rules
.Add(new DecoratedRule(rule
));
41 // For really fast access
42 if (rule
.RouteName
!= null)
44 if (name2Rule
.ContainsKey(rule
.RouteName
))
46 throw new InvalidOperationException("Attempt to register route with duplicated name: " + rule
.RouteName
);
49 name2Rule
[rule
.RouteName
] = rule
;
56 public void Add(IRoutingRule rule
, RouteAction action
)
59 rules
.Add(new DecoratedRule(rule
, action
));
65 /// <param name="routeName">Name of the route.</param>
66 /// <param name="hostname">The hostname.</param>
67 /// <param name="virtualPath">The virtual path.</param>
68 /// <param name="parameters">The parameters.</param>
69 /// <returns></returns>
70 public string CreateUrl(string routeName
, string hostname
, string virtualPath
, IDictionary parameters
)
76 if (!name2Rule
.TryGetValue(routeName
, out rule
))
78 throw new MonoRailException("Could not find named route: " + routeName
);
82 return rule
.CreateUrl(hostname
, virtualPath
, parameters
, out points
);
88 /// <param name="hostname">The hostname.</param>
89 /// <param name="virtualPath">The virtual path.</param>
90 /// <param name="parameters">The parameters.</param>
91 /// <returns></returns>
92 public string CreateUrl(string hostname
, string virtualPath
, IDictionary parameters
)
95 string winnerUrl
= null;
97 foreach(IRoutingRule rule
in rules
)
101 string url
= rule
.CreateUrl(hostname
, virtualPath
, parameters
, out points
);
103 if (url
!= null && points
> winnerPoints
)
106 winnerPoints
= points
;
116 /// <param name="hostname">The hostname.</param>
117 /// <param name="virtualPath">The virtual path.</param>
118 /// <param name="parameters">The parameters.</param>
119 /// <returns></returns>
120 public string CreateUrl(string hostname
, string virtualPath
, object parameters
)
122 return CreateUrl(hostname
, virtualPath
, new ReflectionBasedDictionaryAdapter(parameters
));
128 /// <param name="url">The URL.</param>
129 /// <param name="context">The context.</param>
130 /// <returns></returns>
131 public RouteMatch
FindMatch(string url
, IRouteContext context
)
135 int winnerPoints
= 0;
136 RouteMatch winner
= null;
137 DecoratedRule winnerule
= null;
139 foreach(DecoratedRule rule
in rules
)
141 RouteMatch match
= new RouteMatch();
143 int points
= rule
.Matches(url
, context
, match
);
145 if (points
!= 0 && points
> winnerPoints
)
147 winnerPoints
= points
;
153 if (winner
!= null && winnerule
.SelectionAction
!= null)
155 winnerule
.SelectionAction(context
, winner
);
162 /// Gets a value indicating whether this container is empty.
164 /// <value><c>true</c> if this instance is empty; otherwise, <c>false</c>.</value>
167 get { return rules.Count == 0; }
170 class DecoratedRule
: IRoutingRule
172 private readonly IRoutingRule inner
;
173 private RouteAction selectionAction
;
175 public DecoratedRule(IRoutingRule inner
)
180 public DecoratedRule(IRoutingRule inner
, RouteAction selectionAction
) : this(inner
)
182 this.selectionAction
= selectionAction
;
185 public string CreateUrl(string hostname
, string virtualPath
, IDictionary parameters
, out int points
)
187 return inner
.CreateUrl(hostname
, virtualPath
, parameters
, out points
);
190 public int Matches(string url
, IRouteContext context
, RouteMatch match
)
192 return inner
.Matches(url
, context
, match
);
195 public string RouteName
197 get { return inner.RouteName; }
200 public RouteAction SelectionAction
202 get { return selectionAction; }