blob: 6339df67fd36c182e1e15006600046431182c45c [file] [log] [blame]
/*
* Copyright 2003,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pluto.core;
import java.io.IOException;
import javax.portlet.PortletException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pluto.Constants;
import org.apache.pluto.internal.InternalPortletWindow;
import org.apache.pluto.internal.impl.ActionRequestImpl;
import org.apache.pluto.internal.impl.ActionResponseImpl;
import org.apache.pluto.internal.impl.PortletRequestImpl;
import org.apache.pluto.internal.impl.PortletResponseImpl;
import org.apache.pluto.internal.impl.RenderRequestImpl;
import org.apache.pluto.internal.impl.RenderResponseImpl;
import org.apache.pluto.util.StringManager;
/**
* Used internally to invoke/dispatch requests from the container to
* the portlet application.
*
* @author <a href="mailto:ddewolf@apache.org">David H. DeWolf</a>
* @author <a href="mailto:zheng@apache.org">ZHENG Zhong</a>
*/
class PortletInvoker {
/** Logger. */
private static final Log LOG = LogFactory.getLog(PortletInvoker.class);
/** Exception Messages. */
private static final StringManager EXCEPTIONS = StringManager.getManager(
PortletInvoker.class.getPackage().getName());
// Private Member Variables ------------------------------------------------
/** Portlet Window for which we are invoking the portlet. */
private InternalPortletWindow portletWindow = null;
// Constructor -------------------------------------------------------------
/**
* Default Constructor. Create a new invoker which
* is initialized for the given <code>InternalPortletWindow</code>.
*
* @param portletWindow the portlet window.
*/
public PortletInvoker(InternalPortletWindow portletWindow) {
this.portletWindow = portletWindow;
}
// Public Methods ----------------------------------------------------------
/**
* Invoke the portlet with an action request.
*
* @param request action request used for the invocation.
* @param response action response used for the invocation.
* @throws PortletException if a error occurs within the portlet.
* @throws IOException if an IO error occurs writing the response.
*
* @see PortletServlet
* @see javax.portlet.Portlet#processAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse)
*/
public void action(ActionRequestImpl request, ActionResponseImpl response)
throws PortletException, IOException {
if (LOG.isDebugEnabled()) {
LOG.debug("Performing Action Invocation");
}
invoke(request, response, Constants.METHOD_ACTION);
}
/**
* Invoke the portlet with a render request.
*
* @param request action request used for the invocation.
* @param response action response used for the invocation.
* @throws PortletException if a error occurs within the portlet.
* @throws IOException if an IO error occurs writing the response.
*
* @see PortletServlet
* @see javax.portlet.Portlet#render(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
*/
public void render(RenderRequestImpl request, RenderResponseImpl response)
throws PortletException, IOException {
if (LOG.isDebugEnabled()) {
LOG.debug("Performing Render Invocation");
}
invoke(request, response, Constants.METHOD_RENDER);
}
/**
* Invoke the portlet with a load request.
*
* @param request action request used for the invocation.
* @param response action response used for the invocation.
* @throws PortletException if a error occurs within the portlet.
*
* @see PortletServlet
*/
public void load(PortletRequestImpl request, PortletResponseImpl response)
throws PortletException, IOException {
if (LOG.isDebugEnabled()) {
LOG.debug("Performing Load Invocation");
}
invoke(request, response, Constants.METHOD_NOOP);
}
// Private Invoke Method ---------------------------------------------------
/**
* Perform the invocation.
*
* @param request portlet request
* @param response portlet response
* @param methodID method identifier
* @throws PortletException if a portlet exception occurs.
* @throws IOException if an error occurs writing to the response.
*/
private void invoke(PortletRequestImpl request,
PortletResponseImpl response,
Integer methodID)
throws PortletException, IOException {
String uri = portletWindow.getPortletEntity().getControllerServletUri();
if (LOG.isDebugEnabled()) {
LOG.debug("Dispatching to portlet servlet at: " + uri);
}
ServletContext servletContext = portletWindow.getServletContext();
RequestDispatcher dispatcher = servletContext.getRequestDispatcher(uri);
if (dispatcher != null) {
try {
// Tomcat does not like to properly include wrapped requests
// and responses. Thus we "unwrap" and then include.
HttpServletRequest servletRequest =
request.getHttpServletRequest();
HttpServletResponse servletResponse =
response.getHttpServletResponse();
servletRequest.setAttribute(Constants.METHOD_ID, methodID);
servletRequest.setAttribute(Constants.PORTLET_REQUEST, request);
servletRequest.setAttribute(Constants.PORTLET_RESPONSE, response);
dispatcher.include(servletRequest, servletResponse);
} catch (javax.servlet.UnavailableException ex) {
int seconds = ex.isPermanent()?-1:ex.getUnavailableSeconds();
String message = EXCEPTIONS.getString(
"error.portlet.invoker.unavailable",
uri, new String[] {String.valueOf(seconds)}
);
if (LOG.isErrorEnabled()) {
LOG.error(message, ex);
}
throw new javax.portlet.UnavailableException(
message, seconds);
} catch (javax.servlet.ServletException ex) {
String message = EXCEPTIONS.getString("error.portlet.invoker");
if(LOG.isErrorEnabled()) {
LOG.error(message);
}
if (ex.getRootCause() != null &&
ex.getRootCause() instanceof PortletException) {
throw (PortletException) ex.getRootCause();
}
else if(ex.getRootCause() != null) {
throw new PortletException(ex.getRootCause());
}
else {
throw new PortletException(ex);
}
} finally {
request.removeAttribute(Constants.METHOD_ID);
request.removeAttribute(Constants.PORTLET_REQUEST);
request.removeAttribute(Constants.PORTLET_RESPONSE);
}
} else {
String msg = EXCEPTIONS.getString(
"error.portlet.invoker.dispatcher",
new String[] {servletContext.getServletContextName(), uri}
);
if (LOG.isErrorEnabled()) {
LOG.error(msg);
}
throw new PortletException(msg);
}
}
}