dev@javaserverfaces.java.net

Re: seeking review 1663

From: Sheetal Vartak <sheetal.vartak_at_oracle.com>
Date: Fri, 27 Aug 2010 10:34:06 -0700

Hi Ed and Jason,
Thanks for your comments. Attaching the changes incorporated with the feedback.
Please review.

Thanks
Sheetal

issue 1663.

Changed files :

M jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/ComponentSupport.java
M jsf-ri/src/main/java/com/sun/faces/util/MessageUtils.java
M jsf-ri/src/main/resources/com/sun/faces/resources/Messages.properties

diffs :

Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/ComponentSupport.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/ComponentSupport.java (revision 8578)
+++ jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/ComponentSupport.java (working copy)
@@ -56,15 +56,20 @@
 
 import com.sun.faces.context.StateContext;
 import com.sun.faces.facelets.tag.jsf.core.FacetHandler;
+import com.sun.faces.util.MessageUtils;
 
 import javax.faces.FacesException;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIPanel;
 import javax.faces.component.UIViewRoot;
+import javax.faces.component.html.HtmlForm;
+import javax.faces.application.ProjectStage;
 import javax.faces.context.FacesContext;
 import javax.faces.view.facelets.FaceletContext;
 import javax.faces.view.facelets.TagAttribute;
 import javax.faces.view.facelets.TagAttributeException;
+import javax.faces.application.FacesMessage;
+
 import java.io.IOException;
 import java.util.Collection;
 import java.util.HashMap;
@@ -398,6 +403,45 @@
             }
         }
     }
+
+ /**
+ * method to inspect what interfaces the component implements.
+ * if one of the interfaces is ActionSource, ActionSource2 or EditableValueHolder
+ * then that component needs to be wrapped inside an HtmlForm.
+ * @param interfaces
+ * @return
+ */
+
+ private static boolean inspectInterfaces(Class[] interfaces) {
+ for (int i = 0; i < interfaces.length; i++) {
+ String name = interfaces[i].getName();
+
+ if (name.equals("javax.faces.component.ActionSource") ||
+ name.equals("javax.faces.component.ActionSource2") ||
+ name.equals("javax.faces.component.EditableValueHolder")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * method to inspect of the the parent ancestry of the component
+ * contains HtmlForm as one of the ancestors.
+ * @param component
+ * @return true of HtmlForm is one of the ancestors
+ */
+
+ private static boolean inspectParentAncestry(UIComponent component) {
+
+ do {
+ if (component instanceof HtmlForm) {
+ return true;
+ }
+ component = component.getParent();
+ } while (!(component instanceof UIViewRoot));
+ return false;
+ }
     
     /**
      * <p class="changed_added_2_0">Add the child component to the parent. If the parent is a facet,
@@ -406,7 +450,25 @@
      * does not yet exist, make the child the facet.</p>
      */
     public static void addComponent(FaceletContext ctx, UIComponent parent, UIComponent child) {
-
+
+ //fix for issue 1663. to be executed only if in dev mode
+ if (ctx.getFacesContext().isProjectStage(ProjectStage.Development)) {
+ Class[] interfaces = child.getClass().getInterfaces();
+ if (inspectInterfaces(interfaces)) {
+ //child component implements ActionSource/ActionSource2
+ //or EditableValueHolder
+ //now make sure that there is a HtmlForm in the ancestry
+ if (!inspectParentAncestry(parent)) {
+ //no HtmlForm in the ancestry of the child
+ String key = MessageUtils.FORM_OMITTED_FOR_ACTIONSOURCE;
+ Object[] params = new Object[]{};
+
+ FacesMessage m = MessageUtils.getExceptionMessage(key, params);
+ m.setSeverity(FacesMessage.SEVERITY_WARN);
+ ctx.getFacesContext().addMessage(null, m);
+ }
+ }
+ }
         String facetName = getFacetName(parent);
         if (facetName == null) {
             parent.getChildren().add(child);
Index: jsf-ri/src/main/java/com/sun/faces/util/MessageUtils.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/util/MessageUtils.java (revision 8578)
+++ jsf-ri/src/main/java/com/sun/faces/util/MessageUtils.java (working copy)
@@ -334,8 +334,9 @@
             "com.sun.faces.MISSING_COMPONENT_FACET";
     public static final String MISSING_COMPONENT_METADATA =
             "com.sun.faces.MISSING_COMPONENT_METADATA";
+ public static final String FORM_OMITTED_FOR_ACTIONSOURCE =
+ "com.sun.faces.FORM_OMITTED_FOR_ACTIONSOURCE";
 
-
     // ------------------------------------------------------------ Constructors
 
 
Index: jsf-ri/src/main/resources/com/sun/faces/resources/Messages.properties
===================================================================
--- jsf-ri/src/main/resources/com/sun/faces/resources/Messages.properties (revision 8578)
+++ jsf-ri/src/main/resources/com/sun/faces/resources/Messages.properties (working copy)
@@ -180,3 +180,4 @@
 com.sun.faces.MISSING_COMPONENT_ATTRIBUTE_VALUE=The following attribute(s) are required, but no values have been supplied for them: ''{0}''.
 com.sun.faces.MISSING_COMPONENT_FACET=The following facets(s) are required, but no facets have been supplied for them: ''{0}''.
 com.sun.faces.MISSING_COMPONENT_METADATA=The composite component metadata for component with clientid ''{0}'' cannot be found.
+com.sun.faces.FORM_OMITTED_FOR_ACTIONSOURCE=The button/link component needs to have a Form in its ancestry. Please add <h:form>.



On Aug 26, 2010, at 6:19 PM, Jason Lee wrote:

> +1
>
> On 8/26/10 8:19 PM, Ed Burns wrote:
>>>>>>> On Thu, 26 Aug 2010 19:16:02 -0500, Jason Lee<jason_at_steeplesoft.com> said:
>> JL> I think checking for a parent of UIViewRoot, while helpful, isn't
>> JL> sufficient. I think you hit on the issue with your UIPanel question. I
>> JL> think, then, you'd almost have to walk up the tree until you find either
>> JL> UIViewRoot or a UIForm. The value fro
>> JL> com.sun.faces.MISSING_FORM_FOR_BUTTON should be updated to reflect that
>> JL> the immediate parent need not be the UIForm.
>>
>> JL> There's also no check to make sure the user is in development mode.
>> JL> This is certain to be expensive, so this shouldn't be done for a
>> JL> production app (which the issue's initial comment suggests).
>>
>> I would like it to be the case that if you have any ui components that
>> implement ActionSource, ActionSource2, or EditableValueHolder that are
>> not enclosed within a UIForm, then you get the error message.
>>
>> Furthermore, I would like this feature to take effect only if
>> ProjectStage == Development. If ProjectStage is not Development, there
>> must be no runtime performance penalty of any kind, other than checking
>> the ProjectStage, to support this feature.
>>
>> Ed
>>
>
>
> --
> Jason Lee
> Senior Member of Technical Staff at Oracle
> http://blogs.steeplesoft.com
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_javaserverfaces.dev.java.net
> For additional commands, e-mail: dev-help_at_javaserverfaces.dev.java.net
>