2010-06-05 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.Compilation / RouteValueExpressionBuilder.cs
1 //
2 // RouteValueExpressionBuilder.cs
3 //
4 // Authors:
5 //   Marek Habersack (mhabersack@novell.com)
6 //
7 // (C) 2010 Novell, Inc (http://novell.com)
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 using System;
32 using System.CodeDom;
33 using System.ComponentModel;
34 using System.Reflection;
35 using System.Web.UI;
36 using System.Web.Routing;
37
38 namespace System.Web.Compilation
39 {
40         [ExpressionEditor ("System.Web.UI.Design.RouteValueExpressionEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
41         [ExpressionPrefix ("Routes")]
42         public class RouteValueExpressionBuilder : ExpressionBuilder
43         {
44                 public override bool SupportsEvaluate { get { return true; } }
45                 
46                 public RouteValueExpressionBuilder ()
47                 {
48                 }
49
50                 // This method is used only from within pages that aren't compiled
51                 public override object EvaluateExpression (object target, BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
52                 {
53                         // Mono doesn't use this, so let's leave it like that for now
54                         throw new NotImplementedException ();
55                 }
56
57                 public override CodeExpression GetCodeExpression (BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
58                 {
59                         if (entry == null)
60                                 throw new NullReferenceException (".NET emulation (entry == null)");
61                         
62                         var ret = new CodeMethodInvokeExpression ();
63                         ret.Method = new CodeMethodReferenceExpression (new CodeTypeReferenceExpression (typeof (RouteValueExpressionBuilder)), "GetRouteValue");
64
65                         var thisref = new CodeThisReferenceExpression ();
66                         CodeExpressionCollection parameters = ret.Parameters;
67                         parameters.Add (new CodePropertyReferenceExpression (thisref, "Page"));
68                         parameters.Add (new CodePrimitiveExpression (entry.Expression));
69                         parameters.Add (new CodeTypeOfExpression (new CodeTypeReference (entry.DeclaringType)));
70                         parameters.Add (new CodePrimitiveExpression (entry.Name));
71                         
72                         return ret;
73                 }
74
75                 public static object GetRouteValue (Page page, string key, Type controlType, string propertyName)
76                 {
77                         RouteData rd = page != null ? page.RouteData : null;
78                         if (rd == null || String.IsNullOrEmpty (key))
79                                 return null;
80                         
81                         object value = rd.Values [key];
82                         if (value == null)
83                                 return null;
84
85                         if (controlType == null || String.IsNullOrEmpty (propertyName) || !(value is string))
86                                 return value;
87
88                         PropertyDescriptorCollection pcoll = TypeDescriptor.GetProperties (controlType);
89                         if (pcoll == null || pcoll.Count == 0)
90                                 return value;
91
92                         PropertyDescriptor pdesc = pcoll [propertyName];
93                         if (pdesc == null)
94                                 return value;
95
96                         TypeConverter cvt = pdesc.Converter;
97                         if (cvt == null || !cvt.CanConvertFrom (typeof (string)))
98                                 return value;
99
100                         return cvt.ConvertFrom (value);
101                 }
102         }
103 }