1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  /**
21   * The contents of this file are subject to the terms of the Common Development
22   * and Distribution License (the License). You may not use this file except in
23   * compliance with the License.
24   *
25   * You can obtain a copy of the License at http://www.sun.com/cddl/cddl.html and
26   * legal/CDDLv1.0.txt. See the License for the specific language governing
27   * permission and limitations under the License.
28   *
29   * When distributing Covered Code, include this CDDL Header Notice in each file
30   * and include the License file at legal/CDDLv1.0.txt.
31   *
32   * If applicable, add the following below the CDDL Header, with the fields
33   * enclosed by brackets [] replaced by your own identifying information:
34   * "Portions Copyrighted [year] [name of copyright owner]"
35   *
36   * Copyright 2008 Sun Microsystems Inc. All rights reserved.
37   */
38  
39  package com.liferay.portal.portletcontainer;
40  
41  import com.liferay.portal.SystemException;
42  import com.liferay.portal.ccpp.PortalProfileFactory;
43  import com.liferay.portal.kernel.portlet.LiferayWindowState;
44  import com.liferay.portal.kernel.servlet.ProtectedPrincipal;
45  import com.liferay.portal.kernel.util.GetterUtil;
46  import com.liferay.portal.kernel.util.JavaConstants;
47  import com.liferay.portal.kernel.util.LocaleUtil;
48  import com.liferay.portal.kernel.util.StringPool;
49  import com.liferay.portal.model.PortletConstants;
50  import com.liferay.portal.model.Role;
51  import com.liferay.portal.model.User;
52  import com.liferay.portal.service.RoleLocalServiceUtil;
53  import com.liferay.portal.theme.ThemeDisplay;
54  import com.liferay.portal.util.PortalUtil;
55  import com.liferay.portal.util.PropsValues;
56  import com.liferay.portal.util.WebKeys;
57  import com.liferay.portlet.ActionRequestImpl;
58  import com.liferay.portlet.ActionResponseImpl;
59  import com.liferay.portlet.InvokerPortletImpl;
60  import com.liferay.portlet.RenderRequestImpl;
61  import com.liferay.portlet.RenderResponseImpl;
62  import com.liferay.portlet.ResourceRequestImpl;
63  import com.liferay.portlet.ResourceResponseImpl;
64  import com.liferay.portlet.UserInfoFactory;
65  
66  import com.sun.portal.container.ChannelMode;
67  import com.sun.portal.container.ChannelState;
68  import com.sun.portal.container.ChannelURLType;
69  import com.sun.portal.container.Container;
70  import com.sun.portal.container.ContainerFactory;
71  import com.sun.portal.container.ContainerRequest;
72  import com.sun.portal.container.ContainerType;
73  import com.sun.portal.container.ExecuteActionRequest;
74  import com.sun.portal.container.ExecuteActionResponse;
75  import com.sun.portal.container.GetMarkupRequest;
76  import com.sun.portal.container.GetMarkupResponse;
77  import com.sun.portal.container.GetResourceRequest;
78  import com.sun.portal.container.GetResourceResponse;
79  import com.sun.portal.portletcontainer.appengine.PortletAppEngineUtils;
80  import com.sun.portal.portletcontainer.portlet.impl.PortletRequestConstants;
81  
82  import java.io.IOException;
83  import java.io.PrintWriter;
84  
85  import java.net.URL;
86  
87  import java.security.Principal;
88  
89  import java.util.ArrayList;
90  import java.util.Collections;
91  import java.util.List;
92  import java.util.Locale;
93  import java.util.Map;
94  
95  import javax.ccpp.Profile;
96  
97  import javax.portlet.ActionRequest;
98  import javax.portlet.ActionResponse;
99  import javax.portlet.EventRequest;
100 import javax.portlet.EventResponse;
101 import javax.portlet.Portlet;
102 import javax.portlet.PortletConfig;
103 import javax.portlet.PortletContext;
104 import javax.portlet.PortletException;
105 import javax.portlet.PortletRequest;
106 import javax.portlet.PortletResponse;
107 import javax.portlet.RenderRequest;
108 import javax.portlet.RenderResponse;
109 import javax.portlet.ResourceRequest;
110 import javax.portlet.ResourceResponse;
111 
112 import javax.servlet.http.HttpServletRequest;
113 import javax.servlet.http.HttpServletResponse;
114 
115 import org.apache.commons.logging.Log;
116 import org.apache.commons.logging.LogFactory;
117 
118 /**
119  * <a href="WindowInvoker.java.html"><b><i>View Source</i></b></a>
120  *
121  * @author Deepak Gothe
122  * @author Brian Wing Shun Chan
123  *
124  */
125 public class WindowInvoker extends InvokerPortletImpl {
126 
127     public void init(PortletConfig portletConfig) throws PortletException {
128         if (_remotePortlet){
129             _portletConfig = portletConfig;
130         }
131         else {
132             super.init(portletConfig);
133         }
134     }
135 
136     public void prepare(
137             com.liferay.portal.model.Portlet portletModel, Portlet portlet,
138             PortletContext portletContext)
139         throws PortletException {
140 
141         super.prepare(portletModel, portlet, portletContext);
142 
143         _portletModel = portletModel;
144         _container = _getContainer();
145     }
146 
147     public void prepare(
148             com.liferay.portal.model.Portlet portletModel, Portlet portlet,
149             PortletConfig portletConfig, PortletContext portletContext,
150             boolean facesPortlet, boolean strutsPortlet,
151             boolean strutsBridgePortlet)
152         throws PortletException {
153 
154         super.prepare(
155             portletModel, portlet, portletConfig, portletContext, facesPortlet,
156             strutsPortlet, strutsBridgePortlet);
157 
158         _portletModel = portletModel;
159         _container = _getContainer();
160     }
161 
162     protected void invokeAction(
163             ActionRequest actionRequest, ActionResponse actionResponse)
164         throws IOException, PortletException {
165 
166         if (!_isWARFile()) {
167             super.invokeAction(actionRequest, actionResponse);
168 
169             return;
170         }
171 
172         try {
173             ActionRequestImpl actionRequestImpl =
174                 (ActionRequestImpl)actionRequest;
175             ActionResponseImpl actionResponseImpl =
176                 (ActionResponseImpl)actionResponse;
177 
178             HttpServletRequest request =
179                 actionRequestImpl.getOriginalHttpServletRequest();
180             HttpServletResponse response =
181                 actionResponseImpl.getHttpServletResponse();
182 
183             _initUser(request, _portletModel);
184 
185             ExecuteActionRequest executeActionRequest =
186                 ContainerRequestFactory.createExecuteActionRequest(
187                     request, _portletModel, actionRequestImpl.getWindowState(),
188                     actionRequestImpl.getPortletMode(), _getPlid(actionRequest),
189                     isFacesPortlet(), _remotePortlet);
190 
191             _populateContainerRequest(
192                 request, response, executeActionRequest, actionRequest);
193 
194             ExecuteActionResponse executeActionResponse =
195                 ContainerResponseFactory.createExecuteActionResponse(response);
196 
197             ChannelURLType urlType =
198                 executeActionRequest.getWindowRequestReader().readURLType(
199                     request);
200 
201             _container.executeAction(
202                 executeActionRequest, executeActionResponse, urlType);
203 
204             URL redirectURL = executeActionResponse.getRedirectURL();
205 
206             if (redirectURL != null) {
207                 actionResponseImpl.setRedirectLocation(redirectURL.toString());
208             }
209 
210             ChannelState newWindowState =
211                 executeActionResponse.getNewWindowState();
212 
213             if (newWindowState != null) {
214                 actionResponseImpl.setWindowState(
215                     PortletAppEngineUtils.getWindowState(newWindowState));
216             }
217 
218             ChannelMode newPortletMode =
219                 executeActionResponse.getNewChannelMode();
220 
221             if (newPortletMode != null) {
222                 actionResponseImpl.setPortletMode(
223                     PortletAppEngineUtils.getPortletMode(newPortletMode));
224             }
225         }
226         catch (Exception e) {
227             throw new PortletException(e);
228         }
229         finally {
230             _setPortletAttributes(actionRequest, actionResponse);
231         }
232     }
233 
234     protected void invokeEvent(
235             EventRequest eventRequest, EventResponse eventResponse)
236         throws IOException, PortletException {
237 
238         if (!_isWARFile()) {
239             super.invokeEvent(eventRequest, eventResponse);
240         }
241     }
242 
243     protected String invokeRender(
244             RenderRequest renderRequest, RenderResponse renderResponse)
245         throws IOException, PortletException {
246 
247         if (!_isWARFile()) {
248             return super.invokeRender(renderRequest, renderResponse);
249         }
250 
251         try {
252             RenderRequestImpl renderRequestImpl =
253                 (RenderRequestImpl)renderRequest;
254             RenderResponseImpl renderResponseImpl =
255                 (RenderResponseImpl)renderResponse;
256 
257             HttpServletRequest request =
258                 renderRequestImpl.getOriginalHttpServletRequest();
259             HttpServletResponse response =
260                 renderResponseImpl.getHttpServletResponse();
261 
262             _initUser(request, _portletModel);
263 
264             GetMarkupRequest getMarkupRequest =
265                 ContainerRequestFactory.createGetMarkUpRequest(
266                     request, _portletModel, renderRequestImpl.getWindowState(),
267                     renderRequestImpl.getPortletMode(), _getPlid(renderRequest),
268                     isFacesPortlet(), _remotePortlet);
269 
270             _populateContainerRequest(
271                 request, response, getMarkupRequest, renderRequest);
272 
273             GetMarkupResponse getMarkupResponse =
274                 ContainerResponseFactory.createGetMarkUpResponse(response);
275 
276             List<String> allowableContentTypes =
277                 getMarkupRequest.getAllowableContentTypes();
278 
279             if (renderRequest.getWindowState().equals(
280                     LiferayWindowState.EXCLUSIVE)) {
281 
282                 allowableContentTypes.add("*/*");
283             }
284 
285             getMarkupRequest.setAllowableContentTypes(allowableContentTypes);
286 
287             _container.getMarkup(getMarkupRequest, getMarkupResponse);
288 
289             Map<String, List<String>> properties =
290                 getMarkupResponse.getStringProperties();
291 
292             if ((properties != null) &&
293                 (properties.containsKey("clear-request-parameters"))) {
294 
295                 getMarkupRequest.getRenderParameters().clear();
296             }
297 
298             StringBuffer sb = getMarkupResponse.getMarkup();
299 
300             PrintWriter pw = response.getWriter();
301 
302             pw.print(sb);
303 
304             return getMarkupResponse.getTitle();
305 
306         }
307         catch (Exception e) {
308             throw new PortletException(e);
309         }
310         finally {
311             _setPortletAttributes(renderRequest, renderResponse);
312         }
313     }
314 
315     protected void invokeResource(
316             ResourceRequest resourceRequest, ResourceResponse resourceResponse)
317         throws IOException, PortletException {
318 
319         if (!_isWARFile()) {
320             super.invokeResource(resourceRequest, resourceResponse);
321 
322             return;
323         }
324 
325         try {
326             ResourceRequestImpl resourceRequestImpl =
327                 (ResourceRequestImpl)resourceRequest;
328             ResourceResponseImpl resourceResponseImpl =
329                 (ResourceResponseImpl)resourceResponse;
330 
331             HttpServletRequest request =
332                 resourceRequestImpl.getOriginalHttpServletRequest();
333             HttpServletResponse response =
334                 resourceResponseImpl.getHttpServletResponse();
335 
336             _initUser(request, _portletModel);
337 
338             GetResourceRequest getResourceRequest =
339                 ContainerRequestFactory.createGetResourceRequest(
340                     request, _portletModel,
341                     resourceRequestImpl.getWindowState(),
342                     resourceRequestImpl.getPortletMode(),
343                     _getPlid(resourceRequest), isFacesPortlet(),
344                     _remotePortlet);
345 
346             _populateContainerRequest(
347                 request, response, getResourceRequest, resourceRequest);
348 
349             GetResourceResponse getResourceResponse =
350                 ContainerResponseFactory .createGetResourceResponse(response);
351 
352             _container.getResources(
353                 getResourceRequest, getResourceResponse);
354 
355             String contentType = getResourceResponse.getContentType();
356 
357             if (contentType != null) {
358                 resourceResponseImpl.setContentType(contentType);
359             }
360 
361             StringBuffer sb = getResourceResponse.getContentAsBuffer();
362 
363             byte[] bytes = getResourceResponse.getContentAsBytes();
364 
365             if (sb != null) {
366                 response.getWriter().print(sb);
367             }
368             else if ((bytes != null) && (bytes.length > 0)) {
369                 response.getOutputStream().write(bytes);
370             }
371             else {
372                 response.getWriter().print(StringPool.BLANK);
373             }
374 
375         }
376         catch (Exception e) {
377             throw new PortletException(e);
378         }
379         finally {
380             _setPortletAttributes(resourceRequest, resourceResponse);
381         }
382     }
383 
384     private Profile _getCCPPProfile(HttpServletRequest request) {
385         if (_profile == null) {
386             _profile = PortalProfileFactory.getCCPPProfile(request);
387         }
388 
389         return _profile;
390     }
391 
392     private Container _getContainer() {
393         if (_remotePortlet) {
394             return ContainerFactory.getContainer(ContainerType.WSRP_CONSUMER);
395         }
396         else {
397             return ContainerFactory.getContainer(
398                 ContainerType.PORTLET_CONTAINER);
399         }
400     }
401 
402     public Locale _getLocale(
403         HttpServletRequest request, PortletRequest portletRequest) {
404 
405         ThemeDisplay themeDisplay = _getThemeDisplay(portletRequest);
406 
407         Locale locale = themeDisplay.getLocale();
408 
409         if (locale == null) {
410             locale = request.getLocale();
411         }
412 
413         if (locale == null) {
414             locale = LocaleUtil.getDefault();
415         }
416 
417         return locale;
418     }
419 
420     private long _getPlid(PortletRequest portletRequest) {
421         ThemeDisplay themeDisplay = _getThemeDisplay(portletRequest);
422 
423         return themeDisplay.getPlid();
424     }
425 
426     private List<String> _getRoles(HttpServletRequest request) {
427         if (_remoteUserId <= 0) {
428             return Collections.emptyList();
429         }
430 
431         long companyId = PortalUtil.getCompanyId(request);
432 
433         List<Role> roles = null;
434 
435         try {
436             roles = RoleLocalServiceUtil.getRoles(companyId);
437         }
438         catch (SystemException se) {
439             _log.error(se);
440         }
441 
442         if (roles == null || roles.isEmpty()) {
443             return Collections.EMPTY_LIST;
444         }
445         else {
446             List<String> roleNames = new ArrayList<String>(roles.size());
447 
448             for (Role role : roles) {
449                 roleNames.add(role.getName());
450             }
451 
452             return roleNames;
453         }
454     }
455 
456     private ThemeDisplay _getThemeDisplay(PortletRequest portletRequest) {
457         ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
458             WebKeys.THEME_DISPLAY);
459 
460         return themeDisplay;
461     }
462 
463     private void _initUser(
464         HttpServletRequest request, com.liferay.portal.model.Portlet portlet) {
465 
466         long userId = PortalUtil.getUserId(request);
467         String remoteUser = request.getRemoteUser();
468 
469         String userPrincipalStrategy = portlet.getUserPrincipalStrategy();
470 
471         if (userPrincipalStrategy.equals(
472                 PortletConstants.USER_PRINCIPAL_STRATEGY_SCREEN_NAME)) {
473 
474             try {
475                 User user = PortalUtil.getUser(request);
476 
477                 _remoteUser = user.getScreenName();
478                 _remoteUserId = user.getUserId();
479                 _userPrincipal = new ProtectedPrincipal(_remoteUser);
480             }
481             catch (Exception e) {
482                 _log.error(e);
483             }
484         }
485         else {
486             if ((userId > 0) && (remoteUser == null)) {
487                 _remoteUser = String.valueOf(userId);
488                 _remoteUserId = userId;
489                 _userPrincipal = new ProtectedPrincipal(_remoteUser);
490             }
491             else {
492                 _remoteUser = remoteUser;
493                 _remoteUserId = GetterUtil.getLong(remoteUser);
494                 _userPrincipal = request.getUserPrincipal();
495             }
496         }
497     }
498 
499     private boolean _isWARFile() {
500         return getPortletConfig().isWARFile();
501     }
502 
503     private void _populateContainerRequest(
504         HttpServletRequest request, HttpServletResponse response,
505         ContainerRequest containerRequest, PortletRequest portletRequest) {
506 
507         containerRequest.setRoles(_getRoles(request));
508         containerRequest.setUserID(_remoteUser);
509         containerRequest.setUserPrincipal(_userPrincipal);
510         containerRequest.setLocale(_getLocale(request, portletRequest));
511         containerRequest.setUserInfo(
512             UserInfoFactory.getUserInfo(_remoteUserId, _portletModel));
513 
514         containerRequest.setAttribute(
515             WebKeys.THEME_DISPLAY, _getThemeDisplay(portletRequest));
516 
517         containerRequest.setAttribute(
518             PortletRequest.CCPP_PROFILE, _getCCPPProfile(request));
519 
520         containerRequest.setAttribute(
521             PortletRequestConstants.ESCAPE_XML_VALUE,
522             Boolean.valueOf(PropsValues.PORTLET_URL_ESCAPE_XML));
523     }
524 
525     private void _setPortletAttributes(
526         PortletRequest portletRequest, PortletResponse portletResponse) {
527 
528         HttpServletRequest request = PortalUtil.getHttpServletRequest(
529             portletRequest);
530 
531         request.setAttribute(
532             JavaConstants.JAVAX_PORTLET_CONFIG, getPortletConfig());
533         request.setAttribute(
534             JavaConstants.JAVAX_PORTLET_REQUEST, portletRequest);
535         request.setAttribute(
536             JavaConstants.JAVAX_PORTLET_RESPONSE, portletResponse);
537     }
538 
539     private static Log _log = LogFactory.getLog(WindowInvoker.class);
540 
541     private com.liferay.portal.model.Portlet _portletModel;
542     private PortletConfig _portletConfig;
543     private Container _container;
544     private boolean _remotePortlet;
545     private Profile _profile;
546     private String _remoteUser;
547     private long _remoteUserId;
548     private Principal _userPrincipal;
549 
550 }