1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.aggregator.impl;
18
19 import java.io.IOException;
20 import java.util.ArrayList;
21 import java.util.Iterator;
22 import java.util.List;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.jetspeed.PortalReservedParameters;
27 import org.apache.jetspeed.aggregator.FailedToRenderFragmentException;
28 import org.apache.jetspeed.aggregator.PageAggregator;
29 import org.apache.jetspeed.aggregator.PortletContent;
30 import org.apache.jetspeed.aggregator.PortletRenderer;
31 import org.apache.jetspeed.aggregator.RenderingJob;
32 import org.apache.jetspeed.aggregator.CurrentWorkerContext;
33 import org.apache.jetspeed.container.state.NavigationalState;
34 import org.apache.jetspeed.exception.JetspeedException;
35 import org.apache.jetspeed.om.page.ContentFragment;
36 import org.apache.jetspeed.om.page.ContentPage;
37 import org.apache.jetspeed.request.RequestContext;
38 import org.apache.pluto.om.window.PortletWindow;
39
40 /***
41 * Asynchronous Page Aggregator builds the content required to render a
42 * page of portlets by rendering the portlets in parallel. Each portlet is
43 * rendered on its own thread. A work manager handles the thread pooling
44 * and synchronization of worker threads.
45 *
46 * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
47 * @author <a>Woonsan Ko</a>
48 * @version $Id: $
49 */
50 public class AsyncPageAggregatorImpl implements PageAggregator
51 {
52 protected final static Log log = LogFactory.getLog(AsyncPageAggregatorImpl.class);
53
54 protected PortletRenderer renderer;
55
56 protected List fallBackContentPathes;
57
58 public AsyncPageAggregatorImpl(PortletRenderer renderer)
59 {
60 this.renderer = renderer;
61 }
62
63 /***
64 * Builds the portlet set defined in the context into a portlet tree.
65 *
66 * @return Unique Portlet Entity ID
67 */
68 public void build( RequestContext context ) throws JetspeedException, IOException
69 {
70 ContentPage page = context.getPage();
71 if (null == page)
72 {
73 throw new JetspeedException("Failed to find PSML Pin ContentPageAggregator.build");
74 }
75 ContentFragment root = page.getRootContentFragment();
76 if (root == null)
77 {
78 throw new JetspeedException("No root ContentFragment found in ContentPage");
79 }
80
81 NavigationalState nav = context.getPortalURL().getNavigationalState();
82 PortletWindow window = nav.getMaximizedWindow();
83 if (null != window)
84 {
85 renderMaximizedWindow(context, page, root, window);
86 }
87 else
88 {
89 aggregateAndRender(root, context, page, true, null, null, null);
90 }
91
92 context.getResponse().getWriter().write(root.getRenderedContent());
93 if (null != window)
94 {
95 context.getRequest().removeAttribute(PortalReservedParameters.MAXIMIZED_FRAGMENT_ATTRIBUTE);
96 context.getRequest().removeAttribute(PortalReservedParameters.MAXIMIZED_LAYOUT_ATTRIBUTE);
97 }
98 }
99
100 /***
101 * <p>
102 * renderMaximizedWindow
103 * </p>
104 *
105 * @param context
106 * @param page
107 * @param layoutContentFragment
108 * @param defaultPortletDecorator
109 * @param dispatcher
110 * @param window
111 * @throws FailedToRenderContentFragmentException
112 */
113 protected void renderMaximizedWindow( RequestContext context, ContentPage page, ContentFragment layoutContentFragment,
114 PortletWindow window ) throws FailedToRenderFragmentException
115 {
116 ContentFragment maxedContentFragment = page.getContentFragmentById(window.getId().toString());
117 if (maxedContentFragment != null)
118 {
119 context.getRequest().setAttribute(PortalReservedParameters.MAXIMIZED_FRAGMENT_ATTRIBUTE, maxedContentFragment);
120 context.getRequest().setAttribute(PortalReservedParameters.FRAGMENT_ATTRIBUTE, maxedContentFragment);
121 context.getRequest().setAttribute(PortalReservedParameters.MAXIMIZED_LAYOUT_ATTRIBUTE, page.getRootContentFragment());
122 try
123 {
124 renderer.renderNow(maxedContentFragment, context);
125 renderer.renderNow(layoutContentFragment, context);
126 }
127 catch (Exception e)
128 {
129 log.error(e.getMessage(), e);
130 maxedContentFragment.overrideRenderedContent("Sorry, but we were unable access the requested portlet. Send the following message to your portal admin: "+ e.getMessage());
131 }
132 }
133 }
134
135 protected void aggregateAndRender(ContentFragment f, RequestContext context, ContentPage page, boolean isRoot,
136 List sequentialJobs, List parallelJobs, List layoutFragments)
137 throws FailedToRenderFragmentException
138 {
139
140
141
142 if (sequentialJobs == null)
143 {
144 sequentialJobs = new ArrayList();
145 }
146 if (parallelJobs == null)
147 {
148 parallelJobs = new ArrayList();
149 }
150 if (layoutFragments == null)
151 {
152 layoutFragments = new ArrayList();
153 }
154
155 if (f.getContentFragments() != null && f.getContentFragments().size() > 0)
156 {
157 Iterator children = f.getContentFragments().iterator();
158 while (children.hasNext())
159 {
160 ContentFragment child = (ContentFragment) children.next();
161 if (!"hidden".equals(f.getState()))
162 {
163 if (child.getType().equals(ContentFragment.PORTLET))
164 {
165
166 RenderingJob job = renderer.createRenderingJob(child, context);
167
168
169 if (job != null)
170 {
171 if (job.getTimeout() > 0)
172 parallelJobs.add(job);
173 else
174 sequentialJobs.add(job);
175 }
176 }
177 else
178 {
179
180
181 aggregateAndRender(child, context, page, false, sequentialJobs, parallelJobs, layoutFragments);
182 layoutFragments.add(child);
183 }
184 }
185 }
186 }
187
188
189 if (!isRoot)
190 return;
191
192 int parallelJobCount = parallelJobs.size();
193 int sequentialJobCount = sequentialJobs.size();
194
195 if (log.isInfoEnabled())
196 {
197 log.info("Aggregating " + page.getPath() + ". Parallel: " + parallelJobCount + ", Sequential: " + sequentialJobCount);
198 }
199
200 CurrentWorkerContext.setParallelRenderingMode(parallelJobCount > 0);
201
202
203 Iterator iter = parallelJobs.iterator();
204 while (iter.hasNext())
205 {
206 RenderingJob job = (RenderingJob) iter.next();
207 renderer.processRenderingJob(job);
208 }
209
210
211 iter = sequentialJobs.iterator();
212 while (iter.hasNext())
213 {
214 RenderingJob job = (RenderingJob) iter.next();
215 renderer.processRenderingJob(job);
216 }
217
218
219 renderer.waitForRenderingJobs(parallelJobs);
220
221
222 CurrentWorkerContext.setParallelRenderingMode(false);
223
224
225 iter = layoutFragments.iterator();
226 while (iter.hasNext())
227 {
228 ContentFragment child = (ContentFragment) iter.next();
229 renderer.renderNow(child, context);
230 }
231
232
233 String defaultPortletDecorator = page.getEffectiveDefaultDecorator(ContentFragment.PORTLET);
234 if (log.isDebugEnabled())
235 {
236 log.debug("Rendering portlet fragment: [[name, " + f.getName() + "], [id, " + f.getId() + "]]");
237 }
238
239 renderer.renderNow(f, context);
240 }
241
242
243 }