lifecycleimpl.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 573 行

JAVA
573
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.jsf.lifecycle;import com.caucho.util.*;import java.io.*;import java.util.*;import java.util.logging.*;import java.lang.reflect.*;import javax.el.*;import javax.faces.*;import javax.faces.application.*;import javax.faces.component.*;import javax.faces.context.*;import javax.faces.event.*;import javax.faces.lifecycle.*;import javax.faces.render.*;import javax.servlet.http.*;import com.caucho.config.*;import com.caucho.jsf.application.*;import com.caucho.util.*;/** * The default lifecycle implementation */public class LifecycleImpl extends Lifecycle{  private static final L10N L = new L10N(LifecycleImpl.class);  private static final Logger log    = Logger.getLogger(LifecycleImpl.class.getName());    private ArrayList<PhaseListener> _phaseList = new ArrayList<PhaseListener>();  private PhaseListener []_phaseListeners = new PhaseListener[0];    public LifecycleImpl()  {  }  public void addPhaseListener(PhaseListener listener)  {    if (listener == null)      throw new NullPointerException();        synchronized (_phaseList) {      _phaseList.add(listener);      _phaseListeners = new PhaseListener[_phaseList.size()];      _phaseList.toArray(_phaseListeners);    }  }    public PhaseListener []getPhaseListeners()  {    return _phaseListeners;  }    public void removePhaseListener(PhaseListener listener)  {    if (listener == null)      throw new NullPointerException();        synchronized (_phaseList) {      _phaseList.remove(listener);      _phaseListeners = new PhaseListener[_phaseList.size()];      _phaseList.toArray(_phaseListeners);    }  }  public void execute(FacesContext context)    throws FacesException  {    boolean isFiner = log.isLoggable(Level.FINER);        if (context.getResponseComplete() || context.getRenderResponse())      return;    beforePhase(context, PhaseId.RESTORE_VIEW);    context.setCurrentPhaseId(PhaseId.RESTORE_VIEW);    try {      if (isFiner)	log.finer("JSF[] before restore view");            restoreView(context);    } finally {      context.setCurrentPhaseId(null);      afterPhase(context, PhaseId.RESTORE_VIEW);    }    if (context.getResponseComplete() || context.getRenderResponse())      return;    UIViewRoot viewRoot = context.getViewRoot();    beforePhase(context, PhaseId.APPLY_REQUEST_VALUES);    context.setCurrentPhaseId(PhaseId.APPLY_REQUEST_VALUES);        try {      if (isFiner)	log.finer(context.getViewRoot() + " before process decodes");            viewRoot.processDecodes(context);    } finally {      context.setCurrentPhaseId(null);      afterPhase(context, PhaseId.APPLY_REQUEST_VALUES);    }    //    // Process Validations (processValidators)    //        if (context.getResponseComplete() || context.getRenderResponse())      return;        beforePhase(context, PhaseId.PROCESS_VALIDATIONS);    context.setCurrentPhaseId(PhaseId.PROCESS_VALIDATIONS);    try {      if (isFiner)	log.finer(context.getViewRoot() + " before process validators");            viewRoot.processValidators(context);    } finally {      context.setCurrentPhaseId(null);            afterPhase(context, PhaseId.PROCESS_VALIDATIONS);    }    //    // Update Model Values (processUpdates)    //        if (context.getResponseComplete() || context.getRenderResponse())      return;        beforePhase(context, PhaseId.UPDATE_MODEL_VALUES);    context.setCurrentPhaseId(PhaseId.UPDATE_MODEL_VALUES);    try {      if (isFiner)	log.finer(context.getViewRoot() + " before process updates");            viewRoot.processUpdates(context);    } catch (RuntimeException e) {      if (sendError(context, "processUpdates", e))	return;    } finally {      context.setCurrentPhaseId(null);      afterPhase(context, PhaseId.UPDATE_MODEL_VALUES);    }    //    // Invoke Application (processApplication)    //        if (context.getResponseComplete() || context.getRenderResponse())      return;        beforePhase(context, PhaseId.INVOKE_APPLICATION);    context.setCurrentPhaseId(PhaseId.INVOKE_APPLICATION);    try {      if (isFiner)	log.finer(context.getViewRoot() + " before process application");            viewRoot.processApplication(context);    } finally {      context.setCurrentPhaseId(null);            afterPhase(context, PhaseId.INVOKE_APPLICATION);    }  }  private void restoreView(FacesContext context)    throws FacesException  {    Application app = context.getApplication();    if (app instanceof ApplicationImpl)      ((ApplicationImpl) app).initRequest();        ViewHandler view = app.getViewHandler();    view.initView(context);    UIViewRoot viewRoot = context.getViewRoot();        if (viewRoot != null) {      ExternalContext extContext = context.getExternalContext();            viewRoot.setLocale(extContext.getRequestLocale());      doSetBindings(context.getELContext(), viewRoot);      return;    }    String viewId = calculateViewId(context);    String renderKitId = view.calculateRenderKitId(context);    RenderKitFactory renderKitFactory      = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);        RenderKit renderKit = renderKitFactory.getRenderKit(context, renderKitId);    ResponseStateManager stateManager = renderKit.getResponseStateManager();    if (stateManager.isPostback(context)) {      viewRoot = view.restoreView(context,  viewId);      if (viewRoot != null) {	doSetBindings(context.getELContext(), viewRoot);      }      else {	// XXX: backward compat issues with ViewHandler and StateManager		// throw new ViewExpiredException(L.l("{0} is an expired view", viewId));	context.renderResponse();      	viewRoot = view.createView(context, viewId);	context.setViewRoot(viewRoot);      }            context.setViewRoot(viewRoot);    }    else {      context.renderResponse();            viewRoot = view.createView(context, viewId);      context.setViewRoot(viewRoot);    }  }  private void doSetBindings(ELContext elContext, UIComponent component)  {    if (component == null)      return;    ValueExpression binding = component.getValueExpression("binding");    if (binding != null)      binding.setValue(elContext, component);    Iterator<UIComponent> iter = component.getFacetsAndChildren();    while (iter.hasNext())      doSetBindings(elContext, iter.next());  }  private String calculateViewId(FacesContext context)  {    return JspViewHandler.createViewId(context);  }    public void render(FacesContext context)    throws FacesException  {    if (context.getResponseComplete())      return;    Application app = context.getApplication();    ViewHandler view = app.getViewHandler();    beforePhase(context, PhaseId.RENDER_RESPONSE);    context.setCurrentPhaseId(PhaseId.RENDER_RESPONSE);    try {      if (log.isLoggable(Level.FINER))	log.finer(context.getViewRoot() + " before render view");            view.renderView(context, context.getViewRoot());    } catch (java.io.IOException e) {      if (sendError(context, "renderView", e))	return;            throw new FacesException(e);    } catch (RuntimeException e) {      if (sendError(context, "renderView", e))	return;      throw e;    } finally {      context.setCurrentPhaseId(null);      afterPhase(context, PhaseId.RENDER_RESPONSE);      logMessages(context);    }  }  private void beforePhase(FacesContext context, PhaseId phase)  {    for (int i = 0; i < _phaseListeners.length; i++) {      PhaseListener listener = _phaseListeners[i];      PhaseId id = listener.getPhaseId();      if (id == phase || id == PhaseId.ANY_PHASE) {	PhaseEvent event = new PhaseEvent(context, phase, this);	listener.beforePhase(event);      }    }  }  private void afterPhase(FacesContext context, PhaseId phase)  {    for (int i = _phaseListeners.length - 1; i >= 0; i--) {      PhaseListener listener = _phaseListeners[i];      PhaseId id = listener.getPhaseId();      if (phase == id || id == PhaseId.ANY_PHASE) {	PhaseEvent event = new PhaseEvent(context, phase, this);		listener.afterPhase(event);      }    }  }  private void logMessages(FacesContext context)  {    UIViewRoot root = context.getViewRoot();    String viewId = "";    if (root != null)      viewId = root.getViewId();    Iterator<FacesMessage> iter = context.getMessages();    while (iter != null && iter.hasNext()) {      FacesMessage msg = iter.next();      if (log.isLoggable(Level.FINE)) {	if (msg.getDetail() != null)	  log.fine(viewId + " [ " + msg.getSeverity() + "] " + msg.getSummary() + " " + msg.getDetail());	else	  log.fine(viewId + " [ " + msg.getSeverity() + "] " + msg.getSummary());      }    }  }  private boolean sendError(FacesContext context,			    String lifecycle,			    Exception e)  {    for (Throwable cause = e; cause != null; cause = cause.getCause()) {      if (cause instanceof DisplayableException) {	if (e instanceof RuntimeException)	  throw (RuntimeException) e;	else	  throw new FacesException(e);      }    }        ExternalContext extContext = context.getExternalContext();    Object response = extContext.getResponse();    if (! (response instanceof HttpServletResponse)) {      context.renderResponse();      if (e instanceof RuntimeException)	throw (RuntimeException) e;      else	throw new RuntimeException(e);    }    log.log(Level.WARNING, e.toString(), e);        HttpServletResponse res = (HttpServletResponse) response;    try {      context.renderResponse();      context.responseComplete();            res.setStatus(500, "JSF Exception");      res.setContentType("text/html");      PrintWriter out = res.getWriter();      out.println("<body>");      out.println("<h3>JSF exception detected in " + lifecycle + " phase</h3>");      String msg = e.getMessage();      out.println("<span style='color:red;font:bold'>" + Html.escapeHtml(msg) + "</span><br/>");      out.println("<h3>Context: " + context.getViewRoot() + "</h3>");      out.println("<code><pre>");      String errorId = null;            if (e instanceof FacesException && msg.startsWith("id=")) {	int p = msg.indexOf(' ');	errorId = msg.substring(3, p);      }      printComponentTree(out, errorId, context, context.getViewRoot(), 0);            out.println("</pre></code>");      if (! Alarm.isTest()) {	out.println("<h3>Stack Trace</h3>");	out.println("<pre>");	if (e.getCause() != null)	  e.getCause().printStackTrace(out);	else	  e.printStackTrace(out);	out.println("</pre>");      }            out.println("</body>");            // clear, so we don't just loop      Application app = context.getApplication();          ViewHandler view = app.getViewHandler();            UIViewRoot viewRoot = context.getViewRoot();            viewRoot = view.createView(context, viewRoot.getViewId());      context.setViewRoot(viewRoot);      view.writeState(context);      return true;    } catch (IOException e1) {      throw new RuntimeException(e);    }  }  private void printComponentTree(PrintWriter out,				  String errorId,				  FacesContext context,				  UIComponent comp,				  int depth)  {    for (int i = 0; i < depth; i++)      out.print(' ');    boolean isError = false;    if (errorId != null && errorId.equals(comp.getClientId(context))) {      isError = true;      out.print("<span style='color:red'>");    }    out.print("&lt;" + comp.getClass().getSimpleName());    if (comp.getId() != null)      out.print(" id=\"" + comp.getId() + "\"");    for (Method method : comp.getClass().getMethods()) {      if (! method.getName().startsWith("get")	  && ! method.getName().startsWith("is"))	continue;      else if (method.getParameterTypes().length != 0)	continue;      String name;      if (method.getName().startsWith("get"))	name = method.getName().substring(3);      else if (method.getName().startsWith("is"))	name = method.getName().substring(2);      else	continue;      // XXX: getURL      name = Character.toLowerCase(name.charAt(0)) + name.substring(1);            ValueExpression expr = comp.getValueExpression(name);      Class type = method.getReturnType();      if (expr != null) {	out.print(" " + name + "=\"" + expr.getExpressionString() + "\"");      }      else if (method.getDeclaringClass().equals(UIComponent.class)	       || method.getDeclaringClass().equals(UIComponentBase.class)) {      }      else if (name.equals("family")) {      }      else if (String.class.equals(type)) {	try {	  Object value = method.invoke(comp);	  if (value != null)	    out.print(" " + name + "=\"" + value + "\"");	} catch (Exception e) {	}      }    }    int facetCount = comp.getFacetCount();    int childCount = comp.getChildCount();    if (facetCount == 0 && childCount == 0) {      out.print("/>");      if (isError)	out.print("</span>");      out.println();      return;    }    out.println(">");    if (isError)      out.print("</span>");    for (int i = 0; i < childCount; i++) {      printComponentTree(out, errorId, context,			 comp.getChildren().get(i), depth + 1);    }        for (int i = 0; i < depth; i++)      out.print(' ');    if (isError)      out.print("<span style='color:red'>");        out.println("&lt;/" + comp.getClass().getSimpleName() + ">");    if (isError)      out.print("</span>");  }  public String toString()  {    return "DefaultLifecycleImpl[]";  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?