Refactored the Kernel registration fluent interface to be more readable, better suppo...
[castle.git] / MonoRail / Castle.MonoRail.Views.Brail / Macros / SectionMacro.cs
blobe65ea84586506bbb984a8595b4fa677abc2e1f63
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;
18 using System.Collections;
19 using Boo.Lang.Compiler;
20 using Boo.Lang.Compiler.Ast;
21 using Framework;
22 using Macros;
24 public class SectionMacro : AbstractAstMacro
26 private string componentContextName;
27 private string componentVariableName;
29 public override Statement Expand(MacroStatement macro)
31 if (macro.Arguments.Count == 0)
32 throw new MonoRailException("Section must be called with a name");
34 MacroStatement component = GetParentComponent(macro);
36 componentContextName = ComponentNaming.GetComponentContextName(component);
37 componentVariableName = ComponentNaming.GetComponentNameFor(component);
40 string sectionName = macro.Arguments[0].ToString();
41 Block block = new Block();
42 //if (!Component.SupportsSection(section.Name))
43 // throw new ViewComponentException( String.Format("The section '{0}' is not supported by the ViewComponent '{1}'", section.Name, ComponentName));
44 MethodInvocationExpression supportsSection = new MethodInvocationExpression(
45 AstUtil.CreateReferenceExpression(componentVariableName + ".SupportsSection"),
46 new StringLiteralExpression(sectionName));
47 //create the new exception
48 RaiseStatement raiseSectionNotSupportted = new RaiseStatement(
49 new MethodInvocationExpression(
50 AstUtil.CreateReferenceExpression(typeof(ViewComponentException).FullName),
51 new StringLiteralExpression(
52 String.Format("The section '{0}' is not supported by the ViewComponent '{1}'", sectionName,
53 component.Arguments[0].ToString())
55 ));
57 Block trueBlock = new Block();
58 trueBlock.Add(raiseSectionNotSupportted);
59 IfStatement ifSectionNotSupported =
60 new IfStatement(new UnaryExpression(UnaryOperatorType.LogicalNot, supportsSection),
61 trueBlock, null);
62 block.Add(ifSectionNotSupported);
63 //componentContext.RegisterSection(sectionName);
64 MethodInvocationExpression mie = new MethodInvocationExpression(
65 new MemberReferenceExpression(new ReferenceExpression(componentContextName), "RegisterSection"),
66 new StringLiteralExpression(sectionName),
67 CodeBuilderHelper.CreateCallableFromMacroBody(CodeBuilder, macro));
68 block.Add(mie);
70 IDictionary sections = (IDictionary) component["sections"];
71 if (sections == null)
73 component["sections"] = sections = new Hashtable();
75 sections.Add(sectionName, block);
76 return null;
79 private static MacroStatement GetParentComponent(Node macro)
81 Node parent = macro.ParentNode;
82 while(!(parent is MacroStatement))
84 parent = parent.ParentNode;
86 MacroStatement parentComponent = (MacroStatement) parent;
87 if (parentComponent == null ||
88 parentComponent.Name.ToLowerInvariant() != "component")
90 throw new MonoRailException("A section must be contained in a component");
92 return parentComponent;