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 2013/08/23 06:39:25 UTC

svn commit: r1516700 - in /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets: PassthroughRule.java tag/MetaRulesetImpl.java tag/jsf/ComponentTagHandlerDelegate.java tag/jsf/PassthroughRuleImpl.java

Author: lu4242
Date: Fri Aug 23 04:39:25 2013
New Revision: 1516700

URL: http://svn.apache.org/r1516700
Log:
MYFACES-3757 Implement passthrough attributes using p:<attributeName> 

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/PassthroughRule.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/PassthroughRuleImpl.java   (with props)
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/MetaRulesetImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/PassthroughRule.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/PassthroughRule.java?rev=1516700&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/PassthroughRule.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/PassthroughRule.java Fri Aug 23 04:39:25 2013
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public interface PassthroughRule
+{
+    
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/PassthroughRule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/MetaRulesetImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/MetaRulesetImpl.java?rev=1516700&r1=1516699&r2=1516700&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/MetaRulesetImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/MetaRulesetImpl.java Fri Aug 23 04:39:25 2013
@@ -37,6 +37,8 @@ import java.util.Map;
 import java.util.WeakHashMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import org.apache.myfaces.view.facelets.PassthroughRule;
+import org.apache.myfaces.view.facelets.tag.jsf.PassThroughLibrary;
 
 /**
  * 
@@ -101,7 +103,11 @@ public final class MetaRulesetImpl exten
         return metadata;
     }
 
+    private final static TagAttribute[] EMPTY = new TagAttribute[0];
+    
     private final Map<String, TagAttribute> _attributes;
+    
+    private final TagAttribute[] _passthroughAttributes;
 
     private final List<Metadata> _mappers;
 
@@ -110,6 +116,8 @@ public final class MetaRulesetImpl exten
     private final Tag _tag;
 
     private final Class<?> _type;
+    
+    private final List<MetaRule> _passthroughRules;
 
     public MetaRulesetImpl(Tag tag, Class<?> type)
     {
@@ -125,11 +133,48 @@ public final class MetaRulesetImpl exten
         // Usually ComponentTagHandlerDelegate has 5 rules at max
         // and CompositeComponentResourceTagHandler 6, so 8 is a good number
         _rules = new ArrayList<MetaRule>(8); 
+        _passthroughRules = new ArrayList<MetaRule>(2);
 
-        // setup attributes
-        for (TagAttribute attribute : allAttributes)
+        // Passthrough attributes are different from normal attributes, because they
+        // are just rendered into the markup without additional processing from the
+        // renderer. Here it starts attribute processing, so this is the best place 
+        // to find the passthrough attributes.
+        TagAttribute[] passthroughAttribute = _tag.getAttributes().getAll(
+            PassThroughLibrary.NAMESPACE);
+        TagAttribute[] passthroughAttributeAlias = _tag.getAttributes().getAll(
+            PassThroughLibrary.ALIAS_NAMESPACE);
+        
+        if (passthroughAttribute.length > 0 ||
+            passthroughAttributeAlias.length > 0)
+        {
+            _passthroughAttributes = new TagAttribute[passthroughAttribute.length+
+                passthroughAttributeAlias.length];
+            int i = 0;
+            for (TagAttribute attribute : allAttributes)
+            {
+                // The fastest check is check if the length is > 0, because
+                // most attributes usually has no namespace attached.
+                if (attribute.getNamespace().length() > 0 &&
+                    (PassThroughLibrary.NAMESPACE.equals(attribute.getNamespace()) ||
+                        PassThroughLibrary.ALIAS_NAMESPACE.equals(attribute.getNamespace())))
+                {
+                    _passthroughAttributes[i] = attribute;
+                    i++;
+                }
+                else
+                {
+                    _attributes.put(attribute.getLocalName(), attribute);
+                }
+            }
+        }
+        else
         {
-            _attributes.put(attribute.getLocalName(), attribute);
+            _passthroughAttributes = EMPTY;
+            // setup attributes
+            for (TagAttribute attribute : allAttributes)
+            {
+                _attributes.put(attribute.getLocalName(), attribute);
+            }
         }
 
         // add default rules
@@ -152,7 +197,14 @@ public final class MetaRulesetImpl exten
     {
         ParameterCheck.notNull("rule", rule);
 
-        _rules.add(rule);
+        if (rule instanceof PassthroughRule)
+        {
+            _passthroughRules.add(rule);
+        }
+        else
+        {
+            _rules.add(rule);
+        }
 
         return this;
     }
@@ -173,11 +225,13 @@ public final class MetaRulesetImpl exten
 
     public Metadata finish()
     {
+        MetadataTarget target = null;
+        
         assert !_rules.isEmpty();
         
         if (!_attributes.isEmpty())
         {
-            MetadataTarget target = this._getMetadataTarget();
+            target = this._getMetadataTarget();
             int ruleEnd = _rules.size() - 1;
 
             // now iterate over attributes
@@ -208,6 +262,46 @@ public final class MetaRulesetImpl exten
                 }
             }
         }
+        
+        if (_passthroughAttributes.length > 0 &&
+            _passthroughRules.size() > 0)
+        {
+            if (target == null)
+            {
+                target = this._getMetadataTarget();
+            }
+            int ruleEnd = _passthroughRules.size() - 1;
+
+            // now iterate over attributes
+            for (TagAttribute passthroughAttribute : _passthroughAttributes)
+            {
+                Metadata data = null;
+
+                int i = ruleEnd;
+
+                // First loop is always safe
+                do
+                {
+                    MetaRule rule = _passthroughRules.get(i);
+                    data = rule.applyRule(passthroughAttribute.getLocalName(),
+                        passthroughAttribute, target);
+                    i--;
+                } while (data == null && i >= 0);
+
+                if (data == null)
+                {
+                    if (log.isLoggable(Level.SEVERE))
+                    {
+                        log.severe(passthroughAttribute.getLocalName() + 
+                            " Unhandled by MetaTagHandler for type " + _type.getName());
+                    }
+                }
+                else
+                {
+                    _mappers.add(data);
+                }
+            }
+        }
 
         if (_mappers.isEmpty())
         {

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java?rev=1516700&r1=1516699&r2=1516700&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentTagHandlerDelegate.java Fri Aug 23 04:39:25 2013
@@ -511,6 +511,9 @@ public class ComponentTagHandlerDelegate
 
         // add auto wiring for attributes
         m.addRule(ComponentRule.INSTANCE);
+        
+        // add special rule for passthrough attributes
+        m.addRule(PassthroughRuleImpl.INSTANCE);
 
         // if it's an ActionSource
         if (ActionSource.class.isAssignableFrom(type))

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/PassthroughRuleImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/PassthroughRuleImpl.java?rev=1516700&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/PassthroughRuleImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/PassthroughRuleImpl.java Fri Aug 23 04:39:25 2013
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.view.facelets.tag.jsf;
+
+import java.util.logging.Logger;
+import javax.faces.component.UIComponent;
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.MetaRule;
+import javax.faces.view.facelets.Metadata;
+import javax.faces.view.facelets.MetadataTarget;
+import javax.faces.view.facelets.TagAttribute;
+import org.apache.myfaces.view.facelets.PassthroughRule;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+final class PassthroughRuleImpl extends MetaRule implements PassthroughRule
+{
+
+    final class LiteralAttributeMetadata extends Metadata
+    {
+        private final String _name;
+        private final String _value;
+
+        public LiteralAttributeMetadata(String name, String value)
+        {
+            _name = name;
+            _value = value;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((UIComponent) instance).getPassThroughAttributes().put(_name, _value);
+        }
+    }
+
+    final static class ValueExpressionMetadata extends Metadata
+    {
+        private final String _name;
+
+        private final TagAttribute _attr;
+
+        private final Class<?> _type;
+
+        public ValueExpressionMetadata(String name, Class<?> type, TagAttribute attr)
+        {
+            _name = name;
+            _attr = attr;
+            _type = type;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance)
+        {
+            ((UIComponent) instance).getPassThroughAttributes().put(
+                _name, _attr.getValueExpression(ctx, _type));
+        }
+    }
+
+    private final static Logger log = Logger.getLogger(PassthroughRuleImpl.class.getName());
+
+    public final static PassthroughRuleImpl INSTANCE = new PassthroughRuleImpl();
+
+    public PassthroughRuleImpl()
+    {
+        super();
+    }
+
+    public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta)
+    {
+        if (meta.isTargetInstanceOf(UIComponent.class))
+        {
+            // if component and dynamic, then must set expression
+            if (!attribute.isLiteral())
+            {
+                Class<?> type = meta.getPropertyType(name);
+                if (type == null)
+                {
+                    type = Object.class;
+                }
+                
+                return new ValueExpressionMetadata(name, type, attribute);
+            }
+            else
+            {
+                return new LiteralAttributeMetadata(name, attribute.getValue());
+            }
+        }
+        return null;
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/PassthroughRuleImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native