* PageThemeCompiler.cs: let property builders through, stop the
[mono.git] / mcs / class / System.Web / System.Web.Compilation / PageCompiler.cs
1 //
2 // System.Web.Compilation.PageCompiler
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2002,2003 Ximian, Inc (http://www.ximian.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 using System;
31 using System.CodeDom;
32 using System.IO;
33 using System.Reflection;
34 using System.Text;
35 using System.Web.Configuration;
36 using System.Web.UI;
37 using System.Web.SessionState;
38 using System.Web.Util;
39 #if NET_2_0
40 using System.Web.Profile;
41 #endif
42
43 namespace System.Web.Compilation
44 {
45         class PageCompiler : TemplateControlCompiler
46         {
47                 PageParser pageParser;
48                 static CodeTypeReference intRef = new CodeTypeReference (typeof (int));
49
50                 public PageCompiler (PageParser pageParser)
51                         : base (pageParser)
52                 {
53                         this.pageParser = pageParser;
54                 }
55
56                 protected override void CreateConstructor (CodeStatementCollection localVars,
57                                                            CodeStatementCollection trueStmt)
58                 {
59                         if (pageParser.ClientTarget != null) {
60                                 CodeExpression prop;
61                                 prop = new CodePropertyReferenceExpression (thisRef, "ClientTarget");
62                                 CodeExpression ct = new CodePrimitiveExpression (pageParser.ClientTarget);
63                                 if (localVars == null)
64                                         localVars = new CodeStatementCollection ();
65                                 localVars.Add (new CodeAssignStatement (prop, ct));
66                         }
67
68                         base.CreateConstructor (localVars, trueStmt);
69                 }
70                 
71                 protected override void AddInterfaces () 
72                 {
73                         base.AddInterfaces ();
74                         CodeTypeReference cref;
75                         
76                         if (pageParser.EnableSessionState) {
77                                 cref = new CodeTypeReference (typeof(IRequiresSessionState));
78 #if NET_2_0
79                                 cref.Options |= CodeTypeReferenceOptions.GlobalReference;
80                                 if (partialClass != null)
81                                         partialClass.BaseTypes.Add (cref);
82                                 else
83 #endif
84                                         mainClass.BaseTypes.Add (cref);
85                         }
86                         
87                         if (pageParser.ReadOnlySessionState) {
88                                 cref = new CodeTypeReference (typeof (IReadOnlySessionState));
89 #if NET_2_0
90                                 cref.Options |= CodeTypeReferenceOptions.GlobalReference;
91                                 if (partialClass != null)
92                                         partialClass.BaseTypes.Add (cref);                                      
93                                 else
94 #endif
95                                         mainClass.BaseTypes.Add (cref);
96                         }
97                 }
98
99                 void CreateGetTypeHashCode () 
100                 {
101                         CodeMemberMethod method = new CodeMemberMethod ();
102                         method.ReturnType = intRef;
103                         method.Name = "GetTypeHashCode";
104                         method.Attributes = MemberAttributes.Public | MemberAttributes.Override;
105                         Random rnd = new Random (pageParser.InputFile.GetHashCode ());
106                         method.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (rnd.Next ())));
107                         mainClass.Members.Add (method);
108                 }
109
110                 static CodeAssignStatement CreatePropertyAssign (CodeExpression expr, string name, object value)
111                 {
112                         CodePropertyReferenceExpression prop;
113                         prop = new CodePropertyReferenceExpression (expr, name);
114                         CodePrimitiveExpression prim;
115                         prim = new CodePrimitiveExpression (value);
116                         return new CodeAssignStatement (prop, prim);
117                 }
118
119                 static CodeAssignStatement CreatePropertyAssign (string name, object value)
120                 {
121                         return CreatePropertyAssign (thisRef, name, value);
122                 }
123
124                 protected override void AddStatementsToInitMethod (CodeMemberMethod method)
125                 {
126 #if NET_2_0
127                         CodeMethodInvokeExpression expr = new CodeMethodInvokeExpression (thisRef, "InitializeCulture");
128                         method.Statements.Add (new CodeExpressionStatement (expr));
129
130                         CodeArgumentReferenceExpression ctrlVar = new CodeArgumentReferenceExpression("__ctrl");
131                         if (pageParser.Title != null)
132                                 method.Statements.Add (CreatePropertyAssign (ctrlVar, "Title", pageParser.Title));
133
134                         if (pageParser.MasterPageFile != null)
135                                 method.Statements.Add (CreatePropertyAssign (ctrlVar, "MasterPageFile", pageParser.MasterPageFile));
136
137                         if (pageParser.Theme != null)
138                                 method.Statements.Add (CreatePropertyAssign (ctrlVar, "Theme", pageParser.Theme));
139
140                         if (pageParser.StyleSheetTheme != null)
141                                 method.Statements.Add (CreatePropertyAssign (ctrlVar, "StyleSheetTheme", pageParser.StyleSheetTheme));
142 #endif
143                 }
144
145                 protected override void PrependStatementsToFrameworkInitialize (CodeMemberMethod method)
146                 {
147                         base.PrependStatementsToFrameworkInitialize (method);
148 #if NET_2_0
149                         if (pageParser.StyleSheetTheme != null)
150                                 method.Statements.Add (CreatePropertyAssign ("StyleSheetTheme", pageParser.StyleSheetTheme));
151 #endif
152                 }
153
154                 protected override void AppendStatementsToFrameworkInitialize (CodeMemberMethod method)
155                 {
156                         string responseEncoding = pageParser.ResponseEncoding;
157                         if (responseEncoding != null)
158                                 method.Statements.Add (CreatePropertyAssign ("ResponseEncoding", responseEncoding));
159                         
160                         int codepage = pageParser.CodePage;
161                         if (codepage != -1)
162                                 method.Statements.Add (CreatePropertyAssign ("CodePage", codepage));
163
164                         string contentType = pageParser.ContentType;
165                         if (contentType != null)
166                                 method.Statements.Add (CreatePropertyAssign ("ContentType", contentType));
167
168                         if (pageParser.OutputCache) {
169                                 CodeMethodReferenceExpression init = new CodeMethodReferenceExpression (null,
170                                                 "InitOutputCache");
171                                 CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression (init,
172                                                 OutputCacheParams ());
173                                 method.Statements.Add (invoke);
174                         }
175                         
176                         int lcid = pageParser.LCID;
177                         if (lcid != -1)
178                                 method.Statements.Add (CreatePropertyAssign ("LCID", lcid));
179
180                         string culture = pageParser.Culture;
181                         if (culture != null)
182                                 method.Statements.Add (CreatePropertyAssign ("Culture", culture));
183
184                         culture = pageParser.UICulture;
185                         if (culture != null)
186                                 method.Statements.Add (CreatePropertyAssign ("UICulture", culture));
187
188                         string errorPage = pageParser.ErrorPage;
189                         if (errorPage != null)
190                                 method.Statements.Add (CreatePropertyAssign ("ErrorPage", errorPage));
191
192                         if (pageParser.HaveTrace) {
193                                 CodeAssignStatement stmt = new CodeAssignStatement ();
194                                 stmt.Left = new CodePropertyReferenceExpression (thisRef, "TraceEnabled");
195                                 stmt.Right = new CodePrimitiveExpression (pageParser.Trace);
196                                 method.Statements.Add (stmt);
197                         }
198
199                         if (pageParser.TraceMode != TraceMode.Default) {
200                                 CodeAssignStatement stmt = new CodeAssignStatement ();
201                                 CodeTypeReferenceExpression tm = new CodeTypeReferenceExpression ("System.Web.TraceMode");
202                                 stmt.Left = new CodePropertyReferenceExpression (thisRef, "TraceModeValue");
203                                 stmt.Right = new CodeFieldReferenceExpression (tm, pageParser.TraceMode.ToString ());
204                                 method.Statements.Add (stmt);
205                         }
206
207                         if (pageParser.NotBuffer) {
208                                 CodeAssignStatement stmt = new CodeAssignStatement ();
209                                 stmt.Left = new CodePropertyReferenceExpression (thisRef, "Buffer");
210                                 stmt.Right = new CodePrimitiveExpression (false);
211                                 method.Statements.Add (stmt);
212                         }
213
214 #if NET_1_1
215                         if (pageParser.ValidateRequest) {
216                                 CodeMethodInvokeExpression expr = new CodeMethodInvokeExpression ();
217                                 CodePropertyReferenceExpression prop;
218                                 prop = new CodePropertyReferenceExpression (thisRef, "Request");
219                                 expr.Method = new CodeMethodReferenceExpression (prop, "ValidateInput");
220                                 method.Statements.Add (expr);
221                         }
222 #endif
223 #if NET_2_0
224                         if (!pageParser.EnableEventValidation) {
225                                 CodeAssignStatement stmt = new CodeAssignStatement ();
226                                 CodePropertyReferenceExpression prop;
227                                 prop = new CodePropertyReferenceExpression (thisRef, "EnableEventValidation");
228                                 stmt.Left = prop;
229                                 stmt.Right = new CodePrimitiveExpression (pageParser.EnableEventValidation);
230                                 method.Statements.Add (stmt);
231                         }
232
233                         if (pageParser.MaintainScrollPositionOnPostBack) {
234                                 CodeAssignStatement stmt = new CodeAssignStatement ();
235                                 CodePropertyReferenceExpression prop;
236                                 prop = new CodePropertyReferenceExpression (thisRef, "MaintainScrollPositionOnPostBack");
237                                 stmt.Left = prop;
238                                 stmt.Right = new CodePrimitiveExpression (pageParser.MaintainScrollPositionOnPostBack);
239                                 method.Statements.Add (stmt);
240                         }
241 #endif
242                         
243                         base.AppendStatementsToFrameworkInitialize (method);
244                 }
245
246                 private CodeExpression[] OutputCacheParams ()
247                 {
248                         return new CodeExpression [] {
249                                 new CodePrimitiveExpression (pageParser.OutputCacheDuration),
250                                 new CodePrimitiveExpression (pageParser.OutputCacheVaryByHeader),
251                                 new CodePrimitiveExpression (pageParser.OutputCacheVaryByCustom),
252                                 new CodeSnippetExpression (typeof (OutputCacheLocation).ToString () +
253                                                 "." + pageParser.OutputCacheLocation.ToString ()),
254                                 new CodePrimitiveExpression (pageParser.OutputCacheVaryByParam)
255                                 };
256                 }
257                 
258                 protected internal override void CreateMethods ()
259                 {
260                         base.CreateMethods ();
261
262 #if NET_2_0
263                         CreateProfileProperty ();
264                         if (pageParser.MasterType != null) {
265                                 CodeMemberProperty mprop = new CodeMemberProperty ();
266                                 mprop.Name = "Master";
267                                 mprop.Type = new CodeTypeReference (pageParser.MasterType);
268                                 mprop.Attributes = MemberAttributes.Public | MemberAttributes.New;
269                                 CodeExpression prop = new CodePropertyReferenceExpression (new CodeBaseReferenceExpression (), "Master");
270                                 prop = new CodeCastExpression (pageParser.MasterType, prop);
271                                 mprop.GetStatements.Add (new CodeMethodReturnStatement (prop));
272                                 mainClass.Members.Add (mprop);
273                         }
274 #endif
275                         
276                         CreateGetTypeHashCode ();
277                 }
278
279                 public static Type CompilePageType (PageParser pageParser)
280                 {
281                         PageCompiler compiler = new PageCompiler (pageParser);
282                         return compiler.GetCompiledType ();
283                 }
284         }
285 }
286
287