/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.resiliency.mpi.portlet;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.model.Portlet;
import com.liferay.portal.kernel.portlet.ActionResult;
import com.liferay.portal.kernel.portlet.PortletContainer;
import com.liferay.portal.kernel.portlet.PortletContainerException;
import com.liferay.portal.kernel.resiliency.PortalResiliencyException;
import com.liferay.portal.kernel.resiliency.spi.SPI;
import com.liferay.portal.kernel.resiliency.spi.SPIRegistryUtil;
import com.liferay.portal.kernel.resiliency.spi.agent.SPIAgent;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.util.PropsValues;
import java.util.Collections;
import java.util.List;
import javax.portlet.Event;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Shuyang Zhou
*/
public class PortalResiliencyPortletContainerWrapper
implements PortletContainer {
public static PortletContainer
createPortalResiliencyPortletContainerWrapper(
PortletContainer portletContainer) {
if (PropsValues.PORTAL_RESILIENCY_ENABLED) {
portletContainer = new PortalResiliencyPortletContainerWrapper(
portletContainer);
}
return portletContainer;
}
public PortalResiliencyPortletContainerWrapper(
PortletContainer portletContainer) {
_portletContainer = portletContainer;
}
@Override
public void preparePortlet(HttpServletRequest request, Portlet portlet)
throws PortletContainerException {
_portletContainer.preparePortlet(request, portlet);
}
@Override
public ActionResult processAction(
HttpServletRequest request, HttpServletResponse response,
Portlet portlet)
throws PortletContainerException {
SPIAgent spiAgent = getSPIAgentForPortlet(portlet);
if (spiAgent == null) {
return _portletContainer.processAction(request, response, portlet);
}
Object[] requestAttributeValues = captureRequestAttibutes(
request, _ACTION_REQUEST_ATTRIBUTE_NAMES);
request.setAttribute(
WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.ACTION);
request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);
try {
spiAgent.service(request, response);
return (ActionResult)request.getAttribute(
WebKeys.SPI_AGENT_ACTION_RESULT);
}
catch (PortalResiliencyException pre) {
_log.error(pre, pre);
return ActionResult.EMPTY_ACTION_RESULT;
}
finally {
request.removeAttribute(WebKeys.SPI_AGENT_ACTION_RESULT);
restoreRequestAttibutes(
request, _ACTION_REQUEST_ATTRIBUTE_NAMES,
requestAttributeValues);
}
}
@Override
public List<Event> processEvent(
HttpServletRequest request, HttpServletResponse response,
Portlet portlet, Layout layout, Event event)
throws PortletContainerException {
SPIAgent spiAgent = getSPIAgentForPortlet(portlet);
if (spiAgent == null) {
return _portletContainer.processEvent(
request, response, portlet, layout, event);
}
Object[] requestAttributeValues = captureRequestAttibutes(
request, _EVENT_REQUEST_ATTRIBUTE_NAMES);
request.setAttribute(WebKeys.SPI_AGENT_EVENT, event);
request.setAttribute(WebKeys.SPI_AGENT_LAYOUT, layout);
request.setAttribute(
WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.EVENT);
request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);
try {
spiAgent.service(request, response);
return (List<Event>)request.getAttribute(
WebKeys.SPI_AGENT_EVENT_RESULT);
}
catch (PortalResiliencyException pre) {
_log.error(pre, pre);
return Collections.emptyList();
}
finally {
request.removeAttribute(WebKeys.SPI_AGENT_EVENT_RESULT);
restoreRequestAttibutes(
request, _EVENT_REQUEST_ATTRIBUTE_NAMES,
requestAttributeValues);
}
}
@Override
public void render(
HttpServletRequest request, HttpServletResponse response,
Portlet portlet)
throws PortletContainerException {
SPIAgent spiAgent = getSPIAgentForPortlet(portlet);
if (spiAgent == null) {
_portletContainer.render(request, response, portlet);
return;
}
Object[] requestAttributeValues = captureRequestAttibutes(
request, _RENDER_REQUEST_ATTRIBUTE_NAMES);
request.setAttribute(
WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.RENDER);
request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);
try {
spiAgent.service(request, response);
}
catch (PortalResiliencyException pre) {
_log.error(pre, pre);
}
finally {
restoreRequestAttibutes(
request, _RENDER_REQUEST_ATTRIBUTE_NAMES,
requestAttributeValues);
}
}
@Override
public void serveResource(
HttpServletRequest request, HttpServletResponse response,
Portlet portlet)
throws PortletContainerException {
SPIAgent spiAgent = getSPIAgentForPortlet(portlet);
if (spiAgent == null) {
_portletContainer.serveResource(request, response, portlet);
return;
}
Object[] requestAttributeValues = captureRequestAttibutes(
request, _RESOURCE_REQUEST_ATTRIBUTE_NAMES);
request.setAttribute(
WebKeys.SPI_AGENT_LIFECYCLE, SPIAgent.Lifecycle.RESOURCE);
request.setAttribute(WebKeys.SPI_AGENT_PORTLET, portlet);
try {
spiAgent.service(request, response);
}
catch (PortalResiliencyException pre) {
_log.error(pre, pre);
}
finally {
restoreRequestAttibutes(
request, _RESOURCE_REQUEST_ATTRIBUTE_NAMES,
requestAttributeValues);
}
}
protected Object[] captureRequestAttibutes(
HttpServletRequest request, String... names) {
Object[] values = new Object[names.length];
for (int i = 0; i < names.length; i++) {
values[i] = request.getAttribute(names[i]);
}
return values;
}
protected SPIAgent getSPIAgentForPortlet(Portlet portlet)
throws PortletContainerException {
try {
SPI spi = SPIRegistryUtil.getPortletSPI(portlet.getRootPortletId());
if (spi == null) {
return null;
}
if (_log.isDebugEnabled()) {
_log.debug(
"Portlet " + portlet + " is registered to SPI " + spi);
}
return spi.getSPIAgent();
}
catch (Exception e) {
throw new PortletContainerException(e);
}
}
protected void restoreRequestAttibutes(
HttpServletRequest request, String[] names, Object[] values) {
for (int i = 0; i < names.length; i++) {
String name = names[i];
Object value = values[i];
if (value == null) {
request.removeAttribute(name);
}
else {
request.setAttribute(name, value);
}
}
}
private static final String[] _ACTION_REQUEST_ATTRIBUTE_NAMES =
{WebKeys.SPI_AGENT_LIFECYCLE, WebKeys.SPI_AGENT_PORTLET};
private static final String[] _EVENT_REQUEST_ATTRIBUTE_NAMES = {
WebKeys.SPI_AGENT_EVENT, WebKeys.SPI_AGENT_LAYOUT,
WebKeys.SPI_AGENT_LIFECYCLE, WebKeys.SPI_AGENT_PORTLET
};
private static final String[] _RENDER_REQUEST_ATTRIBUTE_NAMES =
_ACTION_REQUEST_ATTRIBUTE_NAMES;
private static final String[] _RESOURCE_REQUEST_ATTRIBUTE_NAMES =
_ACTION_REQUEST_ATTRIBUTE_NAMES;
private static final Log _log = LogFactoryUtil.getLog(
PortalResiliencyPortletContainerWrapper.class);
private final PortletContainer _portletContainer;
}