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.context;
35
36 import info.magnolia.cms.core.AggregationState;
37 import info.magnolia.cms.core.Content;
38 import info.magnolia.cms.util.ContentUtil;
39 import info.magnolia.objectfactory.annotation.RequestScoped;
40 import info.magnolia.rendering.engine.OutputProvider;
41 import info.magnolia.rendering.engine.RenderException;
42 import info.magnolia.rendering.engine.RenderExceptionHandler;
43 import info.magnolia.rendering.template.RenderableDefinition;
44 import info.magnolia.rendering.util.AppendableWriter;
45
46 import java.io.IOException;
47 import java.io.OutputStream;
48 import java.io.Writer;
49 import java.util.EmptyStackException;
50 import java.util.Stack;
51
52 import javax.inject.Inject;
53 import javax.inject.Provider;
54 import javax.jcr.Node;
55
56
57
58
59
60
61 @RequestScoped
62 public class AggregationStateBasedRenderingContext implements RenderingContext {
63
64
65
66
67 private static class StackState {
68
69 RenderableDefinition renderableDefinition;
70 OutputProvider outputProvider;
71 Content legacyContent;
72
73 private StackState(RenderableDefinition renderableDefinition, OutputProvider outputProvider, Content legacyContent) {
74 this.renderableDefinition = renderableDefinition;
75 this.outputProvider = outputProvider;
76 this.legacyContent = legacyContent;
77 }
78 }
79
80 private final AggregationState aggregationState;
81 private final Stack<StackState> stack = new Stack<StackState>();
82 private RenderableDefinition currentRenderableDefinition;
83 private OutputProvider currentOutputProvider;
84 private RenderExceptionHandler exceptionHandler;
85
86
87
88
89
90
91 private int depth = 0;
92
93 @Inject
94 public AggregationStateBasedRenderingContext(Provider<AggregationState> aggregationStateProvider, RenderExceptionHandler exceptionHandler) {
95 this(aggregationStateProvider.get(), exceptionHandler);
96 }
97
98 public AggregationStateBasedRenderingContext(AggregationState aggregationState, RenderExceptionHandler exceptionHandler) {
99 this.aggregationState = aggregationState;
100 this.exceptionHandler = exceptionHandler;
101 }
102
103 @Override
104 public Node getMainContent() {
105
106 Content mainContent = aggregationState.getMainContent();
107 return mainContent != null ? mainContent.getJCRNode() : null;
108 }
109
110 @Override
111 public Node getCurrentContent() {
112 Content currentContent = aggregationState.getCurrentContent();
113 return currentContent != null ? currentContent.getJCRNode() : null;
114 }
115
116 @Override
117 public RenderableDefinition getRenderableDefinition() {
118 return currentRenderableDefinition;
119 }
120
121 @Override
122 public void push(Node content, RenderableDefinition renderableDefinition) {
123 push(content, renderableDefinition, null);
124 }
125
126 @Override
127 public void push(Node content, RenderableDefinition renderableDefinition, OutputProvider outputProvider) {
128
129
130
131 Content legacyContent = ContentUtil.asContent(content);
132
133 if (aggregationState.getMainContent() == null) {
134 aggregationState.setMainContent(legacyContent);
135 }
136
137 if (depth > 0) {
138 stack.push(new StackState(currentRenderableDefinition, currentOutputProvider, aggregationState.getCurrentContent()));
139 }
140 aggregationState.setCurrentContent(legacyContent);
141 currentRenderableDefinition = renderableDefinition;
142 currentOutputProvider = outputProvider != null ? outputProvider : currentOutputProvider;
143 depth++;
144 }
145
146 @Override
147 public void pop() {
148 if (depth == 0) {
149 throw new EmptyStackException();
150 } else if (depth == 1) {
151 aggregationState.setCurrentContent(null);
152 currentRenderableDefinition = null;
153 currentOutputProvider = null;
154 } else {
155 StackState state = stack.pop();
156 aggregationState.setCurrentContent(state.legacyContent);
157 currentRenderableDefinition = state.renderableDefinition;
158 currentOutputProvider = state.outputProvider;
159 }
160 depth--;
161
162 }
163
164 @Override
165 public OutputProvider getOutputProvider() {
166 return currentOutputProvider;
167 }
168
169 @Override
170 public AppendableWriter getAppendable() throws RenderException, IOException {
171 return new AppendableWriter(this.currentOutputProvider.getAppendable());
172 }
173
174 @Override
175 public OutputStream getOutputStream() throws RenderException, IOException {
176 return this.currentOutputProvider.getOutputStream();
177 }
178
179 @Override
180 public void handleException(RenderException renderException, Writer out) {
181 exceptionHandler.handleException(renderException, out);
182 }
183 }