/*
* Copyright 2005-2006 the original author or authors.
*
* 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.strecks.controller;
import java.util.Collection;
import java.util.Collections;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForward;
import org.strecks.constants.InfrastructureKeys;
import org.strecks.context.ActionContext;
import org.strecks.exceptions.ApplicationRuntimeException;
import org.strecks.interceptor.AfterInterceptor;
import org.strecks.interceptor.BeforeInterceptor;
import org.strecks.util.Assert;
import org.strecks.util.ReflectHelper;
import org.strecks.view.ActionForwardViewAdapter;
import org.strecks.view.RenderingViewAdapter;
import org.strecks.view.ViewAdapter;
/**
* Delegate which carries out Strecks-specific request processing on behalf of the
* <code>ControllerRequestProcessor</code> class.
* @author Phil Zoio
*/
public class ControllerProcessorDelegateImpl implements ControllerProcessorDelegate
{
private static Log log = LogFactory.getLog(ControllerProcessorDelegateImpl.class);
private Collection<BeforeInterceptor> beforeInterceptors = Collections.emptyList();
private Collection<AfterInterceptor> afterInterceptors = Collections.emptyList();
public ControllerProcessorDelegateImpl()
{
}
public ActionForward handleActionPerform(ControllerAction action, ActionContext context) throws Exception
{
HttpServletRequest request = context.getRequest();
ViewAdapter viewAdapter = null;
Object actionBean = null;
Exception ee = null;
try
{
actionBean = action.getBeanSource().createBean(context);
// Dependency injection and init method done here
action.preExecute(actionBean, context);
// BeforeInterceptor exceptions are handled by the Struts-configured exception handler
for (BeforeInterceptor beforeInterceptor : beforeInterceptors)
{
runBeforeInterceptor(actionBean, beforeInterceptor, context);
}
Collection<BeforeInterceptor> actionBeforeInterceptors = action.getBeforeInterceptors();
if (actionBeforeInterceptors != null)
{
for (BeforeInterceptor beforeInterceptor : actionBeforeInterceptors)
{
runBeforeInterceptor(actionBean, beforeInterceptor, context);
}
}
viewAdapter = action.executeController(actionBean, context);
}
catch (Exception e)
{
ee = e;
log.error(e);
throw e;
}
finally
{
Collection<AfterInterceptor> actionAfterInterceptors = action.getAfterInterceptors();
if (actionAfterInterceptors != null)
{
for (AfterInterceptor afterInterceptor : actionAfterInterceptors)
{
runAfterInterceptor(actionBean, afterInterceptor, context, ee);
}
}
// AfterInterceptor exceptions are caught, logged and ignored afterwards
for (AfterInterceptor afterInterceptor : afterInterceptors)
{
runAfterInterceptor(actionBean, afterInterceptor, context, ee);
}
action.postExecute(actionBean, context, ee);
}
request.setAttribute(InfrastructureKeys.ACTION_BEAN, actionBean);
if (viewAdapter == null)
{
return null;
}
else
{
if (viewAdapter instanceof ActionForwardViewAdapter)
{
ActionForwardViewAdapter va = (ActionForwardViewAdapter) viewAdapter;
ActionForward actionForward = va.getActionForward();
request.setAttribute(InfrastructureKeys.ACTION_FORWARD, actionForward);
return actionForward;
}
else if (viewAdapter instanceof RenderingViewAdapter)
{
RenderingViewAdapter va = (RenderingViewAdapter) viewAdapter;
va.render(context);
}
}
return null;
}
@SuppressWarnings("unchecked")
void runAfterInterceptor(Object actionBean, AfterInterceptor afterInterceptor, ActionContext context, Exception ee)
{
try
{
afterInterceptor.afterExecute(actionBean, context, ee);
}
catch (ClassCastException e)
{
throw new ApplicationRuntimeException("Action bean class " + actionBean.getClass().getName()
+ " is not compatible with AfterInterceptor implementation "
+ afterInterceptor.getClass().getName() + ", which is parameterized with the type "
+ ReflectHelper.getGenericType(afterInterceptor.getClass(), AfterInterceptor.class), e);
}
catch (Exception e)
{
log.error("Error during execution of afterInterceptor", e);
}
}
@SuppressWarnings("unchecked")
void runBeforeInterceptor(Object actionBean, BeforeInterceptor beforeInterceptor, ActionContext context)
{
try
{
beforeInterceptor.beforeExecute(actionBean, context);
}
catch (ClassCastException e)
{
throw new ApplicationRuntimeException("Action bean class " + actionBean.getClass().getName()
+ " is not compatible with BeforeInterceptor implementation "
+ beforeInterceptor.getClass().getName() + ", which is parameterized with the type "
+ ReflectHelper.getGenericType(beforeInterceptor.getClass(), BeforeInterceptor.class));
}
}
public Collection<BeforeInterceptor> getBeforeInterceptors()
{
return this.beforeInterceptors;
}
public Collection<AfterInterceptor> getAfterInterceptors()
{
return this.afterInterceptors;
}
public void setAfterInterceptors(Collection<AfterInterceptor> afterInterceptors)
{
Assert.notNull(afterInterceptors);
this.afterInterceptors = afterInterceptors;
}
public void setBeforeInterceptors(Collection<BeforeInterceptor> beforeInterceptors)
{
Assert.notNull(beforeInterceptors);
this.beforeInterceptors = beforeInterceptors;
}
}