[ 
https://issues.apache.org/jira/browse/PIVOT-761?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13054934#comment-13054934
 ] 

dreamtangerine commented on PIVOT-761:
--------------------------------------

Well, I agree that validation belongs to other package, the logic is not inside 
BeanAdapter, but I think we can use it for validation. 

If we want make constrained beans (aka make a constrained data model with 
annotations in its properties),  I think BeanAdapter put method is a good place 
to call the validation framework because is where properties are assigned. 

In fact, we can create a BeanAdapterValidator derived from BeanAdapter that 
call the validation framework if we create two methods where fields are 
assigned or methods are called. All of this classes belonging to pivot-core.

For example :

class BeanAdapter
{
    protected void setField(Field field, Object bean, Object value) 
    {
        field.set(bean, value);
    }

    protected void callSetMethod(Method setterMethod, Object bean, Object value)
    {
        setterMethod.invoke(bean, new Object[] {value});
    }

    @Override
    public Object put(String key, Object value) {
        if (key == null) {
            throw new IllegalArgumentException("key is null.");
        }

        if (key.length() == 0) {
            throw new IllegalArgumentException("key is empty.");
        }

        Method setterMethod = null;

        if (value != null) {
            // Get the setter method for the value type
            setterMethod = getSetterMethod(key, value.getClass());
        }

        if (setterMethod == null) {
            // Get the property type and attempt to coerce the value to it
            Class<?> propertyType = getType(key);

            if (propertyType != null) {
                setterMethod = getSetterMethod(key, propertyType);
                value = coerce(value, propertyType);
            }
        }

        if (setterMethod == null) {
            Field field = getField(key);

            if (field == null) {
                throw new PropertyNotFoundException("Property \"" + key + "\""
                    + " does not exist or is read-only.");
            }

            Class<?> fieldType = field.getType();
            if (value != null) {
                Class<?> valueType = value.getClass();
                if (!fieldType.isAssignableFrom(valueType)) {
                    value = coerce(value, fieldType);
                }
            }

            try {
                field.set(bean, value);
            } catch (IllegalAccessException exception) {
                throw new 
RuntimeException(String.format(ILLEGAL_ACCESS_EXCEPTION_MESSAGE_FORMAT,
                    key, bean.getClass().getName()), exception);
            }
        } else {
            try {
                setterMethod.invoke(bean, new Object[] {value});
            } catch (IllegalAccessException exception) {
                throw new 
RuntimeException(String.format(ILLEGAL_ACCESS_EXCEPTION_MESSAGE_FORMAT,
                    key, bean.getClass().getName()), exception);
            } catch (InvocationTargetException exception) {
                throw new RuntimeException(String.format("Error setting 
property \"%s\" for type %s to value \"%s\"",
                    key, bean.getClass().getName(), "" + value), 
exception.getCause());
            }

        }

        Object previousValue = null;
        mapListeners.valueUpdated(this, key, previousValue);

        return previousValue;
    }
}

and class BeanAdapterValidator

class BeanAdapterValidator extends 
{
   @Override
    protected void setField(Field field, Object bean, Object value) 
    {
        ConstraintViolation violation = ConstraintManager.get().isValid(bean, 
value, field);

        if (null == violation)
          super.setField(field, bean, value) ;
        else
           throw new ConstraintViolationExcetion(violation) ;
    }

   @Override
    protected void callSetMethod(Method setterMethod, Object bean, Object value)
    {
        ConstraintViolation violation = ConstraintManager.get().isValid(bean, 
value, method);

        if (null == violation)
          super.setMethod(method, bean, value) ;
        else
           throw new ConstraintViolationExcetion(violation) ;
    }
}


On the other hand, Form (in fact Component)  also has logic for storing values 
into beans (method store), so I think that it do more than layout (maybe I am 
wrong). And maybe that logic can be extracted to a validation package in the 
pivot-wtk (but i think is difficult extract it).

In summary what I want is :

// Constrained model
Address adr = new Address() ;
Form form = ...

//  Set values to adr and if there are some constraint violated set a flag in 
the form child component.
form.storeWithValidation(adr) ;

or if the logic is outside Form class
ConraintWtkManager.get().store(adr, form) ;

That is all.
DreamTangerine.

> Test a more generic Validation approach on fields and Containers (Forms, etc)
> -----------------------------------------------------------------------------
>
>                 Key: PIVOT-761
>                 URL: https://issues.apache.org/jira/browse/PIVOT-761
>             Project: Pivot
>          Issue Type: Brainstorming
>          Components: wtk
>            Reporter: Sandro Martini
>            Assignee: Sandro Martini
>            Priority: Minor
>             Fix For: 2.1
>
>
> Investigating on this field ... both on validating single fields (not only 
> text input fields) and Container (like Forms), like in JSF.
> Some reference here:
> http://apache-pivot-developers.417237.n3.nabble.com/Text-validators-td3078385.html
> General idea: put investigation code under /skunk and the minimal set of 
> interfaces and classes, and the rest outside (in a dedicated subproject, here 
> or under apache-extras).

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to