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/04/20 15:35:40 UTC
svn commit: r935912 - in /myfaces:
core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/
shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/
Author: jakobk
Date: Tue Apr 20 13:35:40 2010
New Revision: 935912
URL: http://svn.apache.org/viewvc?rev=935912&view=rev
Log:
MYFACES-2663 NPE in UIParameter when value resolves to null (major refactoring of every use of UIParameter - introduced HtmlRendererUtils.getValidUIParameterChildren() to retrieve UIParameter children correctly)
Modified:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormatRenderer.java
myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java
myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java
myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java
myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRenderer.java
myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormatRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormatRenderer.java?rev=935912&r1=935911&r2=935912&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormatRenderer.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormatRenderer.java Tue Apr 20 13:35:40 2010
@@ -35,6 +35,7 @@ import org.apache.myfaces.buildtools.mav
import org.apache.myfaces.shared_impl.renderkit.JSFAttr;
import org.apache.myfaces.shared_impl.renderkit.RendererUtils;
import org.apache.myfaces.shared_impl.renderkit.html.HtmlRenderer;
+import org.apache.myfaces.shared_impl.renderkit.html.HtmlRendererUtils;
import org.apache.myfaces.shared_impl.renderkit.html.HtmlTextRendererBase;
/**
@@ -90,18 +91,12 @@ public class HtmlFormatRenderer extends
else
{
List<Object> argsList = new ArrayList<Object>();
- for (UIComponent child : htmlOutputFormat.getChildren())
+
+ List<UIParameter> validParams = HtmlRendererUtils.getValidUIParameterChildren(
+ facesContext, htmlOutputFormat.getChildren(), false, false, false);
+ for (UIParameter param : validParams)
{
- if (child instanceof UIParameter)
- {
- // check for the disable attribute (since 2.0)
- if (((UIParameter) child).isDisable())
- {
- // ignore this UIParameter and continue
- continue;
- }
- argsList.add(((UIParameter)child).getValue());
- }
+ argsList.add(param.getValue());
}
args = argsList.toArray(new Object[argsList.size()]);
Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java?rev=935912&r1=935911&r2=935912&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlButtonRendererBase.java Tue Apr 20 13:35:40 2010
@@ -34,7 +34,6 @@ import javax.faces.context.ExternalConte
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.ActionEvent;
-import javax.faces.application.ResourceHandler;
import org.apache.myfaces.shared.config.MyfacesConfig;
import org.apache.myfaces.shared.renderkit.ClientBehaviorEvents;
@@ -206,28 +205,19 @@ public class HtmlButtonRendererBase
}
// render the UIParameter children of the commandButton (since 2.0)
- for (UIComponent child : uiComponent.getChildren())
- {
- if (child.getClass().equals(UIParameter.class))
- {
- UIParameter parameter = (UIParameter) child;
- // check for the disable attribute
- if (parameter.isDisable())
- {
- continue;
- }
- HtmlInputHidden parameterComponent = new HtmlInputHidden();
- parameterComponent.setId(parameter.getName());
- parameterComponent.setValue(parameter.getValue());
- parameterComponent.encodeAll(facesContext);
- }
+ List<UIParameter> validParams = HtmlRendererUtils.getValidUIParameterChildren(
+ facesContext, uiComponent.getChildren(), false, false);
+ for (UIParameter param : validParams)
+ {
+ HtmlInputHidden parameterComponent = new HtmlInputHidden();
+ parameterComponent.setId(param.getName());
+ parameterComponent.setValue(param.getValue());
+ parameterComponent.encodeAll(facesContext);
}
}
protected String buildBehaviorizedOnClick(UIComponent uiComponent, Map<String, List<ClientBehavior>> behaviors,
FacesContext facesContext, ResponseWriter writer, FormInfo nestedFormInfo) {
- //TODO fetch parameters from the button
-
//we can omit autoscroll here for now maybe we should check if it is an ajax behavior and omit it only in this case
StringBuilder userOnClick = new StringBuilder();
//user onclick part
@@ -253,8 +243,6 @@ public class HtmlButtonRendererBase
}
}
- //TODO make parameter resolution here
-
//according to the specification in jsf.util.chain jdocs and the spec document we have to use
//jsf.util.chain to chain the functions and
return HtmlRendererUtils.buildBehaviorChain(facesContext, uiComponent, behaviors,
Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java?rev=935912&r1=935911&r2=935912&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlLinkRendererBase.java Tue Apr 20 13:35:40 2010
@@ -21,7 +21,6 @@ package org.apache.myfaces.shared.render
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -487,51 +486,40 @@ public abstract class HtmlLinkRendererBa
return target;
}
- private StringBuffer addChildParameters(UIComponent component, UIComponent nestingForm) {
+ private StringBuffer addChildParameters(UIComponent component, UIComponent nestingForm)
+ {
//add child parameters
StringBuffer params = new StringBuffer();
params.append("[");
- for (Iterator it = getChildren(component).iterator(); it.hasNext();) {
-
- UIComponent child = (UIComponent) it.next();
- if (child instanceof UIParameter) {
- // check for the disable attribute (since 2.0)
- if (((UIParameter) child).isDisable())
- {
- // ignore this UIParameter and continue
- continue;
- }
-
- String name = ((UIParameter) child).getName();
-
- if (name == null) {
- throw new IllegalArgumentException("Unnamed parameter value not allowed within command link.");
- }
-
- //Not necessary, since we are using oamSetHiddenInput to create hidden fields
- //addHiddenCommandParameter(FacesContext.getCurrentInstance(), nestingForm, name);
+
+ List<UIParameter> validParams = HtmlRendererUtils.getValidUIParameterChildren(
+ FacesContext.getCurrentInstance(), getChildren(component), false, false);
+ for (UIParameter param : validParams)
+ {
+ String name = param.getName();
- Object value = ((UIParameter) child).getValue();
+ //Not necessary, since we are using oamSetHiddenInput to create hidden fields
+ //addHiddenCommandParameter(FacesContext.getCurrentInstance(), nestingForm, name);
- //UIParameter is no ValueHolder, so no conversion possible - calling .toString on value....
- // MYFACES-1832 bad charset encoding for f:param
- // if HTMLEncoder.encode is called, then
- // when is called on writer.writeAttribute, encode method
- // is called again so we have a duplicated encode
- // call.
- //String strParamValue = value != null ? org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder.encode(value.toString(), false, false) : "";
- String strParamValue = value != null ? value.toString() : "";
+ Object value = param.getValue();
- if (params.length() > 1) {
- params.append(",");
- }
+ //UIParameter is no ValueHolder, so no conversion possible - calling .toString on value....
+ // MYFACES-1832 bad charset encoding for f:param
+ // if HTMLEncoder.encode is called, then
+ // when is called on writer.writeAttribute, encode method
+ // is called again so we have a duplicated encode call.
+ String strParamValue = value != null ? value.toString() : "";
- params.append("['");
- params.append(name);
- params.append("','");
- params.append(strParamValue);
- params.append("']");
+ if (params.length() > 1)
+ {
+ params.append(",");
}
+
+ params.append("['");
+ params.append(name);
+ params.append("','");
+ params.append(strParamValue);
+ params.append("']");
}
params.append("]");
return params;
@@ -613,22 +601,15 @@ public abstract class HtmlLinkRendererBa
{
boolean strictXhtmlLinks
= MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isStrictXhtmlLinks();
- for (Iterator it = getChildren(linkComponent).iterator(); it.hasNext(); )
- {
- UIComponent child = (UIComponent)it.next();
- if (child instanceof UIParameter)
- {
- // check for the disable attribute (since 2.0)
- if (((UIParameter) child).isDisable())
- {
- // ignore this UIParameter and continue
- continue;
- }
- String name = ((UIParameter)child).getName();
- Object value = ((UIParameter)child).getValue();
- addParameterToHref(name, value, hrefBuf, firstParameter, charEncoding, strictXhtmlLinks);
- firstParameter = false;
- }
+
+ List<UIParameter> validParams = HtmlRendererUtils.getValidUIParameterChildren(
+ facesContext, getChildren(linkComponent), false, false);
+ for (UIParameter param : validParams)
+ {
+ String name = param.getName();
+ Object value = param.getValue();
+ addParameterToHref(name, value, hrefBuf, firstParameter, charEncoding, strictXhtmlLinks);
+ firstParameter = false;
}
}
Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java?rev=935912&r1=935911&r2=935912&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlOutcomeTargetButtonRendererBase.java Tue Apr 20 13:35:40 2010
@@ -19,20 +19,11 @@
package org.apache.myfaces.shared.renderkit.html;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import javax.faces.FacesException;
-import javax.faces.application.ConfigurableNavigationHandler;
-import javax.faces.application.NavigationCase;
-import javax.faces.application.NavigationHandler;
-import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UIOutcomeTarget;
-import javax.faces.component.UIParameter;
import javax.faces.component.behavior.ClientBehavior;
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.component.html.HtmlOutcomeTargetButton;
@@ -40,8 +31,6 @@ import javax.faces.context.ExternalConte
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
-import org.apache.myfaces.shared.config.MyfacesConfig;
-import org.apache.myfaces.shared.renderkit.ClientBehaviorEvents;
import org.apache.myfaces.shared.renderkit.JSFAttr;
import org.apache.myfaces.shared.renderkit.RendererUtils;
import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRenderer.java?rev=935912&r1=935911&r2=935912&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRenderer.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRenderer.java Tue Apr 20 13:35:40 2010
@@ -50,7 +50,7 @@ public abstract class HtmlRenderer
*
* @return a list of UIComponent objects.
*/
- public List getChildren(UIComponent component)
+ public List<UIComponent> getChildren(UIComponent component)
{
return component.getChildren();
}
Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java?rev=935912&r1=935911&r2=935912&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java Tue Apr 20 13:35:40 2010
@@ -1855,50 +1855,21 @@ public final class HtmlRendererUtils {
// handle URL parameters
Map<String, List<String>> parameters = new HashMap<String,List<String>>();
- for (Iterator<UIComponent> it = component.getChildren().iterator(); it.hasNext(); )
- {
- UIComponent child = (UIComponent) it.next();
- if (child instanceof UIParameter)
+ List<UIParameter> validParams = getValidUIParameterChildren(
+ facesContext, component.getChildren(), true, false);
+ for (UIParameter param : validParams)
+ {
+ String name = param.getName();
+ Object value = param.getValue();
+ if (parameters.containsKey(name))
{
- UIParameter param = (UIParameter) child;
-
- // check for the disable attribute (since 2.0)
- if (param.isDisable())
- {
- // ignore this UIParameter and continue
- continue;
- }
- String name = param.getName();
- if (name == null || STR_EMPTY.equals(name))
- {
- // warn for a null-name
- log.log(Level.WARNING, "The UIParameter " + RendererUtils.getPathToComponent(param) +
- " has a name of null or empty string and thus will not be added to the URL.");
- // and skip it
- continue;
- }
- Object value = param.getValue();
- if (value == null)
- {
- if (facesContext.isProjectStage(ProjectStage.Development))
- {
- // inform the user about the null value when in Development stage
- log.log(Level.INFO, "The UIParameter " + RendererUtils.getPathToComponent(param) +
- " has a value of null and thus will not be added to the URL.");
- }
- // skip a null-value
- continue;
- }
- if (parameters.containsKey(name))
- {
- parameters.get(name).add(value.toString());
- }
- else
- {
- List<String> list = new ArrayList<String>(1);
- list.add(value.toString());
- parameters.put(name, list);
- }
+ parameters.get(name).add(value.toString());
+ }
+ else
+ {
+ List<String> list = new ArrayList<String>(1);
+ list.add(value.toString());
+ parameters.put(name, list);
}
}
@@ -2357,28 +2328,109 @@ public final class HtmlRendererUtils {
* @param uiComponent
* @return
*/
- public static Map<String, String> mapAttachedParamsToStringValues(FacesContext facesContext, UIComponent uiComponent) {
+ public static Map<String, String> mapAttachedParamsToStringValues(FacesContext facesContext, UIComponent uiComponent)
+ {
Map<String, String> retVal = new HashMap<String, String>();
- //we cannot use invokeContextCallback
+ List<UIParameter> validParams = getValidUIParameterChildren(
+ facesContext, uiComponent.getChildren(), true, true);
+ for (UIParameter param : validParams)
+ {
+ String name = param.getName();
+ Object value = param.getValue();
+ if (value instanceof String)
+ {
+ value = "'" + ((String) value) + "'";
+ }
+ retVal.put(name, value.toString());
+ }
+
+ return retVal;
+ }
+
+ /**
+ * Calls getValidUIParameterChildren(facesContext, children, skipNullValue, skipUnrendered, true);
+ *
+ * @param facesContext
+ * @param children
+ * @param skipNullValue
+ * @param skipUnrendered
+ * @return
+ */
+ public static List<UIParameter> getValidUIParameterChildren(FacesContext facesContext,
+ List<UIComponent> children, boolean skipNullValue, boolean skipUnrendered)
+ {
+ return getValidUIParameterChildren(facesContext, children, skipNullValue, skipUnrendered, true);
+ }
+
+ /**
+ * Returns a List of all valid UIParameter children from the given children.
+ * Valid means that the UIParameter is not disabled, its name is not null
+ * (if skipNullName is true), its value is not null (if skipNullValue is true)
+ * and it is rendered (if skipUnrendered is true). This method also creates a
+ * warning for every UIParameter with a null-name (again, if skipNullName is true)
+ * and, if ProjectStage is Development and skipNullValue is true, it informs the
+ * user about every null-value.
+ *
+ * @param facesContext
+ * @param children
+ * @param skipNullValue should UIParameters with a null value be skipped
+ * @param skipUnrendered should UIParameters with isRendered() returning false be skipped
+ * @param skipNullName should UIParameters with a null name be skipped
+ * (normally true, but in the case of h:outputFormat false)
+ * @return
+ */
+ public static List<UIParameter> getValidUIParameterChildren(FacesContext facesContext,
+ List<UIComponent> children, boolean skipNullValue, boolean skipUnrendered, boolean skipNullName)
+ {
+ List<UIParameter> params = new ArrayList<UIParameter>();
- for (Iterator<UIComponent> it = uiComponent.getFacetsAndChildren(); it.hasNext();) {
- UIComponent target = it.next();
- if (!(target instanceof UIParameter)) continue;
- UIParameter param = (UIParameter) target;
- if (param.isRendered() && param.getValue() != null
- && !param.isDisable())
+ for (UIComponent child : children)
+ {
+ if (child instanceof UIParameter)
{
+ UIParameter param = (UIParameter) child;
+
+ // check for the disable attribute (since 2.0)
+ // and the render attribute (only if skipUnrendered is true)
+ if (param.isDisable() ||
+ (skipUnrendered && !param.isRendered()))
+ {
+ // ignore this UIParameter and continue
+ continue;
+ }
+
+ // check the name
String name = param.getName();
- Object value = param.getValue();
- if (value instanceof String) {
- value = "'" + ((String) value) + "'";
+ if (skipNullName && (name == null || STR_EMPTY.equals(name)))
+ {
+ // warn for a null-name
+ log.log(Level.WARNING, "The UIParameter " + RendererUtils.getPathToComponent(param) +
+ " has a name of null or empty string and thus will not be added to the URL.");
+ // and skip it
+ continue;
+ }
+
+ // check the value
+ if (skipNullValue && param.getValue() == null)
+ {
+ if (facesContext.isProjectStage(ProjectStage.Development))
+ {
+ // inform the user about the null value when in Development stage
+ log.log(Level.INFO, "The UIParameter " + RendererUtils.getPathToComponent(param) +
+ " has a value of null and thus will not be added to the URL.");
+ }
+ // skip a null-value
+ continue;
}
- retVal.put(name, value.toString());
+
+ // add the param
+ params.add(param);
}
}
- return retVal;
- }
+
+ return params;
+ }
/**
* @since 4.0.0