You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/11/11 03:42:00 UTC
svn commit: r1200704 - in /myfaces/core/branches/2.0.x:
impl/src/main/java/org/apache/myfaces/el/unified/resolver/CompositeComponentELResolver.java
shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
Author: lu4242
Date: Fri Nov 11 02:41:59 2011
New Revision: 1200704
URL: http://svn.apache.org/viewvc?rev=1200704&view=rev
Log:
MYFACES-2552 TagValueExpression.getType() returns null if the property in the managed bean is null and the expression points to a facelets composite component attribute
Modified:
myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/el/unified/resolver/CompositeComponentELResolver.java
myfaces/core/branches/2.0.x/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
Modified: myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/el/unified/resolver/CompositeComponentELResolver.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/el/unified/resolver/CompositeComponentELResolver.java?rev=1200704&r1=1200703&r2=1200704&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/el/unified/resolver/CompositeComponentELResolver.java (original)
+++ myfaces/core/branches/2.0.x/impl/src/main/java/org/apache/myfaces/el/unified/resolver/CompositeComponentELResolver.java Fri Nov 11 02:41:59 2011
@@ -35,6 +35,9 @@ import javax.faces.component.UIComponent
import javax.faces.context.FacesContext;
import javax.faces.el.CompositeComponentExpressionHolder;
+import org.apache.myfaces.shared.config.MyfacesConfig;
+import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
+
/**
* Composite component attribute EL resolver. See JSF spec, section 5.6.2.2.
*/
@@ -68,7 +71,89 @@ public final class CompositeComponentELR
@Override
public Class<?> getType(ELContext context, Object base, Object property)
{
+ if (base != null && property != null &&
+ base instanceof CompositeComponentAttributesMapWrapper &&
+ property instanceof String)
+ {
+ FacesContext facesContext = facesContext(context);
+ if (facesContext == null)
+ {
+ facesContext = FacesContext.getCurrentInstance();
+ }
+ if (facesContext == null)
+ {
+ return null;
+ }
+ if (!MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isStrictJsf2CCELResolver())
+ {
+ // handle JSF 2.2 spec revisions:
+ // code resembles that found in Mojarra because it originates from
+ // the same contributor, whose ICLA is on file
+ Class<?> exprType = null;
+ Class<?> metaType = null;
+
+ CompositeComponentAttributesMapWrapper evalMap = (CompositeComponentAttributesMapWrapper) base;
+ ValueExpression ve = evalMap.getExpression((String) property);
+ if (ve != null)
+ {
+ exprType = ve.getType(context);
+ }
+
+ if (!"".equals(property))
+ {
+ if (evalMap._propertyDescriptors != null)
+ {
+ for (PropertyDescriptor pd : evalMap._propertyDescriptors)
+ {
+ if (property.equals(pd.getName()))
+ {
+ metaType = resolveType(context, pd);
+ break;
+ }
+ }
+ }
+ }
+ if (metaType != null)
+ {
+ // override exprType only if metaType is narrower:
+ if (exprType == null || exprType.isAssignableFrom(metaType))
+ {
+ context.setPropertyResolved(true);
+ return metaType;
+ }
+ }
+ return exprType;
+ }
+ }
+
// Per the spec, return null.
+ return null;
+ }
+
+ // adapted from CompositeMetadataTargetImpl#getPropertyType():
+ private static Class<?> resolveType(ELContext context, PropertyDescriptor pd)
+ {
+ if (pd != null)
+ {
+ Object type = pd.getValue("type");
+ if (type != null)
+ {
+ type = ((ValueExpression)type).getValue(context);
+ if (type instanceof String)
+ {
+ try
+ {
+ type = FaceletViewDeclarationLanguage._javaTypeToClass((String)type);
+ }
+ catch (ClassNotFoundException e)
+ {
+ type = null;
+ }
+ }
+ return (Class<?>) type;
+ }
+ return pd.getPropertyType();
+ }
return null;
}
Modified: myfaces/core/branches/2.0.x/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java?rev=1200704&r1=1200703&r2=1200704&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java (original)
+++ myfaces/core/branches/2.0.x/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java Fri Nov 11 02:41:59 2011
@@ -321,13 +321,25 @@ public class MyfacesConfig
* Detect if a target (usually head) should be update for the current view in an ajax render
* operation. This is activated if a css or js resource is added dynamically by effect of a refresh
* (c:if, ui:include src="#{...}" or a manipulation of the tree). This ensures ajax updates of content
- * using ui:include will be consistent.
+ * using ui:include will be consistent. Note this behavior is a myfaces specific extension, so to ensure strict compatibility with the spec,
+ * set this param to false (default false).
*/
@JSFWebConfigParam(since="2.0.10", expectedValues="true, false", defaultValue="false")
public final static String INIT_PARAM_STRICT_JSF_2_REFRESH_TARGET_AJAX =
"org.apache.myfaces.STRICT_JSF_2_REFRESH_TARGET_AJAX";
public final static boolean INIT_PARAM_STRICT_JSF_2_REFRESH_TARGET_AJAX_DEFAULT = false;
+ /**
+ * Change default getType() behavior for composite component EL resolver, from return null (see JSF 2_0 spec section 5_6_2_2) to
+ * use the metadata information added by composite:attribute, ensuring components working with chained EL expressions to find the
+ * right type when a getType() is called over the source EL expression.
+ *
+ * To ensure strict compatibility with the spec set this param to true (by default is false, so the change is enabled by default).
+ */
+ @JSFWebConfigParam(since="2.0.10", expectedValues="true, false", defaultValue="false", group="EL")
+ public final static String INIT_PARAM_STRICT_JSF_2_CC_EL_RESOLVER = "org.apache.myfaces.STRICT_JSF_2_CC_EL_RESOLVER";
+ public final static boolean INIT_PARAM_STRICT_JSF_2_CC_EL_RESOLVER_DEFAULT = false;
+
private boolean _prettyHtml;
private boolean _detectJavascript;
private boolean _allowJavascript;
@@ -352,6 +364,7 @@ public class MyfacesConfig
private boolean _renderFormSubmitScriptInline;
private boolean _debugPhaseListenerEnabled;
private boolean _strictJsf2RefreshTargetAjax;
+ private boolean _strictJsf2CCELResolver;
private static final boolean TOMAHAWK_AVAILABLE;
private static final boolean MYFACES_IMPL_AVAILABLE;
@@ -445,6 +458,7 @@ public class MyfacesConfig
setRenderFormSubmitScriptInline(INIT_PARAM_RENDER_FORM_SUBMIT_SCRIPT_INLINE_DEFAULT);
setDebugPhaseListenerEnabled(INIT_PARAM_DEBUG_PHASE_LISTENER_DEFAULT);
setStrictJsf2RefreshTargetAjax(INIT_PARAM_STRICT_JSF_2_REFRESH_TARGET_AJAX_DEFAULT);
+ setStrictJsf2CCELResolver(INIT_PARAM_STRICT_JSF_2_CC_EL_RESOLVER_DEFAULT);
}
private static MyfacesConfig createAndInitializeMyFacesConfig(ExternalContext extCtx)
@@ -530,6 +544,9 @@ public class MyfacesConfig
myfacesConfig.setStrictJsf2RefreshTargetAjax(WebConfigParamUtils.getBooleanInitParameter(extCtx,
INIT_PARAM_STRICT_JSF_2_REFRESH_TARGET_AJAX, INIT_PARAM_STRICT_JSF_2_REFRESH_TARGET_AJAX_DEFAULT));
+
+ myfacesConfig.setStrictJsf2CCELResolver(WebConfigParamUtils.getBooleanInitParameter(extCtx,
+ INIT_PARAM_STRICT_JSF_2_CC_EL_RESOLVER, INIT_PARAM_STRICT_JSF_2_CC_EL_RESOLVER_DEFAULT));
if (TOMAHAWK_AVAILABLE)
{
@@ -976,4 +993,14 @@ public class MyfacesConfig
{
this._strictJsf2RefreshTargetAjax = strictJsf2RefreshTargetAjax;
}
+
+ public boolean isStrictJsf2CCELResolver()
+ {
+ return _strictJsf2CCELResolver;
+ }
+
+ public void setStrictJsf2CCELResolver(boolean strictJsf2CCELResolver)
+ {
+ this._strictJsf2CCELResolver = strictJsf2CCELResolver;
+ }
}