1   /**
2    * Copyright (c) 2000-2008 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 2008 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.portlet.LiferayWindowState;
47  import com.liferay.portal.kernel.servlet.ProtectedPrincipal;
48  import com.liferay.portal.kernel.util.GetterUtil;
49  import com.liferay.portal.kernel.util.JavaConstants;
50  import com.liferay.portal.kernel.util.LocaleUtil;
51  import com.liferay.portal.kernel.util.StringPool;
52  import com.liferay.portal.model.PortletConstants;
53  import com.liferay.portal.model.Role;
54  import com.liferay.portal.model.User;
55  import com.liferay.portal.service.RoleLocalServiceUtil;
56  import com.liferay.portal.theme.ThemeDisplay;
57  import com.liferay.portal.util.PortalUtil;
58  import com.liferay.portal.util.WebKeys;
59  import com.liferay.portlet.ActionRequestImpl;
60  import com.liferay.portlet.ActionResponseImpl;
61  import com.liferay.portlet.InvokerPortlet;
62  import com.liferay.portlet.RenderRequestImpl;
63  import com.liferay.portlet.RenderResponseImpl;
64  import com.liferay.portlet.ResourceRequestImpl;
65  import com.liferay.portlet.ResourceResponseImpl;
66  import com.liferay.portlet.UserInfoFactory;
67  
68  import com.sun.portal.container.ChannelMode;
69  import com.sun.portal.container.ChannelState;
70  import com.sun.portal.container.ChannelURLType;
71  import com.sun.portal.container.Container;
72  import com.sun.portal.container.ContainerFactory;
73  import com.sun.portal.container.ContainerRequest;
74  import com.sun.portal.container.ContainerType;
75  import com.sun.portal.container.ExecuteActionRequest;
76  import com.sun.portal.container.ExecuteActionResponse;
77  import com.sun.portal.container.GetMarkupRequest;
78  import com.sun.portal.container.GetMarkupResponse;
79  import com.sun.portal.container.GetResourceRequest;
80  import com.sun.portal.container.GetResourceResponse;
81  import com.sun.portal.portletcontainer.appengine.PortletAppEngineUtils;
82  
83  import java.io.IOException;
84  import java.io.PrintWriter;
85  
86  import java.net.URL;
87  
88  import java.security.Principal;
89  
90  import java.util.ArrayList;
91  import java.util.Collections;
92  import java.util.List;
93  import java.util.Locale;
94  import java.util.Map;
95  
96  import javax.ccpp.Profile;
97  
98  import javax.portlet.ActionRequest;
99  import javax.portlet.ActionResponse;
100 import javax.portlet.EventRequest;
101 import javax.portlet.EventResponse;
102 import javax.portlet.Portlet;
103 import javax.portlet.PortletConfig;
104 import javax.portlet.PortletContext;
105 import javax.portlet.PortletException;
106 import javax.portlet.PortletRequest;
107 import javax.portlet.PortletResponse;
108 import javax.portlet.RenderRequest;
109 import javax.portlet.RenderResponse;
110 import javax.portlet.ResourceRequest;
111 import javax.portlet.ResourceResponse;
112 
113 import javax.servlet.http.HttpServletRequest;
114 import javax.servlet.http.HttpServletResponse;
115 
116 import org.apache.commons.logging.Log;
117 import org.apache.commons.logging.LogFactory;
118 
119 /**
120  * <a href="WindowInvoker.java.html"><b><i>View Source</i></b></a>
121  *
122  * @author Deepak Gothe
123  * @author Brian Wing Shun Chan
124  *
125  */
126 public class WindowInvoker extends InvokerPortlet {
127 
128     public WindowInvoker(
129             com.liferay.portal.model.Portlet portletModel, Portlet portlet,
130             PortletContext portletContext)
131         throws PortletException {
132 
133         super(portletModel, portlet, portletContext);
134 
135         _portletModel = portletModel;
136         _container = _getContainer();
137     }
138 
139     public WindowInvoker(
140             com.liferay.portal.model.Portlet portletModel, Portlet portlet,
141             PortletConfig portletConfig, PortletContext portletContext,
142             boolean facesPortlet, boolean strutsPortlet,
143             boolean strutsBridgePortlet)
144         throws PortletException {
145 
146         super(
147             portletModel, portlet, portletConfig, portletContext, facesPortlet,
148             strutsPortlet, strutsBridgePortlet);
149 
150         _portletModel = portletModel;
151         _container = _getContainer();
152     }
153 
154     protected void invokeAction(
155             ActionRequest actionRequest, ActionResponse actionResponse)
156         throws IOException, PortletException {
157 
158         if (!_isWARFile()) {
159             super.invokeAction(actionRequest, actionResponse);
160 
161             return;
162         }
163 
164         try {
165             ActionRequestImpl actionRequestImpl =
166                 (ActionRequestImpl)actionRequest;
167             ActionResponseImpl actionResponseImpl =
168                 (ActionResponseImpl)actionResponse;
169 
170             HttpServletRequest request =
171                 actionRequestImpl.getOriginalHttpServletRequest();
172             HttpServletResponse response =
173                 actionResponseImpl.getHttpServletResponse();
174 
175             _initUser(request, _portletModel);
176 
177             ExecuteActionRequest executeActionRequest =
178                 ContainerRequestFactory.createExecuteActionRequest(
179                     request, _portletModel, actionRequestImpl.getWindowState(),
180                     actionRequestImpl.getPortletMode(), _getPlid(actionRequest),
181                     isFacesPortlet(), _remotePortlet);
182 
183             _populateContainerRequest(request, response, executeActionRequest);
184 
185             ExecuteActionResponse executeActionResponse =
186                 ContainerResponseFactory.createExecuteActionResponse(response);
187 
188             ChannelURLType urlType =
189                 executeActionRequest.getWindowRequestReader().readURLType(
190                     request);
191 
192             _container.executeAction(
193                 executeActionRequest, executeActionResponse, urlType);
194 
195             URL redirectURL = executeActionResponse.getRedirectURL();
196 
197             if (redirectURL != null) {
198                 actionResponseImpl.setRedirectLocation(redirectURL.toString());
199             }
200 
201             ChannelState newWindowState =
202                 executeActionResponse.getNewWindowState();
203 
204             if (newWindowState != null) {
205                 actionResponseImpl.setWindowState(
206                     PortletAppEngineUtils.getWindowState(newWindowState));
207             }
208 
209             ChannelMode newPortletMode =
210                 executeActionResponse.getNewChannelMode();
211 
212             if (newPortletMode != null) {
213                 actionResponseImpl.setPortletMode(
214                     PortletAppEngineUtils.getPortletMode(newPortletMode));
215             }
216         }
217         catch (Exception e) {
218             throw new PortletException(e);
219         }
220         finally {
221             _setPortletAttributes(actionRequest, actionResponse);
222         }
223     }
224 
225     protected void invokeEvent(
226             EventRequest eventRequest, EventResponse eventResponse)
227         throws IOException, PortletException {
228 
229         if (!_isWARFile()) {
230             super.invokeEvent(eventRequest, eventResponse);
231         }
232     }
233 
234     protected String invokeRender(
235             RenderRequest renderRequest, RenderResponse renderResponse)
236         throws IOException, PortletException {
237 
238         if (!_isWARFile()) {
239             return super.invokeRender(renderRequest, renderResponse);
240         }
241 
242         try {
243             RenderRequestImpl renderRequestImpl =
244                 (RenderRequestImpl)renderRequest;
245             RenderResponseImpl renderResponseImpl =
246                 (RenderResponseImpl)renderResponse;
247 
248             HttpServletRequest request =
249                 renderRequestImpl.getOriginalHttpServletRequest();
250             HttpServletResponse response =
251                 renderResponseImpl.getHttpServletResponse();
252 
253             _initUser(request, _portletModel);
254 
255             GetMarkupRequest getMarkupRequest =
256                 ContainerRequestFactory.createGetMarkUpRequest(
257                     request, _portletModel, renderRequestImpl.getWindowState(),
258                     renderRequestImpl.getPortletMode(), _getPlid(renderRequest),
259                     isFacesPortlet(), _remotePortlet);
260 
261             _populateContainerRequest(request, response, getMarkupRequest);
262 
263             GetMarkupResponse getMarkupResponse =
264                 ContainerResponseFactory.createGetMarkUpResponse(response);
265 
266             List<String> allowableContentTypes =
267                 getMarkupRequest.getAllowableContentTypes();
268 
269             if (renderRequest.getWindowState().equals(
270                     LiferayWindowState.EXCLUSIVE)) {
271 
272                 allowableContentTypes.add("*/*");
273             }
274 
275             getMarkupRequest.setAllowableContentTypes(allowableContentTypes);
276 
277             _container.getMarkup(getMarkupRequest, getMarkupResponse);
278 
279             Map<String, List<String>> properties =
280                 getMarkupResponse.getStringProperties();
281 
282             if ((properties != null) &&
283                 (properties.containsKey("clear-request-parameters"))) {
284 
285                 getMarkupRequest.getRenderParameters().clear();
286             }
287 
288             StringBuffer sb = getMarkupResponse.getMarkup();
289 
290             PrintWriter pw = response.getWriter();
291 
292             pw.print(sb);
293 
294             return getMarkupResponse.getTitle();
295 
296         }
297         catch (Exception e) {
298             throw new PortletException(e);
299         }
300         finally {
301             _setPortletAttributes(renderRequest, renderResponse);
302         }
303     }
304 
305     protected void invokeResource(
306             ResourceRequest resourceRequest, ResourceResponse resourceResponse)
307         throws IOException, PortletException {
308 
309         if (!_isWARFile()) {
310             super.invokeResource(resourceRequest, resourceResponse);
311 
312             return;
313         }
314 
315         try {
316             ResourceRequestImpl resourceRequestImpl =
317                 (ResourceRequestImpl)resourceRequest;
318             ResourceResponseImpl resourceResponseImpl =
319                 (ResourceResponseImpl)resourceResponse;
320 
321             HttpServletRequest request =
322                 resourceRequestImpl.getOriginalHttpServletRequest();
323             HttpServletResponse response =
324                 resourceResponseImpl.getHttpServletResponse();
325 
326             _initUser(request, _portletModel);
327 
328             GetResourceRequest getResourceRequest =
329                 ContainerRequestFactory.createGetResourceRequest(
330                     request, _portletModel,
331                     resourceRequestImpl.getWindowState(),
332                     resourceRequestImpl.getPortletMode(),
333                     _getPlid(resourceRequest), isFacesPortlet(),
334                     _remotePortlet);
335 
336             _populateContainerRequest(request, response, getResourceRequest);
337 
338             GetResourceResponse getResourceResponse =
339                 ContainerResponseFactory .createGetResourceResponse(response);
340 
341             _container.getResources(
342                 getResourceRequest, getResourceResponse);
343 
344             String contentType = response.getContentType();
345 
346             if (contentType != null) {
347                 resourceResponseImpl.setContentType(contentType);
348             }
349 
350             StringBuffer sb = getResourceResponse.getContentAsBuffer();
351 
352             byte[] bytes = getResourceResponse.getContentAsBytes();
353 
354             if (sb != null) {
355                 response.getWriter().print(sb);
356             }
357             else if ((bytes != null) && (bytes.length > 0)) {
358                 response.getOutputStream().write(bytes);
359             }
360             else {
361                 response.getWriter().print(StringPool.BLANK);
362             }
363 
364         }
365         catch (Exception e) {
366             throw new PortletException(e);
367         }
368         finally {
369             _setPortletAttributes(resourceRequest, resourceResponse);
370         }
371     }
372 
373     private Profile _getCCPPProfile(HttpServletRequest request) {
374         if (_profile == null) {
375             _profile = PortalProfileFactory.getCCPPProfile(request);
376         }
377 
378         return _profile;
379     }
380 
381     private Container _getContainer() {
382         if (_remotePortlet) {
383             return ContainerFactory.getContainer(ContainerType.WSRP_CONSUMER);
384         }
385         else {
386             return ContainerFactory.getContainer(
387                 ContainerType.PORTLET_CONTAINER);
388         }
389     }
390 
391     public Locale _getLocale(HttpServletRequest request) {
392         Locale locale = request.getLocale();
393 
394         if (locale == null) {
395             locale = LocaleUtil.getDefault();
396         }
397 
398         return locale;
399     }
400 
401     private long _getPlid(PortletRequest portletRequest) {
402         ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
403             WebKeys.THEME_DISPLAY);
404 
405         return themeDisplay.getPlid();
406     }
407 
408     private List<String> _getRoles(HttpServletRequest request) {
409         if (_remoteUserId <= 0) {
410             return Collections.emptyList();
411         }
412 
413         long companyId = PortalUtil.getCompanyId(request);
414 
415         List<Role> roles = null;
416 
417         try {
418             roles = RoleLocalServiceUtil.getRoles(companyId);
419         }
420         catch (SystemException se) {
421             _log.error(se);
422         }
423 
424         if (roles == null || roles.isEmpty()) {
425             return Collections.EMPTY_LIST;
426         }
427         else {
428             List<String> roleNames = new ArrayList<String>(roles.size());
429 
430             for (Role role : roles) {
431                 roleNames.add(role.getName());
432             }
433 
434             return roleNames;
435         }
436     }
437 
438     private void _initUser(
439         HttpServletRequest request, com.liferay.portal.model.Portlet portlet) {
440 
441         long userId = PortalUtil.getUserId(request);
442         String remoteUser = request.getRemoteUser();
443 
444         String userPrincipalStrategy = portlet.getUserPrincipalStrategy();
445 
446         if (userPrincipalStrategy.equals(
447                 PortletConstants.USER_PRINCIPAL_STRATEGY_SCREEN_NAME)) {
448 
449             try {
450                 User user = PortalUtil.getUser(request);
451 
452                 _remoteUser = user.getScreenName();
453                 _remoteUserId = user.getUserId();
454                 _userPrincipal = new ProtectedPrincipal(_remoteUser);
455             }
456             catch (Exception e) {
457                 _log.error(e);
458             }
459         }
460         else {
461             if ((userId > 0) && (remoteUser == null)) {
462                 _remoteUser = String.valueOf(userId);
463                 _remoteUserId = userId;
464                 _userPrincipal = new ProtectedPrincipal(_remoteUser);
465             }
466             else {
467                 _remoteUser = remoteUser;
468                 _remoteUserId = GetterUtil.getLong(remoteUser);
469                 _userPrincipal = request.getUserPrincipal();
470             }
471         }
472     }
473 
474     private boolean _isWARFile() {
475         return getPortletConfig().isWARFile();
476     }
477 
478     private void _populateContainerRequest(
479         HttpServletRequest request, HttpServletResponse response,
480         ContainerRequest containerRequest) {
481 
482         containerRequest.setRoles(_getRoles(request));
483         containerRequest.setUserID(_remoteUser);
484         containerRequest.setUserPrincipal(_userPrincipal);
485         containerRequest.setLocale(_getLocale(request));
486         containerRequest.setUserInfo(
487             UserInfoFactory.getUserInfo(_remoteUserId, _portletModel));
488 
489         containerRequest.setAttribute(
490             PortletRequest.CCPP_PROFILE, _getCCPPProfile(request));
491     }
492 
493     private void _setPortletAttributes(
494         PortletRequest portletRequest, PortletResponse portletResponse) {
495 
496         HttpServletRequest request = PortalUtil.getHttpServletRequest(
497             portletRequest);
498 
499         request.setAttribute(
500             JavaConstants.JAVAX_PORTLET_CONFIG, getPortletConfig());
501         request.setAttribute(
502             JavaConstants.JAVAX_PORTLET_REQUEST, portletRequest);
503         request.setAttribute(
504             JavaConstants.JAVAX_PORTLET_RESPONSE, portletResponse);
505     }
506 
507     private static Log _log = LogFactory.getLog(WindowInvoker.class);
508 
509     private com.liferay.portal.model.Portlet _portletModel;
510     private Container _container;
511     private boolean _remotePortlet;
512     private Profile _profile;
513     private String _remoteUser;
514     private long _remoteUserId;
515     private Principal _userPrincipal;
516 
517 }