1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.rendering.engine;
35
36 import info.magnolia.cms.core.AggregationState;
37 import info.magnolia.context.MgnlContext;
38 import info.magnolia.registry.RegistrationException;
39 import info.magnolia.rendering.context.RenderingContext;
40 import info.magnolia.rendering.renderer.Renderer;
41 import info.magnolia.rendering.renderer.registry.RendererRegistry;
42 import info.magnolia.rendering.template.RenderableDefinition;
43 import info.magnolia.rendering.template.assignment.TemplateDefinitionAssignment;
44 import info.magnolia.rendering.template.variation.RenderableVariationResolver;
45
46 import java.util.Collections;
47 import java.util.Map;
48
49 import javax.inject.Provider;
50 import javax.jcr.Node;
51
52
53
54
55
56
57 public class DefaultRenderingEngine implements RenderingEngine {
58
59 protected static final Map<String, Object> EMPTY_CONTEXT = Collections.emptyMap();
60
61 private RendererRegistry rendererRegistry;
62 private TemplateDefinitionAssignment templateDefinitionAssignment;
63 private Provider<RenderingContext> renderingContextProvider;
64 private RenderableVariationResolver variationResolver;
65
66
67
68
69 protected DefaultRenderingEngine() {
70 }
71
72 public DefaultRenderingEngine(RendererRegistry rendererRegistry, TemplateDefinitionAssignment templateDefinitionAssignment, RenderableVariationResolver variationResolver, Provider<RenderingContext> renderingContextProvider) {
73 this.rendererRegistry = rendererRegistry;
74 this.templateDefinitionAssignment = templateDefinitionAssignment;
75 this.variationResolver = variationResolver;
76 this.renderingContextProvider = renderingContextProvider;
77 }
78
79 @Override
80 public void render(Node content, OutputProvider out) throws RenderException {
81 render(content, EMPTY_CONTEXT, out);
82 }
83
84 @Override
85 public void render(Node content, Map<String, Object> contextObjects, OutputProvider out) throws RenderException {
86 render(content, getRenderableDefinitionFor(content), contextObjects, out);
87 }
88
89 @Override
90 public void render(Node content, RenderableDefinition definition, Map<String, Object> contextObjects, OutputProvider out) throws RenderException {
91
92 final Renderer renderer = getRendererFor(definition);
93 final RenderingContext renderingContext = getRenderingContext();
94
95 RenderableDefinition variation = variationResolver.resolveVariation(definition);
96
97 AggregationState aggregationState = MgnlContext.getAggregationState();
98
99 String previousTemplateVariation = aggregationState.getRenderableVariation();
100 renderingContext.push(content, variation != null ? variation : definition, out);
101 try {
102 aggregationState.setRenderableVariation(variation != null ? variation.getName() : null);
103 renderer.render(renderingContext, contextObjects);
104 } finally {
105 renderingContext.pop();
106 aggregationState.setRenderableVariation(previousTemplateVariation);
107 }
108 }
109
110 protected RenderableDefinition getRenderableDefinitionFor(Node content) throws RenderException {
111 try {
112 return templateDefinitionAssignment.getAssignedTemplateDefinition(content);
113 } catch (RegistrationException e) {
114 throw new RenderException("Can't resolve RenderableDefinition for node [" + content + "]", e);
115 }
116 }
117
118 protected Renderer getRendererFor(RenderableDefinition definition) throws RenderException {
119 final String renderType = definition.getRenderType();
120 if (renderType == null) {
121 throw new RenderException("No renderType defined for definition [" + definition + "]");
122 }
123 try {
124 return rendererRegistry.get(renderType);
125 } catch (RegistrationException e) {
126 throw new RenderException("Can't find renderer [" + renderType + "]", e);
127 }
128 }
129
130 @Override
131 public RenderingContext getRenderingContext() {
132 return renderingContextProvider.get();
133 }
134
135 }