You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by Guido Sohne <ca...@yahoo.com> on 2001/06/10 10:14:37 UTC

validating action for use with intake, comments ?

I've done some work on validating input data with an app that already uses
Turbine but didn't know use Intake until now. I wrote this class below that
seems to help when doing validation in Actions.

public abstract class ValidatingAction extends VelocityAction
{    
    private Context my_context;
    private RunData my_data;
    private IntakeTool my_intake;
    private boolean is_valid;

    /**
     * Check to see if all the data presented is indeed
     * valid. 
     * @returns a <code>boolean</code> value
     */
    public boolean isAllValid()
        throws Exception
    {
        is_valid = false;
        
        if (my_intake != null && my_intake.isAllValid())
        {
            is_valid = true;
        }

        return is_valid;
    }

    public void initValidation(RunData data, Context context)
    {
        my_context = context;
        my_data = data;
        my_intake = (IntakeTool) context.get("intake");
    }

    public Object retrieve(String groupName, Object obj)
        throws Exception
    {
        my_intake.get(groupName, IntakeTool.DEFAULT_KEY).setProperties(obj);
        return obj;
    }

    public void redo(String screen, String message)
    {
        my_data.setMessage(message);
        setTemplate(my_data, screen);
    }

    public void populate(String groupName, Object obj)
        throws Exception
    {
        Group group = my_intake.get(groupName, IntakeTool.DEFAULT_KEY);
        group.getProperties(obj);
    }
}

The populate method is the reason why I submitted a patch yesterday to include a getProperties method into the Intake Group.java code. We'll see why shortly ...

A few things bother me about this code:-

Context and RunData are kept as private variables. Does this affect changes made in a class that inherits from this action ? To be more specific, lets look at some code that is in a class that inherits from this particular action. Lines that use the class above are marked with asterisks.

    public 
void doEdit (RunData data, Context context)
        throws Exception
    {
*       initValidation(data, context);

        Department dept = new Department();
        NumberKey nk = new
NumberKey(data.getParameters().getString("rowid"));

        Criteria crit = new Criteria();
        crit.add(DepartmentPeer.ROWID, nk);

        Vector v = DepartmentPeer.doSelect(crit);
        Enumeration e = v.elements();

        if(e.hasMoreElements())
            dept = (Department) e.nextElement();

        data.setMessage("Editing " + dept.getName() + " Department ");
        setTemplate(data, "AddDepartment.vm");

*       populate("Department", dept);
    }

Note that populate("Department", dept) sticks the dept object that was just
created into the Department Intake group. I noticed that if I changed a
field in such a way that the data was invalid, my screen would try and do a
create instead of an update. This was because I relied on sticking a
department object into context to help the template decide whether or not to
present update or insert event buttons. The whole reason for doing this is
to enable one to edit data by clicking on a link that contains the primary
key of the object in question.

With the populate method, I no longer need to keep a department in context
because it's already inside Intake with the correct values and waiting to be
edited before form submission / validation.

It bothers me that initValidation(data, context) has to be called by this
code. I wish there was a way in which this could work more transparently in
such a way that data and context are set up and available for use. One could
use null values and create private data and context when necessary *but*
then one would have to pass in data and context to every method, which kind
of defeats the purpose of the whole thing.

Another worry would be that if one keeps a private data and context, what
will happen if a method does something to change data in the class that is
inheriting from ValidatingAction ? Will the two copies of RunData get out of
sync or do they stay the same ? Java uses references to point to objects so
I think they would keep in sync but correct me if I am wrong ...

Here's another example ...

public void doUpdate(RunData data, Context context)
        throws Exception
    {
        initValidation(data, context);
        if(!isAllValid())
        {
            redo(ScreenName, "Correct Mistakes and Try Again");
            return;
        }

        Department entry = new Department();
        retrieve("Department", entry);

        entry.setModified(true);
        entry.setNew(false);
        entry.save();

        data.setMessage(StringConstants.deptUpdate);
        setTemplate(data, "ShowDepartments.vm");
    }

To my way of thinking, having a ValidatingAction class keeps logic within
event methods in Actions reasonably clear and with minimal code. This really
helps when teaching others how to do web applications using Turbine without
having to explain how every single thing works.

Hope this helps someone. Any comments ?


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-dev-help@jakarta.apache.org