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