I have been working on a couple of things for Maverick, to give it some of the stuff I like from other frameworks. I have added the concept of "actions" to a ControllerSingleton class I'm calling SuperController (couldn't think of anything else). The actions stuff lets you specify an action in the request parameters which will be translated into a call to a function in the controller. This lets you partition your work by objects and by functions. This is kind of a combination of the Maverick/Struts style of object partitioning and the Niggle function partitioning.
I'm also thinking of working on a validation framework modeled after the Struts new validation package. I think it's possible to even just re-use their framework as it's fairly separate. I actually don't like their design (as usual for Jakarta, over designed) but it makes a good start.
I've attached the SuperController class I wrote here so you can check it out. If you're interested in this direction, let me know and I'll coordinate with you. In order to get it to work, you'll need the latest Apache Commons BeanUtils (1.5.1).
Zed
package com.zedshaw.mavforum.control; import java.util.*;
/**
* Description of the Class
*
*@author zedshaw
*@created December 17, 2002
*/
public class FormResult {
private Map requestParams;
private Map errors;
/**
* Constructor for the FormResult object
*/
public FormResult() { }
/**
* Constructor for the FormResult object
*
*@param requestParams Description of the Parameter
*/
public FormResult(Map requestParams) {
this.requestParams = requestParams;
// TODO: use one of the faster maps from Jakarta commons
errors = new HashMap();
}
/**
* Gets the parameters attribute of the FormResult object
*
*@return The parameters value
*/
public Map getParameters() {
return requestParams;
}
/**
* Sets the parameters attribute of the FormResult object
*
*@param requestParams The new parameters value
*/
public void setParameters(Map requestParams) {
this.requestParams = requestParams;
}
/**
* Gets the errors attribute of the FormResult object
*
*@return The errors value
*/
public Map getErrors() {
return errors;
}
/**
* Sets the errors attribute of the FormResult object
*
*@param errors The new errors value
*/
public void setErrors(Map errors) {
this.errors = errors;
}
/**
* Adds a feature to the Error attribute of the FormResult object
*
*@param field The feature to be added to the Error attribute
*@param message The feature to be added to the Error attribute
*/
public void putError(String field, String message) {
errors.put(field, message);
}
/**
* Gets the error attribute of the FormResult object
*
*@param field Description of the Parameter
*@return The error value
*/
public String getError(String field) {
return (String) errors.get(field);
}
/**
* Description of the Method
*
*@return Description of the Return Value
*/
public boolean hasErrors() {
return errors.size() > 0;
}
/**
* Gets the parameter attribute of the FormResult object
*
*@param field Description of the Parameter
*@return The parameter value
*/
public Object getParameter(String field) {
Object[] params = (Object[]) requestParams.get(field);
// we do this to protect against when the parameter doesn't exist
return params != null ? params[0] : null;
}
/**
* Gets the parameterArray attribute of the FormResult object
*
*@param field Description of the Parameter
*@return The parameterArray value
*/
public Object[] getParameterArray(String field) {
return (Object[]) requestParams.get(field);
}
}
package com.zedshaw.mavforum.control;
import org.infohazard.maverick.ctl.*;
import org.infohazard.maverick.flow.*;
import java.util.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.MethodUtils;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Description of the Class
*
*@author zedshaw
*@created December 16, 2002
*/
public class SuperController implements ControllerSingleton {
/**
* Description of the Field
*/
public final static Class[] CALL_TYPES = {ControllerContext.class,
FormResult.class};
/**
* Common name for the typical "success" view.
*/
public final static String SUCCESS = "success";
/**
* Common name for the typical "error" view.
*/
public final static String ERROR = "error";
/**
* This is the prefix for the methods, which the ACTION_KEY is appended to
*/
public final static String PERFORM_PREFIX = "perform";
/**
* This is what to look for in the request parameters when determining the
* action
*/
public final static String ACTION_KEY = "m.action";
/**
* Initializes the singleton with the configuration node.
*
*@param controllerNode Description of the Parameter
*@exception ConfigException Description of the Exception
*/
public void init(org.jdom.Element controllerNode) throws ConfigException {
// TODO: put configurations for things like validation here
System.out.println("init called in SuperController");
}
/**
* Sets up the servlet parameters and calls through to the parameterless
* rawPerform() method. Does not result in bean population.
*
*@param cctx Description of the Parameter
*@return Description of the Return Value
*@exception ServletException Description of the Exception
*@see Controller#perform
*/
public final String go(ControllerContext cctx) throws ServletException {
try {
// create the FormRequest to verify
FormResult form = new
FormResult(cctx.getRequest().getParameterMap());
// figure out where the request came from
// look up the validator for that URI
// validate the FormRequest
// determine the action
String m_action = cctx.getRequest().getParameter("m.action");
// call the requested method for that action, return the result
String performResult = null;
if (m_action != null) {
// setup the arguments
Object[] args = new Object[2];
args[0] = cctx;
args[1] = form;
// do the dynamic call
performResult = (String)
MethodUtils.invokeExactMethod(this, PERFORM_PREFIX + m_action, args, CALL_TYPES);
} else {
// just do the quick version if there is no m.action
field
performResult = this.perform(cctx, form);
}
return performResult;
} catch (Exception ex) {
throw new ServletException(ex);
}
}
/**
* This is the method you should override to implement application logic.
* Default implementation just returns "success".
*
*@param ctx Description of the Parameter
*@param form Description of the Parameter
*@return Description of the Return Value
*@exception Exception Description of the Exception
*/
public String perform(ControllerContext ctx, FormResult form) throws Exception
{
System.err.println("Perform ran in the SuperController");
return SUCCESS;
}
}
On Friday, December 20, 2002, at 10:17 AM, Victor Rodriguez wrote:
Hello All,
I'm using Maverick on a new project and I absoulutely love it. Soon I'll have to deal with validation and I was wondering whether there was any "Validation Framework" being implemented already, to which I could contribute to instead of just doing something for this project. I have little experience "doing validation", so I'd rather help implement an existing design that come up with my own.
If there is nothing going on, then perhaps someone would like to share their experiences handling this with Maverick? Could someone point me on the right direction to design something useful for any project and not this one in particular?
On a side note, as I said, I really like Maverick and I would like very much for it to continue being used, expanded, supported etc. I sometimes worry about the little traffic on the mailing list.. any idea if Maverick's user base is expanding?
Happy Holidays!
Best Regards,
Victor Rodriguez.
ps. My project uses velocity for the presentation layer, in case it is of any relevance.
-------------------------------------------------------
This SF.NET email is sponsored by: The Best Geek Holiday Gifts!
Time is running out! Thinkgeek.com has the coolest gifts for
your favorite geek. Let your fingers do the typing. Visit Now.
T H I N K G E E K . C O M http://www.thinkgeek.com/sf/
[INVALID FOOTER]
----- Zed A. Shaw http://www.zedshaw.com/
