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 2009/08/20 06:06:44 UTC
svn commit: r806040 - in
/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite:
AttributeHandler.java CompositeComponentResourceTagHandler.java
Author: lu4242
Date: Thu Aug 20 04:06:43 2009
New Revision: 806040
URL: http://svn.apache.org/viewvc?rev=806040&view=rev
Log:
MYFACES-2312 Implement <composite:attribute> tag handler
Modified:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttributeHandler.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttributeHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttributeHandler.java?rev=806040&r1=806039&r2=806040&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttributeHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/AttributeHandler.java Thu Aug 20 04:06:43 2009
@@ -51,12 +51,24 @@
@JSFFaceletAttribute
private final TagAttribute _targets;
+ /**
+ * If this property is set and the attribute does not have any
+ * value (null), the value set on this property is returned as default
+ * instead null.
+ */
@JSFFaceletAttribute
private final TagAttribute _default;
@JSFFaceletAttribute
private final TagAttribute _displayName;
+ /**
+ * Indicate if the attribute is required or not
+ * <p>
+ * Myfaces specific feature: this attribute is checked only if project stage is
+ * not ProjectStage.Production when a composite component is created.
+ * </p>
+ */
@JSFFaceletAttribute
private final TagAttribute _required;
@@ -75,9 +87,20 @@
@JSFFaceletAttribute
private final TagAttribute _type;
+ /**
+ * Check if the PropertyDescriptor instance created by this handler
+ * can be cacheable or not.
+ */
private boolean _cacheable;
- private volatile PropertyDescriptor _propertyDescriptor;
+ /**
+ * Cached instance used by this component. Note here we have a
+ * "racy single-check". If this field is used, it is supposed
+ * the object cached by this handler is immutable, and this is
+ * granted if all properties not saved as ValueExpression are
+ * "literal".
+ */
+ private PropertyDescriptor _propertyDescriptor;
public AttributeHandler(TagConfig config)
{
@@ -94,15 +117,26 @@
_type = getAttribute("type");
// We can reuse the same PropertyDescriptor only if the properties
- // that requires to be evaluated when apply occur are literal or null.
- // otherwise we need to create it.
+ // that requires to be evaluated when apply (build view time)
+ // occur are literal or null. Otherwise we need to create it.
if ( (_name == null || _name.isLiteral() ) &&
(_displayName == null || _displayName.isLiteral() ) &&
(_preferred == null || _preferred.isLiteral() ) &&
(_expert == null || _expert.isLiteral() ) &&
(_shortDescription == null || _shortDescription.isLiteral() ) )
{
+ // Unfortunately its not possible to create the required
+ // PropertyDescriptor instance here, because there is no way
+ // to get a FaceletContext to create ValueExpressions. It is
+ // possible to create it if we not have set all this properties:
+ // targets, default, required, methodSignature and type. This prevents
+ // the racy single-check.
_cacheable = true;
+ if ( _targets == null && _default == null && _required == null &&
+ _methodSignature == null && _type == null)
+ {
+ _propertyDescriptor = _createPropertyDescriptor();
+ }
}
else
{
@@ -146,6 +180,47 @@
nextHandler.apply(ctx, parent);
}
+ /**
+ * This method could be called only if it is not necessary to set the following properties:
+ * targets, default, required, methodSignature and type
+ *
+ * @return
+ */
+ private PropertyDescriptor _createPropertyDescriptor()
+ {
+ try
+ {
+ CompositeComponentPropertyDescriptor attribute =
+ new CompositeComponentPropertyDescriptor(_name.getValue());
+
+ if (_displayName != null)
+ {
+ attribute.setDisplayName(_displayName.getValue());
+ }
+ if (_preferred != null)
+ {
+ attribute.setPreferred(Boolean.valueOf(_preferred.getValue()));
+ }
+ if (_expert != null)
+ {
+ attribute.setExpert(Boolean.valueOf(_expert.getValue()));
+ }
+ if (_shortDescription != null)
+ {
+ attribute.setShortDescription(_shortDescription.getValue());
+ }
+ return attribute;
+ }
+ catch (IntrospectionException e)
+ {
+ if (log.isErrorEnabled())
+ {
+ log.error("Cannot create PropertyDescriptor for attribute ",e);
+ }
+ throw new TagException(tag,e);
+ }
+ }
+
private PropertyDescriptor _createPropertyDescriptor(FaceletContext ctx, UIComponent parent)
throws TagException, IOException
{
@@ -166,7 +241,7 @@
}
if (_displayName != null)
{
- attribute.setDisplayName(_displayName.getValue());
+ attribute.setDisplayName(_displayName.getValue(ctx));
}
if (_required != null)
{
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java?rev=806040&r1=806039&r2=806040&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentResourceTagHandler.java Thu Aug 20 04:06:43 2009
@@ -18,9 +18,13 @@
*/
package org.apache.myfaces.view.facelets.tag.composite;
+import java.beans.BeanInfo;
+import java.beans.PropertyDescriptor;
import java.io.IOException;
+import javax.el.ValueExpression;
import javax.el.VariableMapper;
+import javax.faces.application.ProjectStage;
import javax.faces.application.Resource;
import javax.faces.component.UIComponent;
import javax.faces.component.UIPanel;
@@ -30,6 +34,7 @@
import javax.faces.view.facelets.ComponentHandler;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.MetaRuleset;
+import javax.faces.view.facelets.TagException;
import org.apache.myfaces.view.facelets.AbstractFaceletContext;
import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
@@ -48,7 +53,7 @@
implements ComponentBuilderHandler
{
private final Resource _resource;
-
+
public CompositeComponentResourceTagHandler(ComponentConfig config, Resource resource)
{
super(config);
@@ -58,8 +63,30 @@
@Override
public UIComponent createComponent(FaceletContext ctx)
{
- FacesContext faceContext = ctx.getFacesContext();
- return faceContext.getApplication().createComponent(faceContext, _resource);
+ FacesContext facesContext = ctx.getFacesContext();
+ UIComponent component = facesContext.getApplication().createComponent(facesContext, _resource);
+
+ // Check required attributes if the app is not on production stage.
+ // Unfortunately, we can't check it on constructor because we need to call
+ // ViewDeclarationLanguage.getComponentMetadata() and on that point it is possible to not
+ // have a viewId.
+ if (!facesContext.isProjectStage(ProjectStage.Production))
+ {
+ BeanInfo beanInfo = (BeanInfo) component.getAttributes().get(UIComponent.BEANINFO_KEY);
+ for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors())
+ {
+ ValueExpression ve = (ValueExpression) propertyDescriptor.getValue("required");
+ if (ve != null)
+ {
+ Boolean required = Boolean.valueOf((String)ve.getValue(facesContext.getELContext()));
+ if (required != null && required.booleanValue())
+ {
+ throw new TagException(this.tag, "Attribute '" + propertyDescriptor.getName() + "' is required");
+ }
+ }
+ }
+ }
+ return component;
}
@Override
@@ -80,7 +107,7 @@
//vdl.retargetAttachedObjects(facesContext, c, handlers)
// TODO: Uncomment this code and test it.
- //vdl.retargetMethodExpressions(facesContext, c);
+ vdl.retargetMethodExpressions(facesContext, c);
if (ctx.getFacesContext().getAttributes().containsKey(
FaceletViewDeclarationLanguage.MARK_INITIAL_STATE_KEY))