📄 lifecycleexecutor.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;import java.util.Map;import javax.faces.FacesException;import javax.faces.FactoryFinder;import javax.faces.component.ActionSource;import javax.faces.context.ExternalContext;import javax.faces.context.FacesContext;import javax.faces.el.MethodBinding;import javax.faces.event.AbortProcessingException;import javax.faces.event.ActionEvent;import javax.faces.event.ActionListener;import javax.faces.lifecycle.Lifecycle;import javax.faces.lifecycle.LifecycleFactory;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.util.Assert;import org.springframework.web.servlet.HandlerAdapter;import org.springframework.web.servlet.ModelAndView;import de.mindmatters.faces.application.DelegatingActionListener;import de.mindmatters.faces.lifecycle.LifecycleImpl;/** * <strong>{@link HandlerAdapter}</strong> implementation that delegates it's * work to any given arbitrary HandlerAdapter and integrates it into the * workflow of the request processing of the underliying JSF implementation. * * @author Andreas Kuhrwahl * @see Lifecycle#execute(FacesContext) * */public final class LifecycleExecutor implements HandlerAdapter { /** The request key of the executing handler. */ private static final String HANDLER = LifecycleExecutor.class.getName() + "#Handler"; /** * <strong>ActionListener</strong> which delegates it's processing to the * internal wrapped {@link HandlerAdapter}. * * @author Andreas Kuhrwahl * */ private class HandlerAdaptingActionListener implements ActionListener { /** The handler processing the request. */ private final Object handler; /** * The {@link ModelAndView} created by * {@link HandlerAdapter#handle(HttpServletRequest, HttpServletResponse, Object)}. */ private ModelAndView modelAndView; /** The FacesContext. */ private final FacesContext context; /** Is the request processed? */ private boolean actionProcessed = false; /** * Creates the ActionListener. * * @param handler * Handler to use * @param context * {@link FacesContext} for the current request */ public HandlerAdaptingActionListener(final Object handler, final FacesContext context) { this.handler = handler; this.context = context; } /** * {@inheritDoc} */ public void processAction(final ActionEvent event) { ExternalContext externalContext = this.context.getExternalContext(); try { if (event.getComponent() instanceof ActionSource) { ActionSource actionSource = (ActionSource) event .getComponent(); MethodBinding mb = actionSource.getAction(); if (mb != null) { String expression = mb.getExpressionString(); if (expression == null) { expression = (String) mb.invoke(this.context, null); } log.warn("Method-binding '" + expression + "' might be ignored."); } } this.modelAndView = LifecycleExecutor.this.internalHandlerAdapter .handle((HttpServletRequest) externalContext .getRequest(), (HttpServletResponse) externalContext .getResponse(), handler); this.actionProcessed = true; } catch (Exception ex) { if (ex instanceof AbortProcessingException) { throw (AbortProcessingException) ex; } else if (ex instanceof FacesException) { if (ex.getCause() instanceof AbortProcessingException) { throw (AbortProcessingException) ex.getCause(); } throw (FacesException) ex; } else { throw new FacesException(ex.getMessage(), ex); } } } /** * @return object with the name of the view and the required model data, * or <code>null</code> if the request has been handled * directly */ public ModelAndView getModelAndView() { if (!this.actionProcessed) { this.modelAndView = new ModelAndView(this.context.getViewRoot() .getViewId()); } return this.modelAndView; } } /** The given arbitrary HandlerAdapter. */ private final HandlerAdapter internalHandlerAdapter; /** The lifecycle this adapter integrates into. */ private final Lifecycle lifecycle; /** For logging. */ protected final Log log = LogFactory.getLog(this.getClass()); /** * Creates a LifecycleExecutor with the given internal * {@link HandlerAdapter} <code>internalHandlerAdapter</code>. * * @param internalHandlerAdapter * The arbitrary HandlerAdapter which is decorated an integrated * in the faces lifecycle */ public LifecycleExecutor(final HandlerAdapter internalHandlerAdapter) { this(internalHandlerAdapter, LifecycleImpl.JSF_SPRING_LIFECYCLE_ID); } /** * Creates a LifecycleExecutor with the given internal * {@link HandlerAdapter} <code>internalHandlerAdapter</code>. * * @param internalHandlerAdapter * The arbitrary HandlerAdapter which is decorated an integrated * in the faces lifecycle * @param lifecycleId * the lifecycle id for identifying the proper lifecycle this * adapter will use for integration purposes */ public LifecycleExecutor(final HandlerAdapter internalHandlerAdapter, final String lifecycleId) { super(); Assert.notNull(internalHandlerAdapter); this.internalHandlerAdapter = internalHandlerAdapter; this.lifecycle = ((LifecycleFactory) FactoryFinder .getFactory(FactoryFinder.LIFECYCLE_FACTORY)) .getLifecycle(lifecycleId); } /** * Associate the given Handler with the current thread. * * @param context * {@link FacesContext} for the current request * @param handler * the current Handler */ static void bindHandler(final FacesContext context, final Object handler) { Assert.notNull(context); Assert.notNull(handler); Map requestMap = context.getExternalContext().getRequestMap(); Assert.isNull(requestMap.get(HANDLER)); requestMap.put(HANDLER, handler); } /** * Unbind the Handler with the current thread. * * @param context * {@link FacesContext} for the current request * @return the formerly associated Handler */ static Object unbindHandler(final FacesContext context) { Assert.notNull(context); return context.getExternalContext().getRequestMap().remove(HANDLER); } /** * Returns the current Handler from the current thread. * * @param context * {@link FacesContext} for the current request * @return the current Handler */ public static Object getHandler(final FacesContext context) { Assert.notNull(context); return context.getExternalContext().getRequestMap().get(HANDLER); } /** * {@inheritDoc} */ public boolean supports(final Object handler) { return this.internalHandlerAdapter.supports(handler); } /** * {@inheritDoc} */ public long getLastModified(final HttpServletRequest request, final Object handler) { return this.internalHandlerAdapter.getLastModified(request, handler); } /** * {@inheritDoc} */ public ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) throws Exception { FacesContext context = FacesContext.getCurrentInstance(); Assert.notNull(context); try { bindHandler(context, handler); HandlerAdaptingActionListener actionListener = new HandlerAdaptingActionListener( handler, context); DelegatingActionListener .bindActionListener(context, actionListener); this.lifecycle.execute(context); return actionListener.getModelAndView(); } catch (Exception ex) { unbindHandler(context); throw ex; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -