001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.resiliency.mpi.portlet;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.portlet.ActionResult;
020    import com.liferay.portal.kernel.portlet.PortletContainer;
021    import com.liferay.portal.kernel.portlet.PortletContainerException;
022    import com.liferay.portal.kernel.resiliency.PortalResiliencyException;
023    import com.liferay.portal.kernel.resiliency.spi.SPI;
024    import com.liferay.portal.kernel.resiliency.spi.SPIRegistryUtil;
025    import com.liferay.portal.kernel.resiliency.spi.agent.SPIAgent;
026    import com.liferay.portal.kernel.util.WebKeys;
027    import com.liferay.portal.model.Layout;
028    import com.liferay.portal.model.Portlet;
029    import com.liferay.portal.util.PropsValues;
030    
031    import java.rmi.RemoteException;
032    
033    import java.util.Collections;
034    import java.util.List;
035    
036    import javax.portlet.Event;
037    
038    import javax.servlet.http.HttpServletRequest;
039    import javax.servlet.http.HttpServletResponse;
040    
041    /**
042     * @author Shuyang Zhou
043     */
044    public class PortalResiliencyPortletContainerWrapper
045            implements PortletContainer {
046    
047            public static PortletContainer
048                    createPortalResiliencyPortletContainerWrapper(
049                            PortletContainer portletContainer) {
050    
051                    if (PropsValues.PORTAL_RESILIENCY_ENABLED) {
052                            portletContainer = new PortalResiliencyPortletContainerWrapper(
053                                    portletContainer);
054                    }
055    
056                    return portletContainer;
057            }
058    
059            public PortalResiliencyPortletContainerWrapper(
060                    PortletContainer portletContainer) {
061    
062                    _portletContainer = portletContainer;
063            }
064    
065            @Override
066            public void preparePortlet(HttpServletRequest request, Portlet portlet)
067                    throws PortletContainerException {
068    
069                    _portletContainer.preparePortlet(request, portlet);
070            }
071    
072            @Override
073            public ActionResult processAction(
074                            HttpServletRequest request, HttpServletResponse response,
075                            Portlet portlet)
076                    throws PortletContainerException {
077    
078                    SPIAgent spiAgent = getSPIAgentForPortlet(portlet);
079    
080                    if (spiAgent == null) {
081                            return _portletContainer.processAction(request, response, portlet);
082                    }
083    
084                    request.setAttribute(
085                            WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.ACTION);
086                    request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);
087    
088                    try {
089                            spiAgent.service(request, response);
090    
091                            return (ActionResult)request.getAttribute(
092                                    WebKeys.SPI_AGENT_ACTION_RESULT);
093                    }
094                    catch (PortalResiliencyException pre) {
095                            _log.error(pre, pre);
096    
097                            return ActionResult.EMPTY_ACTION_RESULT;
098                    }
099                    finally {
100                            request.removeAttribute(WebKeys.SPI_AGENT_ACTION_RESULT);
101                            request.removeAttribute(WebKeys.SPI_AGENT_LIFECYCLE);
102                            request.removeAttribute(WebKeys.SPI_AGENT_PORTLET);
103                    }
104            }
105    
106            @Override
107            public List<Event> processEvent(
108                            HttpServletRequest request, HttpServletResponse response,
109                            Portlet portlet, Layout layout, Event event)
110                    throws PortletContainerException {
111    
112                    SPIAgent spiAgent = getSPIAgentForPortlet(portlet);
113    
114                    if (spiAgent == null) {
115                            return _portletContainer.processEvent(
116                                    request, response, portlet, layout, event);
117                    }
118    
119                    request.setAttribute(WebKeys.SPI_AGENT_EVENT, event);
120                    request.setAttribute(WebKeys.SPI_AGENT_LAYOUT, layout);
121                    request.setAttribute(
122                            WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.EVENT);
123                    request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);
124    
125                    try {
126                            spiAgent.service(request, response);
127    
128                            return (List<Event>)request.getAttribute(
129                                    WebKeys.SPI_AGENT_EVENT_RESULT);
130                    }
131                    catch (PortalResiliencyException pre) {
132                            _log.error(pre, pre);
133    
134                            return Collections.emptyList();
135                    }
136                    finally {
137                            request.removeAttribute(WebKeys.SPI_AGENT_EVENT);
138                            request.removeAttribute(WebKeys.SPI_AGENT_EVENT_RESULT);
139                            request.removeAttribute(WebKeys.SPI_AGENT_LAYOUT);
140                            request.removeAttribute(WebKeys.SPI_AGENT_LIFECYCLE);
141                            request.removeAttribute(WebKeys.SPI_AGENT_PORTLET);
142                    }
143            }
144    
145            @Override
146            public void render(
147                            HttpServletRequest request, HttpServletResponse response,
148                            Portlet portlet)
149                    throws PortletContainerException {
150    
151                    SPIAgent spiAgent = getSPIAgentForPortlet(portlet);
152    
153                    if (spiAgent == null) {
154                            _portletContainer.render(request, response, portlet);
155    
156                            return;
157                    }
158    
159                    request.setAttribute(
160                            WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.RENDER);
161                    request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);
162    
163                    try {
164                            spiAgent.service(request, response);
165                    }
166                    catch (PortalResiliencyException pre) {
167                            _log.error(pre, pre);
168                    }
169                    finally {
170                            request.removeAttribute(WebKeys.SPI_AGENT_LIFECYCLE);
171                            request.removeAttribute(WebKeys.SPI_AGENT_PORTLET);
172                    }
173            }
174    
175            @Override
176            public void serveResource(
177                            HttpServletRequest request, HttpServletResponse response,
178                            Portlet portlet)
179                    throws PortletContainerException {
180    
181                    SPIAgent spiAgent = getSPIAgentForPortlet(portlet);
182    
183                    if (spiAgent == null) {
184                            _portletContainer.serveResource(request, response, portlet);
185    
186                            return;
187                    }
188    
189                    request.setAttribute(
190                            WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.RESOURCE);
191                    request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);
192    
193                    try {
194                            spiAgent.service(request, response);
195                    }
196                    catch (PortalResiliencyException pre) {
197                            _log.error(pre, pre);
198                    }
199                    finally {
200                            request.removeAttribute(WebKeys.SPI_AGENT_LIFECYCLE);
201                            request.removeAttribute(WebKeys.SPI_AGENT_PORTLET);
202                    }
203            }
204    
205            protected SPIAgent getSPIAgentForPortlet(Portlet portlet)
206                    throws PortletContainerException {
207    
208                    SPI spi = SPIRegistryUtil.getPortletSPI(portlet.getRootPortletId());
209    
210                    if (spi == null) {
211                            return null;
212                    }
213    
214                    if (_log.isDebugEnabled()) {
215                            _log.debug("Portlet " + portlet + " is registered to SPI " + spi);
216                    }
217    
218                    try {
219                            return spi.getSPIAgent();
220                    }
221                    catch (RemoteException re) {
222                            throw new PortletContainerException(re);
223                    }
224            }
225    
226            private static Log _log = LogFactoryUtil.getLog(
227                    PortalResiliencyPortletContainerWrapper.class);
228    
229            private PortletContainer _portletContainer;
230    
231    }