You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ms...@apache.org on 2010/01/11 16:22:03 UTC

svn commit: r897901 - in /myfaces/trinidad/branches/trinidad-2.0.x: trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/ trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/facelets/

Author: mstarets
Date: Mon Jan 11 15:22:03 2010
New Revision: 897901

URL: http://svn.apache.org/viewvc?rev=897901&view=rev
Log:
TRINIDAD-1615 - Need MetaTagHandler implementation for the Facelets package

Added:
    myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/
    myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/MetaTagHandler.java
    myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/MethodRule.java
Modified:
    myfaces/trinidad/branches/trinidad-2.0.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/facelets/MethodRule.java

Added: myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/MetaTagHandler.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/MetaTagHandler.java?rev=897901&view=auto
==============================================================================
--- myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/MetaTagHandler.java (added)
+++ myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/MetaTagHandler.java Mon Jan 11 15:22:03 2010
@@ -0,0 +1,398 @@
+/*
+ *  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.trinidadinternal.facelets;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.logging.Level;
+
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.MetaRule;
+import javax.faces.view.facelets.MetaRuleset;
+import javax.faces.view.facelets.Metadata;
+import javax.faces.view.facelets.MetadataTarget;
+import javax.faces.view.facelets.Tag;
+import javax.faces.view.facelets.TagAttribute;
+import javax.faces.view.facelets.TagAttributeException;
+import javax.faces.view.facelets.TagConfig;
+import javax.faces.view.facelets.TagException;
+import javax.faces.view.facelets.TagHandler;
+
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
+
+/**
+ * A base tag for wiring state to an object instance based on rules populated at
+ * the time of creating a MetaRuleset.
+ *
+ * Implementation copied from Facelets 1.1.14, as it got hidden by JSF 2.0
+ * 
+ * @author Jacob Hookom
+ */
+
+public abstract class MetaTagHandler extends TagHandler {
+    private Class lastType = Object.class;
+
+    private Metadata mapper;
+
+    public MetaTagHandler(TagConfig config) {
+        super(config);
+    }
+
+    /**
+     * Extend this method in order to add your own rules.
+     *
+     * @param type
+     * @return
+     */
+    protected MetaRuleset createMetaRuleset(Class type) {
+        assert (type != null);
+        return new MetaRulesetImpl(this.tag, type);
+    }
+
+    /**
+     * Invoking/extending this method will cause the results of the created
+     * MetaRuleset to auto-wire state to the passed instance.
+     *
+     * @param ctx
+     * @param instance
+     */
+    protected void setAttributes(FaceletContext ctx, Object instance) {
+        if (instance != null) {
+            Class type = instance.getClass();
+            if (mapper == null || !this.lastType.equals(type)) {
+                this.lastType = type;
+                this.mapper = this.createMetaRuleset(type).finish();
+            }
+            this.mapper.applyMetadata(ctx, instance);
+        }
+    }
+
+
+    private static class BeanPropertyTagRule extends MetaRule {
+
+        final static class LiteralPropertyMetadata extends Metadata {
+
+            private final Method method;
+
+            private final TagAttribute attribute;
+
+            private Object[] value;
+
+            public LiteralPropertyMetadata(Method method,
+                                           TagAttribute attribute) {
+                this.method = method;
+                this.attribute = attribute;
+            }
+
+            public void applyMetadata(FaceletContext ctx, Object instance) {
+                if (value == null) {
+                    String str = this.attribute.getValue();
+                    value = new Object[] { ctx.getExpressionFactory().coerceToType(str,
+                                                       method.getParameterTypes()[0]) };
+                }
+                try {
+                    method.invoke(instance, this.value);
+                } catch (InvocationTargetException e) {
+                    throw new TagAttributeException(this.attribute,
+                                                    e.getCause());
+                } catch (Exception e) {
+                    throw new TagAttributeException(this.attribute, e);
+                }
+            }
+
+        }
+
+        final static class DynamicPropertyMetadata extends Metadata {
+
+            private final Method method;
+
+            private final TagAttribute attribute;
+
+            private final Class type;
+
+            public DynamicPropertyMetadata(Method method,
+                                           TagAttribute attribute) {
+                this.method = method;
+                this.type = method.getParameterTypes()[0];
+                this.attribute = attribute;
+            }
+
+            public void applyMetadata(FaceletContext ctx, Object instance) {
+                try {
+                    this.method.invoke(instance,
+                                       new Object[] { this.attribute.getObject(ctx,
+                                                                               this.type) });
+                } catch (InvocationTargetException e) {
+                    throw new TagAttributeException(this.attribute,
+                                                    e.getCause());
+                } catch (Exception e) {
+                    throw new TagAttributeException(this.attribute, e);
+                }
+            }
+        }
+
+        public final static BeanPropertyTagRule Instance =
+            new BeanPropertyTagRule();
+
+        public Metadata applyRule(String name, TagAttribute attribute,
+                                  MetadataTarget meta) {
+            Method m = meta.getWriteMethod(name);
+
+            // if the property is writable
+            if (m != null) {
+                if (attribute.isLiteral()) {
+                    return new LiteralPropertyMetadata(m, attribute);
+                } else {
+                    return new DynamicPropertyMetadata(m, attribute);
+                }
+            }
+
+            return null;
+        }
+
+    }
+
+    private static class MetaRulesetImpl extends MetaRuleset {
+
+        private final static WeakHashMap metadata = new WeakHashMap();
+
+        static final private TrinidadLogger log =
+            TrinidadLogger.createTrinidadLogger(MetaRulesetImpl.class);
+
+        private final Tag tag;
+
+        private final Class type;
+
+        private final Map attributes;
+
+        private final List mappers;
+
+        private final List rules;
+
+        public MetaRulesetImpl(Tag tag, Class type) {
+            this.tag = tag;
+            this.type = type;
+            this.attributes = new HashMap();
+            this.mappers = new ArrayList();
+            this.rules = new ArrayList();
+
+            // setup attributes
+            TagAttribute[] attrs = this.tag.getAttributes().getAll();
+            for (int i = 0; i < attrs.length; i++) {
+                attributes.put(attrs[i].getLocalName(), attrs[i]);
+            }
+
+            // add default rules
+            this.rules.add(BeanPropertyTagRule.Instance);
+        }
+
+        public MetaRuleset ignore(String attribute) {
+            assert (attribute != null);
+            this.attributes.remove(attribute);
+            return this;
+        }
+
+        public MetaRuleset alias(String attribute, String property) {
+            assert (attribute != null);
+            assert (property != null);
+            TagAttribute attr =
+                (TagAttribute)this.attributes.remove(attribute);
+            if (attr != null) {
+                this.attributes.put(property, attr);
+            }
+            return this;
+        }
+
+        public MetaRuleset add(Metadata mapper) {
+            assert (mapper != null);
+            if (!this.mappers.contains(mapper)) {
+                this.mappers.add(mapper);
+            }
+            return this;
+        }
+
+        public MetaRuleset addRule(MetaRule rule) {
+            assert (rule != null);
+            this.rules.add(rule);
+            return this;
+        }
+
+        private final MetadataTarget getMetadataTarget() {
+            String key = this.type.getName();
+            MetadataTarget meta = (MetadataTarget)metadata.get(key);
+            if (meta == null) {
+                try {
+                    meta = new MetadataTargetImpl(type);
+                } catch (IntrospectionException e) {
+                    throw new TagException(this.tag, "Error Creating TargetMetadata", e);
+                }
+                metadata.put(key, meta);
+            }
+            return meta;
+        }
+
+        public Metadata finish() {
+            if (!this.attributes.isEmpty()) {
+                if (this.rules.isEmpty()) {
+                    if (log.isLoggable(Level.SEVERE)) {
+                        for (Iterator itr =
+                             this.attributes.values().iterator();
+                             itr.hasNext(); ) {
+                            log.severe(itr.next() +
+                                       " Unhandled by MetaTagHandler for type " +
+                                       this.type.getName());
+                        }
+                    }
+                } else {
+                    MetadataTarget target = this.getMetadataTarget();
+                    // now iterate over attributes
+                    Map.Entry entry;
+                    MetaRule rule;
+                    Metadata data;
+                    int ruleEnd = this.rules.size() - 1;
+                    for (Iterator itr = this.attributes.entrySet().iterator();
+                         itr.hasNext(); ) {
+                        entry = (Map.Entry)itr.next();
+                        data = null;
+                        int i = ruleEnd;
+                        while (data == null && i >= 0) {
+                            rule = (MetaRule)this.rules.get(i);
+                            data = rule.applyRule((String)entry.getKey(), (TagAttribute)entry.getValue(), target);
+                            i--;
+                        }
+                        if (data == null) {
+                            if (log.isLoggable(Level.SEVERE)) {
+                                log.severe(entry.getValue() +
+                                           " Unhandled by MetaTagHandler for type " +
+                                           this.type.getName());
+                            }
+                        } else {
+                            this.mappers.add(data);
+                        }
+                    }
+                }
+            }
+
+            if (this.mappers.isEmpty()) {
+                return NONE;
+            } else {
+                return new MetadataImpl((Metadata[])this.mappers.toArray(new Metadata[this.mappers.size()]));
+            }
+        }
+
+        public MetaRuleset ignoreAll() {
+            this.attributes.clear();
+            return this;
+        }
+
+        private final static Metadata NONE = new Metadata() {
+            public void applyMetadata(FaceletContext ctx, Object instance) {
+                // do nothing
+            }
+        };
+
+        final static class MetadataImpl extends Metadata {
+
+            private final Metadata[] mappers;
+            private final int size;
+
+            public MetadataImpl(Metadata[] mappers) {
+                this.mappers = mappers;
+                this.size = mappers.length;
+            }
+
+            public void applyMetadata(FaceletContext ctx, Object instance) {
+                for (int i = 0; i < size; i++) {
+                    this.mappers[i].applyMetadata(ctx, instance);
+                }
+            }
+
+        }
+    }
+
+    private static class MetadataTargetImpl extends MetadataTarget {
+
+        private final Map pd;
+        private final Class type;
+
+
+        public MetadataTargetImpl(Class type) throws IntrospectionException {
+            this.type = type;
+            this.pd = new HashMap();
+            BeanInfo info = Introspector.getBeanInfo(type);
+            PropertyDescriptor[] pda = info.getPropertyDescriptors();
+            for (int i = 0; i < pda.length; i++) {
+                this.pd.put(pda[i].getName(), pda[i]);
+            }
+        }
+
+        public PropertyDescriptor getProperty(String name) {
+            return (PropertyDescriptor)this.pd.get(name);
+        }
+
+        public boolean isTargetInstanceOf(Class type) {
+            return type.isAssignableFrom(this.type);
+        }
+
+        public Class getTargetClass() {
+            return this.type;
+        }
+
+        public Class getPropertyType(String name) {
+            PropertyDescriptor pd = this.getProperty(name);
+            if (pd != null) {
+                return pd.getPropertyType();
+            }
+            return null;
+        }
+
+        public Method getWriteMethod(String name) {
+            PropertyDescriptor pd = this.getProperty(name);
+            if (pd != null) {
+                return pd.getWriteMethod();
+            }
+            return null;
+        }
+
+        public Method getReadMethod(String name) {
+            PropertyDescriptor pd = this.getProperty(name);
+            if (pd != null) {
+                return pd.getReadMethod();
+            }
+            return null;
+        }
+
+    }
+
+}
+

Added: myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/MethodRule.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/MethodRule.java?rev=897901&view=auto
==============================================================================
--- myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/MethodRule.java (added)
+++ myfaces/trinidad/branches/trinidad-2.0.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/facelets/MethodRule.java Mon Jan 11 15:22:03 2010
@@ -0,0 +1,203 @@
+/*
+ *  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.trinidad.facelets;
+
+import java.io.Serializable;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.el.ELException;
+import javax.el.MethodExpression;
+
+import javax.faces.context.FacesContext;
+import javax.faces.el.EvaluationException;
+import javax.faces.el.MethodBinding;
+
+import javax.faces.el.MethodNotFoundException;
+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 javax.faces.view.facelets.TagAttributeException;
+
+/**
+ * Optional Rule for binding Method[Binding|Expression] properties
+ *
+ * @author Mike Kienenberger
+ * @author Jacob Hookom
+ * 
+ * Implementation copied from Facelets 1.1.14, as it got hidden by JSF 2.0
+ */
+public class MethodRule extends MetaRule {
+
+    private final String methodName;
+
+    private final Class returnTypeClass;
+
+    private final Class[] params;
+
+    public MethodRule(String methodName, Class returnTypeClass,
+                      Class[] params) {
+        this.methodName = methodName;
+        this.returnTypeClass = returnTypeClass;
+        this.params = params;
+    }
+
+    public Metadata applyRule(String name, TagAttribute attribute,
+                              MetadataTarget meta) {
+        if (false == name.equals(this.methodName))
+            return null;
+
+        if (MethodBinding.class.equals(meta.getPropertyType(name))) {
+            Method method = meta.getWriteMethod(name);
+            if (method != null) {
+                return new MethodBindingMetadata(method, attribute,
+                                                 this.returnTypeClass,
+                                                 this.params);
+            }
+        } else if (MethodExpression.class.equals(meta.getPropertyType(name))) {
+            Method method = meta.getWriteMethod(name);
+            if (method != null) {
+                return new MethodExpressionMetadata(method, attribute,
+                                                    this.returnTypeClass,
+                                                    this.params);
+            }
+        }
+
+        return null;
+    }
+
+    private static class MethodBindingMetadata extends Metadata {
+        private final Method _method;
+
+        private final TagAttribute _attribute;
+
+        private Class[] _paramList;
+
+        private Class _returnType;
+
+        public MethodBindingMetadata(Method method, TagAttribute attribute,
+                                     Class returnType, Class[] paramList) {
+            _method = method;
+            _attribute = attribute;
+            _paramList = paramList;
+            _returnType = returnType;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance) {
+            MethodExpression expr =
+                _attribute.getMethodExpression(ctx, _returnType, _paramList);
+
+            try {
+                _method.invoke(instance,
+                               new Object[] { new LegacyMethodBinding(expr) });
+            } catch (InvocationTargetException e) {
+                throw new TagAttributeException(_attribute, e.getCause());
+            } catch (Exception e) {
+                throw new TagAttributeException(_attribute, e);
+            }
+        }
+    }
+
+    private static class MethodExpressionMetadata extends Metadata {
+        private final Method _method;
+
+        private final TagAttribute _attribute;
+
+        private Class[] _paramList;
+
+        private Class _returnType;
+
+        public MethodExpressionMetadata(Method method, TagAttribute attribute,
+                                        Class returnType, Class[] paramList) {
+            _method = method;
+            _attribute = attribute;
+            _paramList = paramList;
+            _returnType = returnType;
+        }
+
+        public void applyMetadata(FaceletContext ctx, Object instance) {
+            MethodExpression expr =
+                _attribute.getMethodExpression(ctx, _returnType, _paramList);
+
+            try {
+                _method.invoke(instance, new Object[] { expr });
+            } catch (InvocationTargetException e) {
+                throw new TagAttributeException(_attribute, e.getCause());
+            } catch (Exception e) {
+                throw new TagAttributeException(_attribute, e);
+            }
+        }
+    }
+    
+
+    private static class LegacyMethodBinding extends MethodBinding implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        private final MethodExpression m;
+
+        public LegacyMethodBinding(MethodExpression m) {
+            this.m = m;
+        }
+
+        /*
+       * (non-Javadoc)
+       *
+       * @see javax.faces.el.MethodBinding#getType(javax.faces.context.FacesContext)
+       */
+
+        public Class getType(FacesContext context) throws MethodNotFoundException {
+            try {
+                return m.getMethodInfo(context.getELContext()).getReturnType();
+            } catch (javax.el.MethodNotFoundException e) {
+                throw new MethodNotFoundException(e.getMessage(),
+                                                  e.getCause());
+            } catch (ELException e) {
+                throw new EvaluationException(e.getMessage(), e.getCause());
+            }
+        }
+
+        /*
+       * (non-Javadoc)
+       *
+       * @see javax.faces.el.MethodBinding#invoke(javax.faces.context.FacesContext,
+       *      java.lang.Object[])
+       */
+
+        public Object invoke(FacesContext context,
+                             Object[] params) throws EvaluationException,
+                                                     MethodNotFoundException {
+            try {
+                return m.invoke(context.getELContext(), params);
+            } catch (javax.el.MethodNotFoundException e) {
+                throw new MethodNotFoundException(e.getMessage(),
+                                                  e.getCause());
+            } catch (ELException e) {
+                throw new EvaluationException(e.getMessage(), e.getCause());
+            }
+        }
+
+        public String getExpressionString() {
+            return m.getExpressionString();
+        }
+    }
+}

Modified: myfaces/trinidad/branches/trinidad-2.0.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/facelets/MethodRule.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/trinidad-2.0.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/facelets/MethodRule.java?rev=897901&r1=897900&r2=897901&view=diff
==============================================================================
--- myfaces/trinidad/branches/trinidad-2.0.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/facelets/MethodRule.java (original)
+++ myfaces/trinidad/branches/trinidad-2.0.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/facelets/MethodRule.java Mon Jan 11 15:22:03 2010
@@ -18,118 +18,15 @@
  */
 package org.apache.myfaces.trinidadinternal.facelets;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import javax.el.MethodExpression;
-import javax.faces.el.MethodBinding;
-
-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 javax.faces.view.facelets.TagAttributeException;
 
 /**
- * Implementation copied from Facelets 1.1.14, as it got hidden by JSF 2.0
+ * This class has been moved to the API jar. 
+ * Keeping implementation here for compatibility reasons. 
  */
-public final class MethodRule extends MetaRule {
-
-    private final String methodName;
-
-    private final Class returnTypeClass;
-
-    private final Class[] params;
+public final class MethodRule extends org.apache.myfaces.trinidad.facelets.MethodRule {
 
     public MethodRule(String methodName, Class returnTypeClass, Class[] params) {
-        this.methodName = methodName;
-        this.returnTypeClass = returnTypeClass;
-        this.params = params;
-    }
-
-    public Metadata applyRule(String name, TagAttribute attribute,
-            MetadataTarget meta) {
-        if (false == name.equals(this.methodName))
-            return null;
-
-        if (MethodBinding.class.equals(meta.getPropertyType(name))) {
-            Method method = meta.getWriteMethod(name);
-            if (method != null) {
-                return new MethodBindingMetadata(method, attribute,
-                        this.returnTypeClass, this.params);
-            }
-        } else if (MethodExpression.class.equals(meta.getPropertyType(name))) {
-            Method method = meta.getWriteMethod(name);
-            if (method != null) {
-                return new MethodExpressionMetadata(method, attribute,
-                        this.returnTypeClass, this.params);
-            }
-        }
-
-        return null;
-    }
-
-    private class MethodBindingMetadata extends Metadata {
-        private final Method _method;
-
-        private final TagAttribute _attribute;
-
-        private Class[] _paramList;
-
-        private Class _returnType;
-
-        public MethodBindingMetadata(Method method, TagAttribute attribute,
-                Class returnType, Class[] paramList) {
-            _method = method;
-            _attribute = attribute;
-            _paramList = paramList;
-            _returnType = returnType;
-        }
-
-        public void applyMetadata(FaceletContext ctx, Object instance) {
-            MethodExpression expr = _attribute.getMethodExpression(ctx,
-                    _returnType, _paramList);
-
-            try {
-                _method.invoke(instance,
-                        new Object[] { new LegacyMethodBinding(expr) });
-            } catch (InvocationTargetException e) {
-                throw new TagAttributeException(_attribute, e.getCause());
-            } catch (Exception e) {
-                throw new TagAttributeException(_attribute, e);
-            }
-        }
-    }
-
-    private class MethodExpressionMetadata extends Metadata {
-        private final Method _method;
-
-        private final TagAttribute _attribute;
-
-        private Class[] _paramList;
-
-        private Class _returnType;
-
-        public MethodExpressionMetadata(Method method, TagAttribute attribute,
-                Class returnType, Class[] paramList) {
-            _method = method;
-            _attribute = attribute;
-            _paramList = paramList;
-            _returnType = returnType;
-        }
-
-        public void applyMetadata(FaceletContext ctx, Object instance) {
-            MethodExpression expr = _attribute.getMethodExpression(ctx,
-                    _returnType, _paramList);
-
-            try {
-                _method.invoke(instance, new Object[] { expr });
-            } catch (InvocationTargetException e) {
-                throw new TagAttributeException(_attribute, e.getCause());
-            } catch (Exception e) {
-                throw new TagAttributeException(_attribute, e);
-            }
-        }
+        super(methodName, returnTypeClass, params);
     }
+   
 }