package org.seasar.tapestry.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * @author maruo_syunsuke
 */
public class AccessaUtil {
    AccessaUtil(){}
    
    public static String getPropertyName( Method method ) {
        String methodName = method.getName();
        return methodName.substring( 3, 4 ).toLowerCase()
                + methodName.substring( 4 );
    }

    public static boolean checkMethod( Method method, String head, int argCount, boolean retVoid ) {
        if( isNotNameStartWith(method,head) )       return false;
        if( isPublic(method) )                      return false;
        if( isReturnVoid(method) != retVoid )        return false;
        if( isNotEqualArgCount(method, argCount ) ) return false;
        return true;
    }
    public static boolean isGetterMethod( Method method ) {
        return checkMethod( method, "get", 0, false );
    }
    public static boolean isSetterMethod( Method method ) {
        return checkMethod( method, "set", 1, true );
    }
    public static boolean isNotNameStartWith( Method method, String str ) {
        String methodName = method.getName();
        return methodName.startsWith( str ) == false;
    }
    public static boolean isReturnVoid( Method method ) {
        return method.getReturnType().equals( void.class );
    }
    public static boolean isPublic( Method method ) {
        return ( method.getModifiers() | Member.PUBLIC ) == 0;
    }
    public static boolean isNotEqualArgCount( Method method, int count ) {
        return method.getParameterTypes().length != count ;
    }

    public static Object getterInvoke(Object target, Method method){
        try {
            return method.invoke(target,new Object[0]);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null ;
    }
    public static void setterInvoke(Object target, Method method, Object obj){
        try {
            method.invoke(target,new Object[]{obj});
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    public static boolean getterToSetter(
            Object targetFrom, Method methodFrom,
            Object targetTo, Method methodTo ){
        Class getObjectClass = methodFrom.getReturnType();
        Class setObjectClass = methodTo.getParameterTypes()[0];
        if( setObjectClass.isAssignableFrom(getObjectClass) == false ) 
            return false ;
        setterInvoke(targetTo,methodTo,getterInvoke(targetFrom,methodFrom));
        return true ;
    }
    public static Map wrapperMap = null ;

    public static Class primitiveToWrapper(Class clazz){
        if( wrapperMap == null ){
            wrapperMap.put( boolean.class,  Boolean.class );
            wrapperMap.put( int.class,      Integer.class );
            wrapperMap.put( char.class,     Character.class );
            wrapperMap.put( byte.class,     Byte.class );
            wrapperMap.put( short.class,    Short.class );
            wrapperMap.put( long.class,     Long.class );
            wrapperMap.put( float.class,    Float.class );
            wrapperMap.put( double.class,   Double.class );
        }
        if( clazz.isPrimitive() ){
            return (Class)wrapperMap.get(clazz);
        }
        return clazz ;
    }
}
