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