You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ja...@apache.org on 2010/12/02 12:07:21 UTC

svn commit: r1041329 - in /myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html: HtmlLinkRendererBase.java HtmlOutcomeTargetButtonRendererBase.java HtmlRendererUtils.java

Author: jakobk
Date: Thu Dec  2 11:07:21 2010
New Revision: 1041329

URL: http://svn.apache.org/viewvc?rev=1041329&view=rev
Log:
MYFACES-2991 NPE from rendering button with missing resource URL (apply null-href handling from h:link also to h:button and log a warning if no href could be determined)

Thanks to David Jencks for the initial patch to this issue.

Modified:
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java?rev=1041329&r1=1041328&r2=1041329&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java Thu Dec  2 11:07:21 2010
@@ -796,7 +796,7 @@ public abstract class HtmlLinkRendererBa
         Map<String, List<ClientBehavior>> behaviors = null;
         
         //calculate href
-        String targetHref = HtmlRendererUtils.getOutcomeTargetLinkHref (facesContext, output);
+        String targetHref = HtmlRendererUtils.getOutcomeTargetHref(facesContext, output);
         
         if (HtmlRendererUtils.isDisabled(output) || targetHref == null)
         {

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java?rev=1041329&r1=1041328&r2=1041329&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java Thu Dec  2 11:07:21 2010
@@ -71,61 +71,54 @@ public class HtmlOutcomeTargetButtonRend
 
         writer.startElement(HTML.INPUT_ELEM, uiComponent);
 
-        writer.writeAttribute(HTML.ID_ATTR, clientId,
-                org.apache.myfaces.shared.renderkit.JSFAttr.ID_ATTR);
+        writer.writeAttribute(HTML.ID_ATTR, clientId, JSFAttr.ID_ATTR);
         writer.writeAttribute(HTML.NAME_ATTR, clientId, JSFAttr.ID_ATTR);
 
         String image = getImage(uiComponent);
-
         ExternalContext externalContext = facesContext.getExternalContext();
 
         if (image != null)
         {
-            writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_IMAGE,
-                    org.apache.myfaces.shared.renderkit.JSFAttr.TYPE_ATTR);
-            String src = facesContext.getApplication().getViewHandler()
-                    .getResourceURL(facesContext, image);
-            writer.writeURIAttribute(HTML.SRC_ATTR, externalContext
-                    .encodeResourceURL(src),
-                    org.apache.myfaces.shared.renderkit.JSFAttr.IMAGE_ATTR);
+            // type="image"
+            writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_IMAGE, JSFAttr.TYPE_ATTR);
+            String src = facesContext.getApplication().getViewHandler().getResourceURL(facesContext, image);
+            writer.writeURIAttribute(HTML.SRC_ATTR, externalContext.encodeResourceURL(src), JSFAttr.IMAGE_ATTR);
         }
         else
         {
-            writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_BUTTON,
-                    org.apache.myfaces.shared.renderkit.JSFAttr.TYPE_ATTR);
-            Object value = org.apache.myfaces.shared.renderkit.RendererUtils
-                    .getStringValue(facesContext, uiComponent);
+            // type="button"
+            writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_BUTTON, JSFAttr.TYPE_ATTR);
+            Object value = RendererUtils.getStringValue(facesContext, uiComponent);
             if (value != null)
             {
-                writer
-                        .writeAttribute(
-                                org.apache.myfaces.shared.renderkit.html.HTML.VALUE_ATTR,
-                                value,
-                                org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
+                writer.writeAttribute(HTML.VALUE_ATTR, value, JSFAttr.VALUE_ATTR);
             }
         }
 
-        if (HtmlRendererUtils.isDisabled(uiComponent))
+        String outcomeTargetHref = HtmlRendererUtils.getOutcomeTargetHref(
+                    facesContext, (UIOutcomeTarget) uiComponent);
+
+        if (HtmlRendererUtils.isDisabled(uiComponent) || outcomeTargetHref == null)
         {
-            HtmlRendererUtils.renderHTMLAttribute(writer, HTML.DISABLED_ATTR,
-                    HTML.DISABLED_ATTR, true);
+            // disable the button - if disabled is true or no fitting NavigationCase was found
+            HtmlRendererUtils.renderHTMLAttribute(writer, HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, true);
         }
         else
         {
-            String href = facesContext.getExternalContext().encodeResourceURL(
-                    HtmlRendererUtils.getOutcomeTargetLinkHref(facesContext,
-                            (UIOutcomeTarget) uiComponent));
+            // render onClick attribute
+            String href = facesContext.getExternalContext().encodeResourceURL(outcomeTargetHref);
+
+            String commandOnClick = (String) uiComponent.getAttributes().get(HTML.ONCLICK_ATTR);
+            String navigationJavaScript = "window.location.href = '" + href + "'";
 
             if (behaviors != null && !behaviors.isEmpty())
             {
                 HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONCLICK_ATTR, 
                         uiComponent, ClientBehaviorEvents.CLICK, null, behaviors, HTML.ONCLICK_ATTR, 
-                        (String) uiComponent.getAttributes().get(HTML.ONCLICK_ATTR), "window.location.href = '" + href + "'");
+                        commandOnClick, navigationJavaScript);
             }
             else
             {
-                String commandOnClick = (String) uiComponent.getAttributes().get(
-                        HTML.ONCLICK_ATTR);
                 StringBuffer onClick = new StringBuffer();
     
                 if (commandOnClick != null)
@@ -133,26 +126,25 @@ public class HtmlOutcomeTargetButtonRend
                     onClick.append(commandOnClick);
                     onClick.append(';');
                 }
-    
-                onClick.append("window.location.href = '" + href + "'");
+                onClick.append(navigationJavaScript);
     
                 writer.writeAttribute(HTML.ONCLICK_ATTR, onClick.toString(), null);
             }
         }
 
-        if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
+        if (uiComponent instanceof ClientBehaviorHolder
+                && JavascriptUtils.isJavascriptAllowed(facesContext.getExternalContext()))
         {
-            HtmlRendererUtils.renderBehaviorizedEventHandlersWithoutOnclick(facesContext, writer, uiComponent, behaviors);
-            HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(facesContext, writer, uiComponent, behaviors);
+            HtmlRendererUtils.renderBehaviorizedEventHandlersWithoutOnclick(
+                    facesContext, writer, uiComponent, behaviors);
+            HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
+                    facesContext, writer, uiComponent, behaviors);
         }
         else
         {
             HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
                     HTML.EVENT_HANDLER_ATTRIBUTES_WITHOUT_ONCLICK);
-            HtmlRendererUtils
-                .renderHTMLAttributes(
-                    writer,
-                    uiComponent,
+            HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
                     HTML.COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONSELECT_AND_ONCHANGE);
 
         }

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java?rev=1041329&r1=1041328&r2=1041329&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java Thu Dec  2 11:07:21 2010
@@ -1773,7 +1773,7 @@ public final class HtmlRendererUtils {
                 + HIDDEN_COMMANDLINK_FIELD_NAME_MYFACES_OLD;
     }
 
-    public static String getOutcomeTargetLinkHref(
+    public static String getOutcomeTargetHref(
             FacesContext facesContext, UIOutcomeTarget component) throws IOException {
         String outcome = component.getOutcome();
         outcome = ((outcome == null) ? STR_EMPTY : outcome.trim());
@@ -1788,8 +1788,13 @@ public final class HtmlRendererUtils {
         // fromAction is null because there is no action method that was called to get the outcome
         NavigationCase navigationCase = navigationHandler.getNavigationCase(facesContext, null, outcome);
 
-        // when navigation case is null, force the "link" to be rendered as text
-        if (navigationCase == null) {
+        // when navigation case is null, force the link or button to be disabled and log a warning
+        if (navigationCase == null)
+        {
+            // log a warning
+            log.warning("Could not determine NavigationCase for UIOutcomeTarget component "
+                    + RendererUtils.getPathToComponent(component));
+
             return null;
         }