All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gw.lang.parser.coercers.BlockCoercer Maven / Gradle / Ivy

There is a newer version: 1.18.2
Show newest version
/*
 * Copyright 2014 Guidewire Software, Inc.
 */

package gw.lang.parser.coercers;

import gw.lang.reflect.IFunctionType;
import gw.lang.reflect.IType;
import gw.lang.parser.IBlockClass;
import gw.lang.function.IBlock;
import gw.config.CommonServices;
import gw.util.GosuClassUtil;

import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Set;

public class BlockCoercer extends BaseCoercer
{
  private static final BlockCoercer INSTANCE = new BlockCoercer();

  private BlockCoercer()
  {
  }

  public Object coerceValue( IType typeToCoerceTo, Object value )
  {
    final IBlock blk = (IBlock)value;
    Class aClass = blk.getClass();
    final Method finalInvoke = getInvokeMethod( aClass );
    final IFunctionType funType = (IFunctionType)typeToCoerceTo;

    Set classes = GosuClassUtil.getAllInterfaces( aClass );
    Class[] interfaces = classes.toArray( new Class[classes.size()] );

    return Proxy.newProxyInstance( blk.getClass().getClassLoader(), interfaces, new InvocationHandler()
    {
      @Override
      public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
      {
        if( IBlockClass.INVOKE_METHOD_NAME.equals( method.getName() ) )
        {
          Object val = finalInvoke.invoke( blk, args );
          return CommonServices.getCoercionManager().convertValue( val, funType.getReturnType() );
        }
        else if( IBlockClass.INVOKE_WITH_ARGS_METHOD_NAME.equals( method.getName() ) )
        {
          Object val = blk.invokeWithArgs( (Object[]) args[0] );
          return CommonServices.getCoercionManager().convertValue( val, funType.getReturnType() );
        }
        else
        {
          return method.invoke( blk, args );
        }
      }
    } );
  }

  private Method getInvokeMethod( Class aClass )
  {
    Method invokeMethod = null;
    for( Method method : aClass.getMethods() )
    {
      if( method.getName().equals( IBlockClass.INVOKE_METHOD_NAME ) )
      {
        invokeMethod = method;
      }
    }
    if( invokeMethod == null )
    {
      throw new IllegalStateException( "Unable to find an invoke method on class " + aClass.getName() );
    }
    return invokeMethod;
  }

  public boolean isExplicitCoercion()
  {
    return false;
  }

  public boolean handlesNull()
  {
    return false;
  }

  public int getPriority( IType to, IType from )
  {
    return 2;
  }

  public static BlockCoercer instance()
  {
    return INSTANCE;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy