Author: craigmcc Date: Fri Jun 30 16:01:22 2006 New Revision: 418411 URL: http://svn.apache.org/viewvc?rev=418411&view=rev Log: SHALE-198 -- Remove incompatibility between <s:subview> component and view controllers using the Tiger Extensions @View annotation, rather than implementing the ViewController interface directly.
Modified: struts/shale/trunk/shale-core/src/main/java/org/apache/shale/component/Subview.java Modified: struts/shale/trunk/shale-core/src/main/java/org/apache/shale/component/Subview.java URL: http://svn.apache.org/viewvc/struts/shale/trunk/shale-core/src/main/java/org/apache/shale/component/Subview.java?rev=418411&r1=418410&r2=418411&view=diff ============================================================================== --- struts/shale/trunk/shale-core/src/main/java/org/apache/shale/component/Subview.java (original) +++ struts/shale/trunk/shale-core/src/main/java/org/apache/shale/component/Subview.java Fri Jun 30 16:01:22 2006 @@ -29,7 +29,9 @@ import org.apache.shale.util.Messages; import org.apache.shale.view.Constants; import org.apache.shale.view.ViewController; +import org.apache.shale.view.faces.CallbacksFactory; import org.apache.shale.view.faces.ExceptionHandlerFactory; +import org.apache.shale.view.faces.ViewControllerCallbacks; /** * <p>Specialized implementation of <code>UINamingContainer</code> that @@ -69,10 +71,10 @@ */ public void encodeBegin(FacesContext context) { - ViewController vc = getViewController(context, false); + Object vc = getViewController(context, false); if (vc != null) { try { - vc.prerender(); + getViewControllerCallbacks(context).prerender(vc); } catch (Exception e) { handleException(e); } @@ -91,10 +93,10 @@ */ public void processDecodes(FacesContext context) { - ViewController vc = getViewController(context, true); + Object vc = getViewController(context, true); if (vc != null) { try { - vc.preprocess(); + getViewControllerCallbacks(context).preprocess(vc); } catch (Exception e) { handleException(e); } @@ -109,28 +111,28 @@ /** * <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> + * if any; otherwise, return <code>null</code>. Note that the signature + * for this method is <code>Object</code>, because the instance might + * have the <code>@View</code> annotation rather than implementing the + * <code>ViewController</code> interface.</p> * * @param context <code>FacesContext</code> for the current request * @param postback Are we processing a postback? */ - private ViewController getViewController(FacesContext context, - boolean postback) { + private Object 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); + Object vc = null; + vc = econtext.getRequestMap().get(name); if (vc == null) { - vc = (ViewController) econtext.getSessionMap().get(name); + vc = econtext.getSessionMap().get(name); } if (vc == null) { - vc = (ViewController) econtext.getApplicationMap().get(name); + vc = econtext.getApplicationMap().get(name); } if (vc != null) { return vc; @@ -138,23 +140,18 @@ // Construct and initialize a new ViewController, if any is associated String expr = "#{" + name + "}"; - try { - vc = (ViewController) context.getApplication(). - createValueBinding(expr).getValue(context); - if (vc == null) { - log.debug(messages.getMessage("subview.noBean", - new Object[] { getId() })); - return null; - } - } catch (ClassCastException e) { - log.error(messages.getMessage("subview.noType", + vc = context.getApplication(). + createValueBinding(expr).getValue(context); + if (vc == null) { + log.debug(messages.getMessage("subview.noBean", new Object[] { getId() })); return null; } // Initialize the ViewController as needed - vc.setPostBack(postback); -// vc.init(); + if (vc instanceof ViewController) { + ((ViewController) vc).setPostBack(postback); + } // Schedule this instance for later processing as needed Map map = econtext.getRequestMap(); @@ -167,6 +164,39 @@ // Return the initialized ViewController return vc; + + } + + + /** + * <p>Lazily cached <code>ViewControllerCallbacks</code> instance.</p> + */ + private transient ViewControllerCallbacks viewControllerCallbacks = null; + + + /** + * <p>Return the <code>ViewControllerCallbacks</code. instance to be used + * to forward prerender and preprocess callbacks to our view controller, + * whether or not it implements the <code>ViewController</code. interface + * (it may not if it is using the <code>@View</code> annotation from the + * shale-tiger module).</p> + * + * @param context <code>FacesContext</code> for the current request + */ + private ViewControllerCallbacks getViewControllerCallbacks(FacesContext context) { + + if (viewControllerCallbacks == null) { + viewControllerCallbacks = (ViewControllerCallbacks) + context.getExternalContext().getApplicationMap(). + get(Constants.VIEW_CALLBACKS); + if (viewControllerCallbacks == null) { + viewControllerCallbacks = + CallbacksFactory.getInstance().getViewControllerCallbacks(); + context.getExternalContext().getApplicationMap(). + put(Constants.VIEW_CALLBACKS, viewControllerCallbacks); + } + } + return viewControllerCallbacks; }