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