package org.osgl.util;

import org.osgl.Osgl;
import org.osgl.exception.NotAppliedException;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Implement {@link PropertySetter} using Java reflection
 */
public class ReflectionPropertySetter<OBJECT, PROP> extends ReflectionPropertyHandler implements PropertySetter<OBJECT, PROP> {

    public ReflectionPropertySetter(Class c, Method m, Field f) {
        super(c, m, f);
    }

    @Override
    public Void apply(OBJECT object, PROP prop) throws NotAppliedException, Osgl.Break {
        setProperty(object, prop);
        return null;
    }

    private void setProperty(OBJECT object, PROP value) throws NotAppliedException, Osgl.Break {
        if (null == object) {
            return;
        }
        ensureMethodOrField(object);
        try {
            if (null != m) {
                m.invoke(object, value);
            } else {
                f.set(object, value);
            }
        } catch (Exception e) {
            throw E.unexpected(e);
        }
    }

}

@@ -249,38 +249,38 @@
 nPropertySetter%3C
-OBJECT
+ENTITY
 , PROP%3E extends 
@@ -331,22 +331,22 @@
 ySetter%3C
-OBJECT
+ENTITY
 , PROP%3E 
@@ -485,32 +485,33 @@
 ply(
-OBJECT object
+ENTITY entity
 , PROP 
-prop
+value
 ) th
@@ -573,20 +573,21 @@
 rty(
-object, prop
+entity, value
 );%0A 
@@ -646,21 +646,21 @@
 rty(
-OBJECT object
+ENTITY entity
 , PR
@@ -730,22 +730,22 @@
 null == 
-object
+entity
 ) %7B%0A    
@@ -798,22 +798,22 @@
 OrField(
-object
+entity
 );%0A     
@@ -837,215 +837,425 @@
     
-if (null != m) %7B%0A                m.invoke(object, value);%0A            %7D else %7B%0A                f.set(object, value);%0A            %7D%0A        %7D catch (Exception e) %7B%0A
+doSet(entity, value);%0A        %7D catch (Exception e) %7B%0A            throw E.unexpected(e);%0A        %7D%0A    %7D%0A%0A    protected void doSet(Object entity, Object value) throws Exception %7B%0A        value = convertValue(value);%0A        if (null != m) %7B%0A            m.invoke(entity, value);%0A        %7D else %7B%0A            f.set(entity, value);%0A    
     
+%7D%0A
     
+%7D%0A%0A
     
-throw E.unexpected(e);%0A        %7D
+protected Object convertValue(Object value) %7B%0A        return value;
 %0A   

allow inject value transform logic in ReflectionPropertySetter