001
014
015 package com.liferay.portal.layoutconfiguration.util;
016
017 import com.liferay.portal.kernel.executor.CopyThreadLocalCallable;
018 import com.liferay.portal.kernel.model.Portlet;
019 import com.liferay.portal.kernel.portlet.PortletContainerException;
020 import com.liferay.portal.kernel.portlet.PortletContainerUtil;
021 import com.liferay.portal.kernel.portlet.RestrictPortletServletRequest;
022 import com.liferay.portal.kernel.servlet.BufferCacheServletResponse;
023 import com.liferay.portal.kernel.util.Mergeable;
024 import com.liferay.portal.kernel.util.StringBundler;
025 import com.liferay.portal.kernel.util.WebKeys;
026
027 import java.io.IOException;
028
029 import java.util.Enumeration;
030 import java.util.concurrent.Callable;
031
032 import javax.servlet.http.HttpServletRequest;
033 import javax.servlet.http.HttpServletResponse;
034
035
038 public class PortletRenderer {
039
040 public PortletRenderer(
041 Portlet portlet, String columnId, Integer columnCount,
042 Integer columnPos) {
043
044 _portlet = portlet;
045 _columnId = columnId;
046 _columnCount = columnCount;
047 _columnPos = columnPos;
048 }
049
050 public void finishParallelRender() {
051 if (_restrictPortletServletRequest != null) {
052 _restrictPortletServletRequest.mergeSharedAttributes();
053 }
054 }
055
056 public Callable<StringBundler> getCallable(
057 HttpServletRequest request, HttpServletResponse response) {
058
059 return new PortletRendererCallable(request, response);
060 }
061
062 public Portlet getPortlet() {
063 return _portlet;
064 }
065
066 public StringBundler render(
067 HttpServletRequest request, HttpServletResponse response)
068 throws PortletContainerException {
069
070 request = PortletContainerUtil.setupOptionalRenderParameters(
071 request, null, _columnId, _columnPos, _columnCount);
072
073 return _render(request, response);
074 }
075
076 public StringBundler renderAjax(
077 HttpServletRequest request, HttpServletResponse response)
078 throws PortletContainerException {
079
080 request = PortletContainerUtil.setupOptionalRenderParameters(
081 request, _RENDER_PATH, _columnId, _columnPos, _columnCount);
082
083 _restrictPortletServletRequest = (RestrictPortletServletRequest)request;
084
085 return _render(request, response);
086 }
087
088 public StringBundler renderError(
089 HttpServletRequest request, HttpServletResponse response)
090 throws PortletContainerException {
091
092 request = PortletContainerUtil.setupOptionalRenderParameters(
093 request, null, _columnId, _columnPos, _columnCount);
094
095 request.setAttribute(
096 WebKeys.PARALLEL_RENDERING_TIMEOUT_ERROR, Boolean.TRUE);
097
098 _restrictPortletServletRequest = (RestrictPortletServletRequest)request;
099
100 try {
101 return _render(request, response);
102 }
103 finally {
104 request.removeAttribute(WebKeys.PARALLEL_RENDERING_TIMEOUT_ERROR);
105 }
106 }
107
108 private StringBundler _render(
109 HttpServletRequest request, HttpServletResponse response)
110 throws PortletContainerException {
111
112 BufferCacheServletResponse bufferCacheServletResponse =
113 new BufferCacheServletResponse(response);
114
115 Object lock = request.getAttribute(
116 WebKeys.PARALLEL_RENDERING_MERGE_LOCK);
117
118 request.setAttribute(WebKeys.PARALLEL_RENDERING_MERGE_LOCK, null);
119
120 Object portletParallelRender = request.getAttribute(
121 WebKeys.PORTLET_PARALLEL_RENDER);
122
123 request.setAttribute(WebKeys.PORTLET_PARALLEL_RENDER, Boolean.FALSE);
124
125 try {
126 PortletContainerUtil.render(
127 request, bufferCacheServletResponse, _portlet);
128
129 return bufferCacheServletResponse.getStringBundler();
130 }
131 catch (IOException ioe) {
132 throw new PortletContainerException(ioe);
133 }
134 finally {
135 request.setAttribute(WebKeys.PARALLEL_RENDERING_MERGE_LOCK, lock);
136 request.setAttribute(
137 WebKeys.PORTLET_PARALLEL_RENDER, portletParallelRender);
138 }
139 }
140
141 private static final String _RENDER_PATH =
142 "/html/portal/load_render_portlet.jsp";
143
144 private final Integer _columnCount;
145 private final String _columnId;
146 private final Integer _columnPos;
147 private final Portlet _portlet;
148 private RestrictPortletServletRequest _restrictPortletServletRequest;
149
150 private class PortletRendererCallable
151 extends CopyThreadLocalCallable<StringBundler> {
152
153 public PortletRendererCallable(
154 HttpServletRequest request, HttpServletResponse response) {
155
156 super(
157 ParallelRenderThreadLocalBinderUtil.getThreadLocalBinder(),
158 false, true);
159
160 _request = request;
161 _response = response;
162 }
163
164 @Override
165 public StringBundler doCall() throws Exception {
166 HttpServletRequest request =
167 PortletContainerUtil.setupOptionalRenderParameters(
168 _request, null, _columnId, _columnPos, _columnCount);
169
170 _restrictPortletServletRequest =
171 (RestrictPortletServletRequest)request;
172
173 try {
174 _split(_request, _restrictPortletServletRequest);
175
176 return _render(request, _response);
177 }
178 catch (Exception e) {
179
180
181
182
183
184 Thread currentThread = Thread.currentThread();
185
186 if (!currentThread.isInterrupted()) {
187 throw e;
188 }
189
190 return null;
191 }
192 }
193
194 private void _split(
195 HttpServletRequest request,
196 RestrictPortletServletRequest restrictPortletServletRequest) {
197
198 Enumeration<String> attributeNames = request.getAttributeNames();
199
200 while (attributeNames.hasMoreElements()) {
201 String attributeName = attributeNames.nextElement();
202
203 Object attribute = request.getAttribute(attributeName);
204
205 if (!(attribute instanceof Mergeable<?>) ||
206 !RestrictPortletServletRequest.isSharedRequestAttribute(
207 attributeName)) {
208
209 continue;
210 }
211
212 Mergeable<?> mergeable = (Mergeable<?>)attribute;
213
214 restrictPortletServletRequest.setAttribute(
215 attributeName, mergeable.split());
216 }
217 }
218
219 private final HttpServletRequest _request;
220 private final HttpServletResponse _response;
221
222 }
223
224 }