📄 multiactioneventcontroller.java
字号:
/* * Copyright 2002-2004 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 de.mindmatters.faces.spring.context.servlet.controller;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import javax.faces.component.EditableValueHolder;import javax.faces.component.UIComponent;import javax.faces.component.UIForm;import javax.faces.context.FacesContext;import javax.faces.el.ValueBinding;import javax.faces.el.VariableResolver;import javax.faces.event.ActionEvent;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.beans.factory.InitializingBean;import org.springframework.util.Assert;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.AbstractController;import org.springframework.web.servlet.mvc.LastModified;import org.springframework.web.servlet.mvc.multiaction.MethodNameResolver;import org.springframework.web.servlet.mvc.multiaction.MultiActionController;import de.mindmatters.faces.application.ActionEventContextHolder;import de.mindmatters.faces.el.ELUtils;import de.mindmatters.faces.spring.context.servlet.lifecycle.ApplyRequestValuesPhaseListener;import de.mindmatters.faces.spring.context.servlet.lifecycle.InvokeApplicationPhaseListener;import de.mindmatters.faces.spring.context.servlet.lifecycle.PhaseListenerHelper;import de.mindmatters.faces.spring.context.servlet.lifecycle.ProcessValidationsPhaseListener;import de.mindmatters.faces.spring.context.servlet.lifecycle.RenderResponsePhaseListener;import de.mindmatters.faces.spring.context.servlet.lifecycle.RestoreViewPhaseListener;import de.mindmatters.faces.spring.context.servlet.lifecycle.UpdateModelValuesPhaseListener;/** * JSF-Spring's integration class of Spring's <strong>{@link MultiActionController}</strong>. * For further informtion please have a look at the documentation of * {@link MultiActionController}. * * <p> * MultiActionController can handle several different types of request with * methods of a well documented form (see {@link MultiActionController}). Such * methods are allowed to take a third parameter HttpSession, a Map or a single * domain specific type. Typically JSF binds the input fields (the request * parameters) of a HTTP form to backing beans (also known as managed beans) * with unique names. All those backing beans which takes the request parameters * will be exposed as third parameter in a Map (with their names as keys) if the * action method is accordingly parameterized. If such a third parameter is a * single domain specific type, the first occurrence of the type in the backing * bean map is exposed to it. So it's very easy to integrate singleton scoped * controllers which can handle request scoped model data. * </p> * * <p> * Furthermore this class implements the phaselistener interfaces specified by * the <code>de.mindmatters.faces.spring.context.servlet.lifecycle</code> * package. Subclasses may override them or (if this class is used with a * delegate configured by {@link #setDelegate(Object)}) delegates may implement * them. * </p> * * @author Andreas Kuhrwahl * */public class MultiActionEventController extends AbstractController implements InitializingBean, LastModified, RestoreViewPhaseListener, ApplyRequestValuesPhaseListener, ProcessValidationsPhaseListener, UpdateModelValuesPhaseListener, InvokeApplicationPhaseListener, RenderResponsePhaseListener { /** * Extends the {@link MultiActionController}. Binding the request * parameters and CommandObject creation is turned off because JSF is * specified to do this operations. Managed beans with HTTP form data will * be exposed as 'CommandObject' instead. * * <p> * {@link ActionMethodNameResolver} is used as default * {@link MethodNameResolver}. * </p> * * @author Andreas Kuhrwahl * */ private final class InternalController extends MultiActionController { /** * Constructor for MultiActionController that looks for handler methods * in the present subclass. Caches methods for quick invocation later. * This class's use of reflection will impose little overhead at * runtime. */ public InternalController() { super(); setMethodNameResolver(new ActionMethodNameResolver()); } /** * Constructor for MultiActionController that looks for handler methods * in delegate, rather than a subclass of this class. Caches methods for * quick invocation later. * * @param delegate * handler object. This doesn't need to implement any * particular interface, as everything is done using * reflection. */ public InternalController(final Object delegate) { super(delegate); setMethodNameResolver(new ActionMethodNameResolver()); } /** * {@inheritDoc} */ public ModelAndView handleRequestInternal( final HttpServletRequest request, final HttpServletResponse response) throws Exception { return super.handleRequestInternal(request, response); } /** * {@inheritDoc} */ protected void bind(final HttpServletRequest request, final Object actionEvent) throws Exception { } /** * {@inheritDoc} */ protected Object newCommandObject(final Class clazz) throws Exception { FacesContext context = FacesContext.getCurrentInstance(); Assert.notNull(context); ActionEvent event = ActionEventContextHolder.getActionEvent(); Assert.notNull(event); Map commandObjects = new HashMap(); searchCommandObjects(findNestingForm(event.getComponent()), context, context.getApplication().getVariableResolver(), commandObjects); Object commandObject = null; if (Map.class.equals(clazz) || Object.class.equals(clazz)) { commandObject = commandObjects; } else { for (Iterator i = commandObjects.values().iterator(); i .hasNext();) { Object currentCommandObject = i.next(); if (clazz.isAssignableFrom(currentCommandObject.getClass())) { commandObject = currentCommandObject; break; } } } return commandObject; } /** * Searches the managed beans which were populated with request * parameters. * * @param component * the {@link UIComponent} to check for population * @param context * the {@link FacesContext} that holds request information * @param variableResolver * the {@link VariableResolver} of the underlying JSF * implementation * @param commandObjects * the Map with the managed beans populated with form data */ private void searchCommandObjects(final UIComponent component, final FacesContext context, final VariableResolver variableResolver, final Map commandObjects) { if (component instanceof EditableValueHolder) { ValueBinding vb = component.getValueBinding("value"); String beanName = ELUtils.resolveToBase(context, vb); commandObjects.put(beanName, variableResolver.resolveVariable( context, beanName)); } for (Iterator i = component.getFacetsAndChildren(); i.hasNext();) { searchCommandObjects((UIComponent) i.next(), context, variableResolver, commandObjects); } } /** * Searches the submitted {@link UIForm}. * * @param component * nested component * @return th {@link UIForm} */ private UIForm findNestingForm(final UIComponent component) { UIComponent parent = component.getParent(); while (parent != null && !(parent instanceof UIForm)) { parent = parent.getParent(); } return (UIForm) parent; } } /** The extended {@link MultiActionController} used for delegation. */ private InternalController controller; /** * The real delegate controller or <code>null</code> if this instance is * used as handler. */ private Object handler; /** * Constructor for MultiActionEventController that looks for handler methods * in the present subclass. */ public MultiActionEventController() { } /** * Constructor for MultiActionEventController that looks for handler methods * in delegate, rather than a subclass of this class. * * @param delegate * handler object. This doesn't need to implement any particular * interface, as everything is done using reflection. */ public MultiActionEventController(final Object delegate) { setDelegate(delegate); } /** * {@inheritDoc} */ public final void afterPropertiesSet() throws Exception { if (this.controller == null) { setDelegate(this); } initMultiActionEventController(); } /** * This method allows the bean instance to perform initialization only * possible when all bean properties have been set and to throw an exception * in the event of misconfiguration. * * @throws Exception * in the event of misconfiguration (such as failure to set an * essential property) or if initialization fails. */ protected void initMultiActionEventController() throws Exception { } /** * {@inheritDoc} */ public final long getLastModified(final HttpServletRequest request) { return controller.getLastModified(request); } /** * Set the delegate used by this class. The default is <code>this</code>, * assuming that handler methods have been added by a subclass. * * @param delegate * an object containing handler methods */ public final void setDelegate(final Object delegate) { this.controller = new InternalController(delegate); if (delegate != this) { this.handler = delegate; } else { this.handler = null; } } /** * Return the {@link MethodNameResolver} used by this class. * * @return the used MethodNameResolver */ public final MethodNameResolver getMethodNameResolver() { return this.controller.getMethodNameResolver(); } /** * Set the method name resolver that this class should use. Allows * parameterization of handler method mappings. * * @param resolver * the resolver - default resolver is * {@link ActionMethodNameResolver} */ public final void setMethodNameResolver(final MethodNameResolver resolver) { this.controller.setMethodNameResolver(resolver); } /** * {@inheritDoc} */ protected final ModelAndView handleRequestInternal( final HttpServletRequest request, final HttpServletResponse response) throws Exception { return this.controller.handleRequestInternal(request, response); } /** * {@inheritDoc} */ public void afterRestoreView(final FacesContext context) { PhaseListenerHelper.getInstance().afterPhase(context, this.handler, RestoreViewPhaseListener.class); } /** * {@inheritDoc} */ public void beforeRestoreView(final FacesContext context) { PhaseListenerHelper.getInstance().beforePhase(context, this.handler, RestoreViewPhaseListener.class); } /** * {@inheritDoc} */ public void afterApplyRequestValues(final FacesContext context) { PhaseListenerHelper.getInstance().afterPhase(context, this.handler, ApplyRequestValuesPhaseListener.class); } /** * {@inheritDoc} */ public void beforeApplyRequestValues(final FacesContext context) { PhaseListenerHelper.getInstance().beforePhase(context, this.handler, ApplyRequestValuesPhaseListener.class); } /** * {@inheritDoc} */ public void afterProcessValidations(final FacesContext context) { PhaseListenerHelper.getInstance().afterPhase(context, this.handler, ProcessValidationsPhaseListener.class); } /** * {@inheritDoc} */ public void beforeProcessValidations(final FacesContext context) { PhaseListenerHelper.getInstance().beforePhase(context, this.handler, ProcessValidationsPhaseListener.class); } /** * {@inheritDoc} */ public void afterUpdateModelValues(final FacesContext context) { PhaseListenerHelper.getInstance().afterPhase(context, this.handler, UpdateModelValuesPhaseListener.class); } /** * {@inheritDoc} */ public void beforeUpdateModelValues(final FacesContext context) { PhaseListenerHelper.getInstance().beforePhase(context, this.handler, UpdateModelValuesPhaseListener.class); } /** * {@inheritDoc} */ public void afterInvokeApplication(final FacesContext context) { PhaseListenerHelper.getInstance().afterPhase(context, this.handler, InvokeApplicationPhaseListener.class); } /** * {@inheritDoc} */ public void beforeInvokeApplication(final FacesContext context) { PhaseListenerHelper.getInstance().beforePhase(context, this.handler, InvokeApplicationPhaseListener.class); } /** * {@inheritDoc} */ public void afterRenderResponse(final FacesContext context) { PhaseListenerHelper.getInstance().afterPhase(context, this.handler, RenderResponsePhaseListener.class); } /** * {@inheritDoc} */ public void beforeRenderResponse(final FacesContext context) { PhaseListenerHelper.getInstance().beforePhase(context, this.handler, RenderResponsePhaseListener.class); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -