The problem of getting the validation information is really a problem of where one gets meta-data from. Some meta-data depends on context, and some is fixed, and that is really the indicator for where it should be put. Another piece of meta-data is the human readable title for the attribute. Again, this can be context dependent or fixed based on the bean. I've included a list of meta-data that I can think of off-hand, but I expect there are more pieces that I haven't thought of yet. We might want to consider a standard method of getting access to all meta-data, based on context and bean. Here is the list: Name of attribute - human readable SQL name of attribute Read method Write method is Transient >From Converter (ie toString) To Converter Comparator Validator (Java) Script Validator (ie JavaScript) List of valid values Approximate display size (not sure what values this would take - perhaps characters?) "Extended" Type (ie a String could be the actual type, but really only email addresses are allowed)
This is kind of like BeanProperties, but there are more pieces. The things that they are likely to depend on are: Locale TimeZone Form name/id Database Type User Preferences (this list probably needs to be configurable and changeable based on the system requirements) Some of these might be fixed, and some might be variable. I think it is possible to create something like an "Introspector" that would know how to look these up in a number of places. The ones I'd like to see implemented are: 1) Definition of meta-data inside bean class itself 2) Definition of meta-data inside separate class 3) Definition of meta-data inside per-bean XML file 4) Definition of meta-data inside per-application XML file with any combination of these allowed, with the preference order being configurable. The information provided should be done in a way such as to allow caching when possible, and when not possible, to allow just the required information to be dynamically generated. If something like this is NOT done, then we will end up with a dozen or so different, unrelated meta-data definition files that each have slightly different syntax and requirements for access, and all are required to be updated on a change to a bean. Bill Wallace (716) 214-8872 Fax: (716) 295-4718 Element K 'the knowledge catalyst' www.elementk.com "Sobkowski, Andrej" <Andrej.Sobkowski@em To: "'Struts Developers List'" ergis.com> <[EMAIL PROTECTED]> cc: 11/02/01 02:03 PM Please respond to Subject: RE: Validator design considerations "Struts Developers List" Ted, thanks for your answer. I understand your idea of "initial validation". And I also agree with "Generally, objects should have dominion over their own data". But in the case of the validation process, IMHO the bean is the data used by a potentially external validation process (and not vice-versa). What if the validation on the same bean is different depending on the app context? It wouldn't be "clean" (for lack of better word) to consider both validations inside the bean itself (validate())... hence the advantage of having separate validation processes on the same bean (related to different app contexts i.e. different actions). Am I missing the point? >We could definately use more standard, backend validators, but, >personally, I would say that the framework object that calls the >standard validator with the property in question should be the >ActionForm, or a business object, and not the Action or ActionServlet >directly. In the current Struts version, the validate() on the FormBean is called by the ActionServlet.performValidate(...) method, isn't it? The validation is part of the whole process that is controlled by the ActionServlet - from a "procedural" point of view - and the same applies if the validate() is in the FormBean or in the Action (the call is simply made on different entities but in the same place). Or not? A salomonic suggestion :) we could have different levels of validators: bean-related and action-related. The first ones will take care of first-level validations that always apply to the bean; the second will be context-specific and called only if the first validations passed. But by separating the validation process (by taking it out of the bean itself), it would be possible to dynamically associate a validation process (validator) with a bean/action. Example in struts-config.xml: <!-- Global validators: pre-defined group of validators --> <global-validator name="myValidator" <validation ... /> <validation ... /> </global-validator> <!-- Bean-specific validations --> <form-bean name="myForm" type="com.mycompany.myFormBean"> <validation property=... /> (see previous message for details) <validation property=... /> </form-bean> <!-- Dynamic link to global validator --> <form-bean name="myForm2" type="com.mycompany.myFormBean2"> <validation link="myGlobalValidator" /> (link to validator defined above) </form-bean> <!-- Action-specific validation --> <action path="/myPath" type="com.mycompany.myActionWithValidation" name="myForm"> <validation property=... /> (see previous message for details) </action> Again, in my personal opinion, all of the above would be cleaner by separating the validators from the beans themselves. Did I manage to change your mind? :) Andrej -----Original Message----- From: Ted Husted [mailto:[EMAIL PROTECTED]] Sent: Friday, November 02, 2001 12:40 PM To: Struts Developers List Subject: Re: Validator design considerations Andrej Sobkowski wrote: > - The form bean itself is a "special data holder" and shouldn't be aware of > how its data is validated. Do you agree? I'm not sure that I do. I like to think of the ActionForm as a firewall. If it has passes the intial validation, then I know it is "safe" to use, and can passed along to business methods. Generally, objects should have dominion over their own data. Under the current model, the bean is not even passed to the Action until it is validated. The Action may undertake additional validation, usually in collaboration with the business model, but I think it is valid for an ActionForm to know whether it's String values pass some form of "prima facia" validation. There is usually additional validation at the business logic level, but this is different from the type of validation we need on ActionForms -- like did they even enter anything? Could it even be a number? I do believe we should be able to incorporate the XML configuration in to the Struts config, so that it is near the ActionForm bean it validates, but I'm not sure if "primary" validation should be delegated to another object, if that's what you're suggesting. We could definately use more standard, backend validators, but, personally, I would say that the framework object that calls the standard validator with the property in question should be the ActionForm, or a business object, and not the Action or ActionServlet directly. -- Ted Husted, Husted dot Com, Fairport NY USA. -- Custom Software ~ Technical Services. -- Tel +1 716 737-3463 -- http://www.husted.com/struts/ Andrej Sobkowski wrote: > > Hello All, > > I have a set of design considerations/suggestions for the Validation > Framework in Struts. Let me know if I'm totally missing the point. > > I like the whole Validator approach, in particular the XML configuration. I > believe that's the way to go, but I'd like to discuss a few points. > > DISCUSSION: The Validator is quite "linked" to Servlet's stuff > (HttpServletRequest) and to FormBean. If I got it right, currently the > Validator needs a set of parameters to be passed to the ValidatorAction, > including the bean to validate, the Field and some Servlet parameters. > > In a similar way, the validation process is linked to the FormBean > (validate() in FormBean class). > > Shouldn't they be separate? > - The Action should take care of the HTTP stuff while the Validator should > only have knowledge of the bean and the corresponding fields to be > validated. > - The form bean itself is a "special data holder" and shouldn't be aware of > how its data is validated. Do you agree? > > I was thinking at something like the following (pseudo-code): > > * CONFIGURATION file (new DTD for struts-config.xml or separate file) > <action path="/login" > type="com.mycompany.myActionWithValidation" > name="myForm"> > <!-- add validation on myForm's property 'lastName' that will check via > a SizeValidator > that the size of the field is between 1 and 15 chars. If not, the > message will be > returned in the ValidationException (I18N can be added easily) --> > <validation property="lastName" > validator="com.mycompany.SizeValidator" > arg0="1" > arg1="15" > message="Last Name is mandatory and can't be longer than 15 > chars" /> > ... > </action> > > * JAVA CODE > public interface IValidator(Object bean) { > +validate() throws ValidationException; > } > > public class Action { > ... > +addValidator(IValidator val) > +validators(): Iterator // returns an Iterator on all validators for the > action > } > > // Validator that checks if text size is >min and < max (for example). > // It can be easily extended to check int min/max and so on. > public class SizeValidator { > ... // min/max > > public void validate(Object bean) throws ValidationException { > Object value = getPropertyValue(bean); > if (value instanceof String) { > // Check String size > String check = (String)value; > if ((check.length() > maxSize) || > (check.length() < minSize)) { > // Validation failed: throw exception > // with corresponding error message (defined in conf) > throwException(getValidationMessage()); > } > } else { > // Error, wrong class type... > } > } > } > > // Minor changes to ActionServlet > public class ActionServlet { > ... > public void processInitValidatorsForAction(..) { > // By reading the XML configuration file, the ActionServlet will execute a > set of addValidator(..) > // For example, consider the following XML struts-config.xml (DTD to be > modified) > // <action > curAction.addValidator(new SizeValidator("lastName", "1", "15"); > curAction.addValidator(new RegExpValidator("phone", "(999)999-9999"); > ... > } > > // Executes all validators on FormBean(s) for action executed > public ActionErrors processValidate(...) { > Iterator it = action.validators(); > try { > ((Validator)it.next()).validate(formBean); // the validator validates > the form bean only > } catch (ValidationException e) { > Log.debug("Validation failed!", e); > errors.addError(e.getMessage()); // Add multilanguage > } > } > } > > Useless to say, this is only a high-level point of view. It does work on my > prototype (no XML config), but it can be enhanced and optimized in many > ways. I think it's also conceptually pretty close to what is currently done > in the Validator. > > The Validators can be designed as desired. To compare two values, simply > define a validator like CompareValidator(property1, property2, compareRule) > with compareRule = "<", ">",... > > What do you think? > > Thanks. > > Andrej > > _________________________________________________________________ > Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp > > -- > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > > Hello All, > > I have a set of design considerations/suggestions for the Validation > Framework in Struts. Let me know if I'm totally missing the point. > > I like the whole Validator approach, in particular the XML configuration. I > believe that's the way to go, but I'd like to discuss a few points. > > DISCUSSION: The Validator is quite "linked" to Servlet's stuff > (HttpServletRequest) and to FormBean. If I got it right, currently the > Validator needs a set of parameters to be passed to the ValidatorAction, > including the bean to validate, the Field and some Servlet parameters. > > In a similar way, the validation process is linked to the FormBean > (validate() in FormBean class). > > Shouldn't they be separate? > - The Action should take care of the HTTP stuff while the Validator should > only have knowledge of the bean and the corresponding fields to be > validated. > - The form bean itself is a "special data holder" and shouldn't be aware of > how its data is validated. Do you agree? > > I was thinking at something like the following (pseudo-code): > > * CONFIGURATION file (new DTD for struts-config.xml or separate file) > <action path="/login" > type="com.mycompany.myActionWithValidation" > name="myForm"> > <!-- add validation on myForm's property 'lastName' that will check via > a SizeValidator > that the size of the field is between 1 and 15 chars. If not, the > message will be > returned in the ValidationException (I18N can be added easily) --> > <validation property="lastName" > validator="com.mycompany.SizeValidator" > arg0="1" > arg1="15" > message="Last Name is mandatory and can't be longer than 15 > chars" /> > ... > </action> > > * JAVA CODE > public interface IValidator(Object bean) { > +validate() throws ValidationException; > } > > public class Action { > ... > +addValidator(IValidator val) > +validators(): Iterator // returns an Iterator on all validators for the > action > } > > // Validator that checks if text size is >min and < max (for example). > // It can be easily extended to check int min/max and so on. > public class SizeValidator { > ... // min/max > > public void validate(Object bean) throws ValidationException { > Object value = getPropertyValue(bean); > if (value instanceof String) { > // Check String size > String check = (String)value; > if ((check.length() > maxSize) || > (check.length() < minSize)) { > // Validation failed: throw exception > // with corresponding error message (defined in conf) > throwException(getValidationMessage()); > } > } else { > // Error, wrong class type... > } > } > } > > // Minor changes to ActionServlet > public class ActionServlet { > ... > public void processInitValidatorsForAction(..) { > // By reading the XML configuration file, the ActionServlet will execute a > set of addValidator(..) > // For example, consider the following XML struts-config.xml (DTD to be > modified) > // <action > curAction.addValidator(new SizeValidator("lastName", "1", "15"); > curAction.addValidator(new RegExpValidator("phone", "(999)999-9999"); > ... > } > > // Executes all validators on FormBean(s) for action executed > public ActionErrors processValidate(...) { > Iterator it = action.validators(); > try { > ((Validator)it.next()).validate(formBean); // the validator validates > the form bean only > } catch (ValidationException e) { > Log.debug("Validation failed!", e); > errors.addError(e.getMessage()); // Add multilanguage > } > } > } > > Useless to say, this is only a high-level point of view. It does work on my > prototype (no XML config), but it can be enhanced and optimized in many > ways. I think it's also conceptually pretty close to what is currently done > in the Validator. > > The Validators can be designed as desired. To compare two values, simply > define a validator like CompareValidator(property1, property2, compareRule) > with compareRule = "<", ">",... > > What do you think? > > Thanks. > > Andrej > > _________________________________________________________________ > Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp > > -- > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED] > For additional commands, e-mail: <mailto:[EMAIL PROTECTED] > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>