You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by cr...@apache.org on 2006/07/01 01:01:22 UTC

svn commit: r418411 - /struts/shale/trunk/shale-core/src/main/java/org/apache/shale/component/Subview.java

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 {@link 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;
 
     }