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