[jboss-cvs] jboss-seam/src/main/org/jboss/seam/el ...

Gavin King gavin.king at jboss.com
Tue May 29 20:19:12 EDT 2007


  User: gavin   
  Date: 07/05/29 20:19:12

  Added:       src/main/org/jboss/seam/el      EL.java
                        OptionalParameterMethodExpression.java
                        SeamELFunctionMapper.java SeamELResolver.java
                        SeamExpressionFactory.java
  Log:
  moved EL stuff into its own package
  support optional FacesEvent parameter everywhere
  
  Revision  Changes    Path
  1.1      date: 2007/05/30 00:19:12;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/el/EL.java
  
  Index: EL.java
  ===================================================================
  package org.jboss.seam.el;
  
  import javax.el.BeanELResolver;
  import javax.el.CompositeELResolver;
  import javax.el.ELContext;
  import javax.el.ELResolver;
  import javax.el.ExpressionFactory;
  import javax.el.FunctionMapper;
  import javax.el.ListELResolver;
  import javax.el.MapELResolver;
  import javax.el.ResourceBundleELResolver;
  import javax.el.VariableMapper;
  
  
  import org.jboss.el.ExpressionFactoryImpl;
  import org.jboss.el.lang.FunctionMapperImpl;
  import org.jboss.el.lang.VariableMapperImpl;
  
  public class EL
  {
     private static final ELResolver EL_RESOLVER = createELResolver();
     public static final ELContext EL_CONTEXT = createELContext();
     
     public static final ExpressionFactory EXPRESSION_FACTORY = new SeamExpressionFactory( new ExpressionFactoryImpl() );
     //public static final ExpressionFactory EXPRESSION_FACTORY = new ExpressionFactoryImpl();
     
     private static ELResolver createELResolver()
     {
        CompositeELResolver resolver = new CompositeELResolver();
        resolver.add( new SeamELResolver() );
        resolver.add( new MapELResolver() );
        resolver.add( new ListELResolver() );
        resolver.add( new ResourceBundleELResolver() );
        resolver.add( new BeanELResolver() );
        return resolver;
     }
  
     private static ELContext createELContext()
     {
        return new ELContext()
        {
  
           @Override
           public ELResolver getELResolver()
           {
              return EL_RESOLVER;
           }
  
           @Override
           public FunctionMapper getFunctionMapper()
           {
              return new SeamELFunctionMapper( new FunctionMapperImpl() );
           }
  
           @Override
           public VariableMapper getVariableMapper()
           {
              return new VariableMapperImpl();
           }
           
        };
     }
     
  }
  
  
  
  1.1      date: 2007/05/30 00:19:12;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/el/OptionalParameterMethodExpression.java
  
  Index: OptionalParameterMethodExpression.java
  ===================================================================
  /**
   * 
   */
  package org.jboss.seam.el;
  
  import javax.el.ELContext;
  import javax.el.MethodExpression;
  import javax.el.MethodInfo;
  import javax.el.MethodNotFoundException;
  
  /**
   * 
   * @author Gavin King
   *
   */
  public class OptionalParameterMethodExpression extends MethodExpression
  {
      
      private MethodExpression withParam;
      private MethodExpression withNoParam;
      
     public OptionalParameterMethodExpression(MethodExpression withParam, MethodExpression withNoParam)
     {
        this.withParam = withParam;
        this.withNoParam = withNoParam;
     }
  
     @Override
     public MethodInfo getMethodInfo(ELContext ctx)
     {
        return withParam.getMethodInfo(ctx);
     }
  
     @Override
     public Object invoke(ELContext ctx, Object[] args)
     {
        try
        {
           return withParam.invoke(ctx, args);
        }
        catch (MethodNotFoundException mnfe)
        {
           try
           {
              return withNoParam.invoke(ctx, new Object[0]);
           }
           catch (MethodNotFoundException mnfe2)
           {
              throw mnfe;
           }
        }
     }
  
     @Override
     public String getExpressionString()
     {
        return withParam.getExpressionString();
     }
  
     @Override
     public boolean isLiteralText()
     {
        return withParam.isLiteralText();
     }
  
     @Override
     public boolean equals(Object object)
     {
        if ( !(object instanceof OptionalParameterMethodExpression) ) return false;
        OptionalParameterMethodExpression other = (OptionalParameterMethodExpression) object;
        return withParam.equals(other.withParam);
     }
  
     @Override
     public int hashCode()
     {
        return withParam.hashCode();
     }
      
   }
  
  
  1.1      date: 2007/05/30 00:19:12;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/el/SeamELFunctionMapper.java
  
  Index: SeamELFunctionMapper.java
  ===================================================================
  package org.jboss.seam.el;
  
  import java.lang.reflect.Method;
  import java.util.HashMap;
  import java.util.Map;
  
  import javax.el.FunctionMapper;
  
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.jboss.seam.security.SecurityFunctions;
  
  /**
   * Resolves Seam EL functions to their corresponding methods.
   *  
   * @author Shane Bryzak
   */
  public class SeamELFunctionMapper extends FunctionMapper
  {
     private static final String SEAM_EL_PREFIX = "s";
     
     private static Map<String,Method> methodCache = new HashMap<String,Method>();
     
     private static final LogProvider log = Logging.getLogProvider(SeamELFunctionMapper.class);
     
     private FunctionMapper functionMapper;
     
     public SeamELFunctionMapper()
     {
        this(null);
     }
     
     public SeamELFunctionMapper(FunctionMapper functionMapper)
     {
        this.functionMapper = functionMapper;
     }
     
     static 
     {
        cacheMethod("hasPermission", SecurityFunctions.class, "hasPermission", 
                 new Class[] {String.class, String.class, Object.class});
        cacheMethod("hasRole", SecurityFunctions.class, "hasRole",
                 new Class[] { String.class });      
     }
  
     @Override 
     public Method resolveFunction(String prefix, String localName) 
     {
        if (SEAM_EL_PREFIX.equals(prefix))
        {
           return methodCache.get(localName);
        }
        else if (functionMapper != null)
        {
           return functionMapper.resolveFunction(prefix, localName);
        }
        else
           return null;
     }  
     
     private static void cacheMethod(String localName, Class cls, String name, Class[] params)
     {
        try
        {
           Method m = cls.getMethod(name, params);
           methodCache.put(localName, m);         
        }
        catch (NoSuchMethodException ex)
        {
           log.warn(String.format("Method %s.%s could not be cached", cls.getName(), name));
        }
     }
     
  }
  
  
  
  1.1      date: 2007/05/30 00:19:12;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/el/SeamELResolver.java
  
  Index: SeamELResolver.java
  ===================================================================
  package org.jboss.seam.el;
  
  import java.util.Collection;
  import java.util.Iterator;
  import java.util.Map;
  
  import javax.el.ELContext;
  import javax.el.ELResolver;
  import javax.faces.model.DataModel;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.Init;
  
  /**
   * Allows the use of #{dataModel.size}, #{dataModel.empty},
   * #{collection.size}, #{map.size}, #{map.values}, #{map.keySet},
   * and #{map.entrySet}.
   * 
   * @author Gavin King
   *
   */
  public class SeamELResolver extends ELResolver
  {
  
     @Override
     public Class getCommonPropertyType(ELContext context, Object base)
     {
        return null;
     }
  
     @Override
     public Iterator getFeatureDescriptors(ELContext context, Object base)
     {
        return null;
     }
  
     @Override
     public Class getType(ELContext context, Object base, Object property)
     {
        return null;
     }
  
     @Override
     public Object getValue(ELContext context, Object base, Object property)
     {
        if (base==null)
        {
           if ( !Contexts.isApplicationContextActive() )
           {
              //if no Seam contexts, bypass straight through to JSF
              return null;
           }
           
           String name = (String) property;
           name = name.replace('$', '.');
           Object result = Component.getInstance(name);
           if (result==null)
           {
              result = Init.instance().getRootNamespace().getChild(name);
           }
           if (result!=null)
           {
              context.setPropertyResolved(true);
           }
           return result;
        }
        else if (base instanceof DataModel)
        {
           if ( "size".equals(property) )
           {
              context.setPropertyResolved(true);
              return ( (DataModel) base ).getRowCount();
           }
           else if ( "empty".equals(property) )
           {
              context.setPropertyResolved(true);
              return ( (DataModel) base ).getRowCount()==0;
           }
           else
           {
              return null;
           }
        }
        else if (base instanceof Collection)
        {
           if ( "size".equals(property) )
           {
              context.setPropertyResolved(true);
              return ( (Collection) base ).size();
           }
           else
           {
              return null;
           }
        }
        else if (base instanceof Map)
        {
           if ( "size".equals(property) )
           {
              context.setPropertyResolved(true);
              return ( (Map) base ).size();
           }
           else if ( "values".equals(property) )
           {
              context.setPropertyResolved(true);
              return ( (Map) base ).values();
           }
           else if ( "keySet".equals(property) )
           {
              context.setPropertyResolved(true);
              return ( (Map) base ).keySet();
           }
           else if ( "entrySet".equals(property) )
           {
              context.setPropertyResolved(true);
              return ( (Map) base ).entrySet();
           }
           else
           {
              return null;
           }
        }
        else
        {
           return null;
        }
     }
  
     @Override
     public boolean isReadOnly(ELContext context, Object base, Object property)
     {
        return base!=null && 
              ( (base instanceof DataModel) || (base instanceof Collection) || (base instanceof Map) );
     }
  
     @Override
     public void setValue(ELContext context, Object base, Object property, Object value) {}
  
  }
  
  
  
  1.1      date: 2007/05/30 00:19:12;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/el/SeamExpressionFactory.java
  
  Index: SeamExpressionFactory.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   * Copyright 2006, JBoss Inc., and individual contributors as indicated
   * by the @authors tag. See the copyright.txt in the distribution for a
   * full listing of individual contributors.
   *
   * This is free software; you can redistribute it and/or modify it
   * under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation; either version 2.1 of
   * the License, or (at your option) any later version.
   *
   * This software is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this software; if not, write to the Free
   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   */
  
  package org.jboss.seam.el;
  
  import javax.el.ELContext;
  import javax.el.ExpressionFactory;
  import javax.el.MethodExpression;
  import javax.el.ValueExpression;
  import javax.faces.event.FacesEvent;
  
  
  /**
   * Allows JSF action listener methods to not declare the
   * totally useless ActionEvent parameter if they don't
   * want to. 
   *
   * @author Gavin King
   */
  public class SeamExpressionFactory extends ExpressionFactory 
  {
     
      private static final Class[] NO_CLASSES = {};
      
      private ExpressionFactory expressionFactory;
      
      public SeamExpressionFactory(ExpressionFactory expressionFactory) 
      {
         this.expressionFactory = expressionFactory;
      }
      
      @Override
      public Object coerceToType(Object obj, Class targetType) 
      {
          return expressionFactory.coerceToType(obj, targetType);
      }
  
      @Override
      public MethodExpression createMethodExpression(ELContext elContext, String expression, Class returnType, Class[] paramTypes) 
      {
          if ( paramTypes.length==1 && FacesEvent.class.isAssignableFrom( paramTypes[0] ) )
          {
           return new OptionalParameterMethodExpression(
                   expressionFactory.createMethodExpression(elContext, expression, returnType, paramTypes),
                   expressionFactory.createMethodExpression(elContext, expression, returnType, NO_CLASSES)
                );
          }
          else
          {
             return expressionFactory.createMethodExpression(elContext, expression, returnType, paramTypes);
          }
      }
      
      @Override
      public ValueExpression createValueExpression(Object instance, Class expectedType) 
      {
          return expressionFactory.createValueExpression(instance, expectedType);
      }
  
      @Override
      public ValueExpression createValueExpression(ELContext elContext, String expression, Class expectedType) 
      {   
          return expressionFactory.createValueExpression(elContext, expression, expectedType);
      }
      
  }
  
  



More information about the jboss-cvs-commits mailing list