Author: craigmcc Date: Thu Feb 10 20:01:08 2005 New Revision: 153339 URL: http://svn.apache.org/viewcvs?view=rev&rev=153339 Log: Correct the place at which subview-related ViewController instances are instantiated and their callback methods called. Now, subviews that are nested inside an <s:subview> component (or the equivalent for non-JSP presentation technologies) get the same ViewController services that the ViewController corresponding to an entire view receives.
Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/component/Subview.java Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/component/Subview.java URL: http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/component/Subview.java?view=diff&r1=153338&r2=153339 ============================================================================== --- struts/shale/trunk/core-library/src/java/org/apache/shale/component/Subview.java (original) +++ struts/shale/trunk/core-library/src/java/org/apache/shale/component/Subview.java Thu Feb 10 20:01:08 2005 @@ -22,6 +22,7 @@ import java.util.Map; import javax.faces.component.UIComponent; import javax.faces.component.UINamingContainer; +import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.event.PhaseId; import org.apache.commons.logging.Log; @@ -62,82 +63,104 @@ /** - * <p>In addition to the standard processing, provide subview initialization - * functionality, equivalent to what [EMAIL PROTECTED] ShaleViewHandler} does for - * standard views, to the enclosed subview. The <code>id</code> property - * of this component is assumed to be the name of the managed bean which is - * the corresponding [EMAIL PROTECTED] ViewController} we should instantiate.</p> + * <p>Prior to the standard processing, call the <code>prerender()</code> + * callback on the [EMAIL PROTECTED] ViewController} associated with this subview, + * if any.</p> * - * <p><strong>FIXME</strong> - Figure out some more elegant way to - * establish that relationship.</p> - * - * @param parent New parent <code>UIComponent</code>, or <code>null</code> - * if the parentage of this component is being removed + * @param context <code>FacesContext</code> for the current request */ - public void setParent(UIComponent parent) { + public void encodeBegin(FacesContext context) { - // Perform standard parentage processing - super.setParent(parent); - if (parent == null) { - if (log.isDebugEnabled()) { - log.debug("setParent(null) for id='" + getId() + "'"); - } - return; + ViewController vc = getViewController(context, false); + if (vc != null) { + vc.prerender(); } - if (log.isDebugEnabled()) { - log.debug("setParent(" + parent.getId() + ") for id='" + getId() + "'"); + super.processDecodes(context); + + } + + + /** + * <p>Prior to the standard processing, call the <code>preprocess()</code> + * callback on the [EMAIL PROTECTED] ViewController} associated with this subview, + * if any.</p> + * + * @param context <code>FacesContext</code> for the current request + */ + public void processDecodes(FacesContext context) { + + ViewController vc = getViewController(context, true); + if (vc != null) { + vc.preprocess(); } + super.processDecodes(context); - // Identify the current phase identifier - FacesContext context = FacesContext.getCurrentInstance(); - PhaseId phaseId = (PhaseId) - context.getExternalContext().getRequestMap().get(ShalePhaseListener.PHASE_ID); - if (phaseId == null) { - if (Beans.isDesignTime()) { // i.e. we are inside a tool - phaseId = PhaseId.RENDER_RESPONSE; // so assume Render Response - } else { - log.warn(messages.getMessage("subview.noPhase")); - return; - } + } + + + // --------------------------------------------------------- Private Methods + + + /** + * <p>Return the [EMAIL PROTECTED] ViewController} associated with this component, + * if any; otherwise, return <code>null</code>. If a new instance was + * created, register it (so that <code>destroy()</code> will ultimately + * be called), and call its <code>init()</code> callback method, + * before returning.</p> + * + * @param context <code>FacesContext</code> for the current request + * @param postback Are we processing a postback? + */ + private ViewController getViewController(FacesContext context, + boolean postback) { + + // If there is an existing ViewController instance, return it + // FIXME - different exception for class cast problems? + String name = getId(); // Name of the managed bean we are looking for + ExternalContext econtext = context.getExternalContext(); + ViewController vc = null; + vc = (ViewController) econtext.getRequestMap().get(name); + if (vc == null) { + vc = (ViewController) econtext.getSessionMap().get(name); } - if (log.isTraceEnabled()) { - log.trace(" Current phase is " + phaseId); + if (vc == null) { + vc = (ViewController) econtext.getApplicationMap().get(name); + } + if (vc != null) { + return vc; } - // Cause the ViewController for our subview to be instantiated - ViewController vc = null; - String expr = "#{" + getId() + "}"; + // Construct and initialize a new ViewController, if any is associated + String expr = "#{" + name + "}"; try { - vc = (ViewController) context.getApplication().createValueBinding(expr). - getValue(context); + vc = (ViewController) context.getApplication(). + createValueBinding(expr).getValue(context); if (vc == null) { log.warn(messages.getMessage("subview.noBean", new Object[] { getId() })); - return; + return null; } } catch (ClassCastException e) { log.error(messages.getMessage("subview.noType", new Object[] { getId() })); - return; + return null; } // Initialize the ViewController as needed - vc.setPostBack(!PhaseId.RENDER_RESPONSE.equals(phaseId)); + vc.setPostBack(postback); vc.init(); - if (vc.isPostBack()) { - vc.preprocess(); - } else { - vc.prerender(); - } // Schedule this instance for later processing as needed - Map map = context.getExternalContext().getRequestMap(); + Map map = econtext.getRequestMap(); List list = (List) map.get(ShaleConstants.VIEWS_INITIALIZED); if (list == null) { list = new ArrayList(); map.put(ShaleConstants.VIEWS_INITIALIZED, list); } list.add(vc); + + // Return the initialized ViewController + return vc; } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]