Author: craigmcc
Date: Tue Feb  8 20:28:23 2005
New Revision: 152994

URL: http://svn.apache.org/viewcvs?view=rev&rev=152994
Log:
Checkpoint checkin of initial ViewController support for subviews.  As will be
evident from the corresponding checkin on the use-cases example app (upcoming),
there are still some outstanding FIXME issues, including:

* Triggering init() and preprocess() on a postback

* Also triggering prerender() on a postback when the
  same page is redisplayed

To support this functionality, you must use the Shale <s:subview> component
instead of the standard JSF <f:subview> component.


Added:
    
struts/shale/trunk/core-library/src/java/org/apache/shale/component/Subview.java
    
struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/SubviewTag.java
Modified:
    struts/shale/trunk/core-library/src/conf/faces-config.xml
    struts/shale/trunk/core-library/src/conf/taglib.tld
    struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties
    
struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShalePhaseListener.java

Modified: struts/shale/trunk/core-library/src/conf/faces-config.xml
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/conf/faces-config.xml?view=diff&r1=152993&r2=152994
==============================================================================
--- struts/shale/trunk/core-library/src/conf/faces-config.xml (original)
+++ struts/shale/trunk/core-library/src/conf/faces-config.xml Tue Feb  8 
20:28:23 2005
@@ -42,6 +42,17 @@
   <!-- Custom Components -->
   <component>
     <description>
+      The "Subview" component performs the same services provided by the
+      "subview" tag in the JSF Core Tag Library, plus it provides
+      ViewController event callback services for the ViewController
+      whose managed bean name is the same as the "id" value of this component.
+    </description>
+    <display-name>Subview</display-name>
+    <component-type>org.apache.shale.Subview</component-type>
+    <component-class>org.apache.shale.component.Subview</component-class>
+  </component>
+  <component>
+    <description>
       The "Token" component emits a transactional token that is then
       validated (on a subsequent form submit) to catch cases where the
       same form was submitted more than once.

Modified: struts/shale/trunk/core-library/src/conf/taglib.tld
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/conf/taglib.tld?view=diff&r1=152993&r2=152994
==============================================================================
--- struts/shale/trunk/core-library/src/conf/taglib.tld (original)
+++ struts/shale/trunk/core-library/src/conf/taglib.tld Tue Feb  8 20:28:23 2005
@@ -39,6 +39,55 @@
 
   <tag>
 
+    <name>subview</name>
+    <tag-class>org.apache.shale.taglib.SubviewTag</tag-class>
+    <body-content>JSP</body-content>
+    <display-name>Subview</display-name>
+    <description>
+      Provide ViewController support functionality for the nested content
+      (typically a JSP dynamic include) of this component.
+    </description>
+
+    <!-- Custom -->
+
+    <!-- JSF -->
+
+    <attribute>
+      <name>binding</name>
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        Value binding expression used to bind this component instance
+        to a backing bean property.
+      </description>
+    </attribute>
+
+    <attribute>
+      <name>id</name>
+      <required>trie</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        Component identifier of this component.  If specified, this identifier
+        must be unique within the context of the closest parent UIComponent
+        that is a NamingContainer.
+      </description>
+    </attribute>
+
+    <attribute>
+      <name>rendered</name>
+      <required>false</required>
+      <rtexprvalue>false</rtexprvalue>
+      <description>
+        Flag indicating whether this component should be rendered.
+        Default value is true.
+      </description>
+    </attribute>
+
+  </tag>
+
+
+  <tag>
+
     <name>token</name>
     <tag-class>org.apache.shale.taglib.TokenTag</tag-class>
     <body-content>empty</body-content>

Modified: 
struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties?view=diff&r1=152993&r2=152994
==============================================================================
--- struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties 
(original)
+++ struts/shale/trunk/core-library/src/java/org/apache/shale/Bundle.properties 
Tue Feb  8 20:28:23 2005
@@ -35,6 +35,11 @@
 context.requestWrapper=Must be an HttpServletRequestWrapper
 context.responseWrapper=Must be an HttpServletResponseWrapper
 
+# org.apache.shale.component.Subview
+subview.noBean=No managed bean for subview {0}
+subview.noPhase=Not currently in a JSF phase, so no subview support provided
+subview.noType=Managed bean for subview {0} is not a ViewController
+
 # org.apache.shale.component.Token
 token.invalid=Invalid resubmit of the same form
 

Added: 
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=auto&rev=152994
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/component/Subview.java
 (added)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/component/Subview.java
 Tue Feb  8 20:28:23 2005
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * 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 org.apache.shale.component;
+
+import java.beans.Beans;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UINamingContainer;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shale.ViewController;
+import org.apache.shale.faces.ShaleConstants;
+import org.apache.shale.faces.ShalePhaseListener;
+import org.apache.shale.faces.ShaleViewHandler;
+import org.apache.shale.util.Messages;
+
+/**
+ * <p>Specialized implementation of <code>UINamingContainer</code> that
+ * provides [EMAIL PROTECTED] ViewController} functionality for subviews.</p>
+ *
+ * $Id$
+ */
+public class Subview extends UINamingContainer {
+    
+    
+    // -------------------------------------------------------- Static 
Variables
+
+    
+    /**
+     * <p>Log instance for this class.</p>
+     */
+    private static final Log log = LogFactory.getLog(Subview.class);
+
+
+    /**
+     * <p>Message resources for this class.</p>
+     */
+    private static Messages messages =
+      new Messages("org.apache.shale.Bundle",
+                   Subview.class.getClassLoader());
+
+
+    // ----------------------------------------------------- UIComponent 
Methods
+
+
+    /**
+     * <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><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
+     */
+    public void setParent(UIComponent parent) {
+
+        // Perform standard parentage processing
+        super.setParent(parent);
+        if (parent == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("setParent(null) for id='" + getId() + "'");
+            }
+            return;
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("setParent(" + parent.getId() + ") for id='" + getId() + 
"'");
+        }
+
+        // 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;
+            }
+        }
+        if (log.isTraceEnabled()) {
+            log.trace("  Current phase is " + phaseId);
+        }
+
+        // Cause the ViewController for our subview to be instantiated
+        ViewController vc = null;
+        String expr = "#{" + getId() + "}";
+        try {
+            vc = (ViewController) 
context.getApplication().createValueBinding(expr).
+                 getValue(context);
+            if (vc == null) {
+                log.warn(messages.getMessage("subview.noBean",
+                                             new Object[] { getId() }));
+                return;
+            }
+        } catch (ClassCastException e) {
+            log.error(messages.getMessage("subview.noType",
+                                          new Object[] { getId() }));
+            return;
+        }
+
+        // Initialize the ViewController as needed
+        vc.setPostBack(!PhaseId.RENDER_RESPONSE.equals(phaseId));
+        vc.init();
+        if (vc.isPostBack()) {
+            vc.preprocess();
+        } else {
+            vc.prerender();
+        }
+
+        // Schedule this instance for later processing as needed
+        Map map = context.getExternalContext().getRequestMap();
+        List list = (List) map.get(ShaleConstants.VIEWS_INITIALIZED);
+        if (list == null) {
+            list = new ArrayList();
+            map.put(ShaleConstants.VIEWS_INITIALIZED, list);
+        }
+        list.add(vc);
+
+    }
+
+
+}

Modified: 
struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShalePhaseListener.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShalePhaseListener.java?view=diff&r1=152993&r2=152994
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShalePhaseListener.java
 (original)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/faces/ShalePhaseListener.java
 Tue Feb  8 20:28:23 2005
@@ -46,6 +46,13 @@
     private static final Log log = LogFactory.getLog(ShalePhaseListener.class);
 
 
+    /**
+     * <p>Request scope attribute under which the [EMAIL PROTECTED] PhaseId} 
for the
+     * current phase is exposed.</p>
+     */
+    public static final String PHASE_ID = "org.apache.shale.faces.PHASE_ID";
+
+
     // --------------------------------------------------- PhaseListener 
Methods
 
 
@@ -67,6 +74,7 @@
         } else if (PhaseId.RENDER_RESPONSE.equals(phaseId)) {
             afterRenderResponse(event);
         }
+        
event.getFacesContext().getExternalContext().getRequestMap().remove(PHASE_ID);
 
     }
 
@@ -84,6 +92,7 @@
                       "," + event.getPhaseId() + ")");
         }
         PhaseId phaseId = event.getPhaseId();
+        
event.getFacesContext().getExternalContext().getRequestMap().put(PHASE_ID, 
phaseId);
         if (PhaseId.RENDER_RESPONSE.equals(phaseId)) {
             beforeRenderResponse(event);
         }

Added: 
struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/SubviewTag.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/SubviewTag.java?view=auto&rev=152994
==============================================================================
--- 
struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/SubviewTag.java
 (added)
+++ 
struts/shale/trunk/core-library/src/java/org/apache/shale/taglib/SubviewTag.java
 Tue Feb  8 20:28:23 2005
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * 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 org.apache.shale.taglib;
+
+import javax.faces.webapp.UIComponentTag;
+import org.apache.shale.component.Token;
+
+/**
+ * <p>JSP custom tag for the [EMAIL PROTECTED] Subview} component.</p>
+ *
+ * $Id$
+ */
+public class SubviewTag extends UIComponentTag {
+    
+
+    /**
+     * <p>Return the required component type.</p>
+     */
+    public String getComponentType() {
+        return "org.apache.shale.Subview";
+    }
+
+
+    /**
+     * <p>Return the required renderer type.</p>
+     */
+    public String getRendererType() {
+        return null;
+    }
+
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to