Adding #if DOTNET35 for REST
[castle.git] / MonoRail / Castle.MonoRail.Views.Brail / Macros / ComponentMacro.cs
blobae4da7298bc608866a8b2ca82a253caf70271dba
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
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.Views.Brail
17 using System.Collections;
18 using Boo.Lang.Compiler;
19 using Boo.Lang.Compiler.Ast;
20 using Boo.Lang.Compiler.TypeSystem;
21 using Framework;
22 using Macros;
24 public class ComponentMacro : AbstractAstMacro
26 private string componentContextName;
27 private string componentFactoryName;
28 private string componentVariableName;
30 public override Statement Expand(MacroStatement macro)
32 componentContextName = ComponentNaming.GetComponentContextName(macro);
33 componentFactoryName = ComponentNaming.GetComponentFactoryName(macro);
34 componentVariableName = ComponentNaming.GetComponentNameFor(macro);
36 if (macro.Arguments.Count == 0) throw new MonoRailException("Component must be called with a name");
38 Block block = new Block();
40 Method method;
42 method = (Method) macro.GetAncestor(NodeType.Method);
44 StringLiteralExpression componentName = new StringLiteralExpression(macro.Arguments[0].ToString());
46 MethodInvocationExpression dictionary = CreateParametersDictionary(macro);
48 Expression macroBody = CodeBuilderHelper.CreateCallableFromMacroBody(CodeBuilder, macro);
50 MethodInvocationExpression initContext = new MethodInvocationExpression();
51 initContext.Target = AstUtil.CreateReferenceExpression("Castle.MonoRail.Views.Brail.BrailViewComponentContext");
52 initContext.Arguments.Extend(
53 new Expression[]
55 new SelfLiteralExpression(),
56 macroBody, componentName,
57 AstUtil.CreateReferenceExpression("OutputStream"),
58 dictionary
59 });
61 // compilerContext = BrailViewComponentContext(macroBodyClosure, "componentName", OutputStream, dictionary)
62 block.Add(new BinaryExpression(BinaryOperatorType.Assign,
63 new ReferenceExpression(componentContextName), initContext));
65 // AddViewComponentProperties( compilerContext.ComponentParams )
66 MethodInvocationExpression addProperties =
67 new MethodInvocationExpression(AstUtil.CreateReferenceExpression("AddViewComponentProperties"));
68 addProperties.Arguments.Add(AstUtil.CreateReferenceExpression(componentContextName + ".ComponentParameters"));
69 block.Add(addProperties);
71 InternalLocal viewComponentFactoryLocal = CodeBuilder.DeclareLocal(method, componentFactoryName,
72 TypeSystemServices.Map(
73 typeof(IViewComponentFactory)));
75 // viewComponentFactory = context.GetService(IViewComponentFactory)
76 MethodInvocationExpression callService = new MethodInvocationExpression(
77 AstUtil.CreateReferenceExpression("context.GetService"));
78 callService.Arguments.Add(CodeBuilder.CreateTypeofExpression(typeof(IViewComponentFactory)));
80 block.Add(new BinaryExpression(BinaryOperatorType.Assign,
81 CodeBuilder.CreateLocalReference(componentFactoryName, viewComponentFactoryLocal),
82 callService));
84 // component = viewComponentFactory.Create( componentName)
85 MethodInvocationExpression createComponent = new MethodInvocationExpression(
86 new MemberReferenceExpression(CodeBuilder.CreateLocalReference(componentFactoryName, viewComponentFactoryLocal),
87 "Create"));
88 createComponent.Arguments.Add(componentName);
89 block.Add(new BinaryExpression(BinaryOperatorType.Assign,
90 new ReferenceExpression(componentVariableName),
91 createComponent));
92 AddSections(block, macro);
94 // component.Init(context, componentContext)
95 MethodInvocationExpression initComponent = new MethodInvocationExpression(
96 AstUtil.CreateReferenceExpression(componentVariableName + ".Init"));
97 initComponent.Arguments.Extend(
98 new Expression[]
100 new ReferenceExpression("context"),
101 new ReferenceExpression(componentContextName)
104 block.Add(initComponent);
106 // component.Render()
107 block.Add(new MethodInvocationExpression(
108 AstUtil.CreateReferenceExpression(componentVariableName + ".Render")));
110 // if component.ViewToRender is not null:
111 // OutputSubView("/"+component.ViewToRender, context.CompnentParameters)
112 Block renderView = new Block();
113 MethodInvocationExpression outputSubView = new MethodInvocationExpression(
114 AstUtil.CreateReferenceExpression("OutputSubView"));
115 outputSubView.Arguments.Add(new BinaryExpression(BinaryOperatorType.Addition,
116 new StringLiteralExpression("/"),
117 AstUtil.CreateReferenceExpression(componentContextName +
118 ".ViewToRender")));
120 outputSubView.Arguments.Add(AstUtil.CreateReferenceExpression(componentContextName + ".ComponentParameters"));
121 renderView.Add(outputSubView);
123 block.Add(new IfStatement(AstUtil.CreateReferenceExpression(componentContextName + ".ViewToRender"),
124 renderView, new Block()));
126 // RemoveViewComponentProperties( compilerContext.ComponentParams )
127 MethodInvocationExpression removeProperties =
128 new MethodInvocationExpression(AstUtil.CreateReferenceExpression("RemoveViewComponentProperties"));
129 removeProperties.Arguments.Add(AstUtil.CreateReferenceExpression(componentContextName + ".ComponentParameters"));
130 block.Add(removeProperties);
132 return block;
135 private static void AddSections(Block block, Node macro)
137 IDictionary sections = (IDictionary) macro["sections"];
139 if (sections == null) return;
141 foreach(DictionaryEntry entry in sections)
143 block.Add((Block) entry.Value);
147 private static MethodInvocationExpression CreateParametersDictionary(MacroStatement macro)
149 // Make sure that hash table is an case insensitive one.
150 MethodInvocationExpression dictionary = new MethodInvocationExpression();
151 dictionary.Target = AstUtil.CreateReferenceExpression("System.Collections.Hashtable");
153 //If component has parameters, add them
154 if (macro.Arguments.Count == 2)
156 dictionary.Arguments.Add(macro.Arguments[1]);
159 dictionary.Arguments.Add(
160 AstUtil.CreateReferenceExpression("System.Collections.CaseInsensitiveHashCodeProvider.Default"));
161 dictionary.Arguments.Add(AstUtil.CreateReferenceExpression("System.Collections.CaseInsensitiveComparer.Default"));
162 return dictionary;