PDA

View Full Version : validation with condition



jonasnas
May 21st, 2007, 11:39 AM
hi,
i have one form for saving and editing projects.( if in url is "id" then edit, else->save). when i enter data in this form, i need that validator would validate some fields according some other fields. my form registers such project's fields :


private String name;

private String status;
private Date startDate;

private Date endDate;

private int probability;

private Branch branch;


i want, that if user entered status "ongoing", the validator would chek if fields "startDate" and "endDate" is not empty and has a good date format. for that i use such validator :


public boolean supports(Class c) {
return Project.class.isAssignableFrom(c);
}

public void validate(Object command, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "startDate", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "endDate", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "client.id", "error.required");


and also has such method in form controler:


protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(
dateFormat, false));


what i need is that if project status is set to some other status (not "ongoing") the validator wouldnt check date fields(startDate and endDate) and would not do some validations that does for status "ongoing" .

jonasnas
May 21st, 2007, 12:01 PM
if i check the object comand in validation it works ok with fiels that are not date format.



public void validate(Object command, Errors errors) {
Project project = (Project)command;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "error.required");

if(!project.getStatus().equals(Project.INTERNAL)){//if status "internal" then do not check
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "startDate", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "endDate", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "client.id", "error.required");
}
}


this validation doesnt require client field if status is "internal" but stil validates dates. i think this is smth with initBinder

dr_pompeii
May 21st, 2007, 03:46 PM
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "startDate", "error.required");
try to avoid this type of validation for variables type date,
is some problematic how you seen , if you send the submit event, the variables type date are not considerated empty, instead the validator see they like null

in initBinder is the important part, post your code to see what is missing or wrong

regards

jonasnas
May 22nd, 2007, 03:17 AM
this is all validation i want to do if staus is NOT "internal"


import ideja.insight.domain.Project;
import ideja.insight.web.util.WebUtils;

import java.util.Date;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

public class ProjectValidator implements Validator {

public static final long DURATION = 1830; //duration in days - 5 years and a bit more

public boolean supports(Class c) {
return Project.class.isAssignableFrom(c);
}

public void validate(Object command, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "startDate", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "endDate", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "client.id", "error.required");




if (!errors.hasErrors()) {
Project project = (Project)command;

Date startDate = project.getStartDate();
Date endDate = project.getEndDate();

if (startDate.after(endDate)){
errors.reject("error.dates");
}

if (!WebUtils.isValidDate(startDate)) {
errors.rejectValue("startDate", "error.invalidDate");
}
if (!WebUtils.isValidDate(endDate)) {
errors.rejectValue("endDate", "error.invalidDate");
}

long from = startDate.getTime();
long to = endDate.getTime();

long difference = to - from;
long days = Math.round(difference/(1000*60*60*24));

if (days > DURATION){
errors.reject("error.duration");
}
}
}
}


if status IS internal it should check only if "name" is not null. i tried to add condition check (like i told earlier) but it still cheks dates fields:


public void validate(Object command, Errors errors) {
Project project = (Project)command;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "error.required");

if(!project.getStatus().equals(Project.INTERNAL)){//if status "internal" then do not check
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "startDate", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "endDate", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "client.id", "error.required");
}


like i said it is working with clients.id but not with dates.
here is my all form cotroller:



package ideja.insight.web;

import ideja.insight.dao.ProjectDao;
import ideja.insight.dao.TaskDao;
import ideja.insight.dao.ClientDao;
import ideja.insight.domain.ProjectsTasks;
import ideja.insight.domain.Branch;
import ideja.insight.domain.Client;
import ideja.insight.domain.TaskType;
import ideja.insight.domain.Project;
import ideja.insight.web.util.WebUtils;
import ideja.insight.web.util.CheckBoxListItem;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.propertyeditors.CustomDa teEditor;
import org.springframework.beans.propertyeditors.CustomNu mberEditor;
import org.springframework.dao.DataIntegrityViolationExce ption;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBin der;
import org.springframework.web.servlet.ModelAndView;

public class ProjectFormController extends FormController {

private ProjectDao projectDao;

private TaskDao taskDao;

private ClientDao clientDao;

public ProjectFormController() {
setCommandName("projectForm");
}

public void setProjectDao(ProjectDao projectDao) {
this.projectDao = projectDao;
}

public void setClientDao(ClientDao clientDao) {
this.clientDao = clientDao;
}

public void setTaskDao(TaskDao taskDao) {
this.taskDao = taskDao;
}

protected Map referenceData(HttpServletRequest request) throws Exception {
Map model = new HashMap();
model.put("clients", clientDao.loadAll());
model.put("probabilities", Project.getProbabilities());
model.put("statuses", Project.getStatuses());
model.put("statusesRestricted", Project.getStatusesRestricted());
model.put("internalProject", Project.INTERNAL);
model.put("notworkedProject", Project.NOTWORKED);
return model;
}

protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(
dateFormat, false));

NumberFormat nf = NumberFormat.getNumberInstance();
nf.setParseIntegerOnly(true);
binder.registerCustomEditor(java.lang.Integer.clas s,
new CustomNumberEditor(java.lang.Integer.class, nf, true) {

public void setAsText(String text) {
text = text.trim();
if (text.equals("")) {
text = "0";

} else if (text.equals("transient")) {
setValue(null);
return;

}
super.setAsText(text);
}
});
}

protected ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws Exception {

Project project = (Project) command;
boolean taskDelete = false;
try {
if (project.isTransient()) {
projectDao.saveProject(project);
projectDao.updateProjectTasks(project);
} else {
projectDao.updateProject(project);
taskDelete = true;
projectDao.updateProjectTasks(project);
}
} catch (DataIntegrityViolationException dive) {
if(taskDelete == false){
errors.reject("error.integrity.project");
return showForm(request, response, errors);
}else{
errors.reject("error.delete.task");
return showForm(request, response, errors);
}
}

String choice = request.getParameter("assign");

if (choice != null)
response.sendRedirect("projectAssign.htm?id="+project.getId().toString());
else
response.sendRedirect(WebUtils.getTraceBack(reques t, "project"));
return null;
}

protected Object formBackingObject(HttpServletRequest request)
throws Exception {
Project project = null;
String id = request.getParameter("id");

if (id == null) {
project = new Project();
project.setBranch(new Branch());
project.setClient(new Client());
project.setCheckBoxes(loadCheckBoxes(project));
} else {
project = projectDao.loadProject(Integer.valueOf(id));
String status = project.getStatus();
if (!status.equals(Project.NOTWORKED) && !status.equals(Project.INTERNAL)) {
project.setCheckBoxes(loadCheckBoxes(project));
}
}
return project;
}

private List loadCheckBoxes(Project project)
{
List list = new ArrayList();
List allTasks = taskDao.getActive();
for (Iterator taskType = allTasks.iterator(); taskType.hasNext(); ) {
TaskType task = (TaskType)taskType.next();
CheckBoxListItem checkBox = new CheckBoxListItem();
checkBox.setId(task.getId());
checkBox.setName(task.getName());
checkBox.setActive(task.isActive());
checkBox.setChecked(false);
checkBox.setInProject(isTaskInProject(task.getId() .intValue(), project));
list.add(checkBox);
}
return list;
}

private boolean isTaskInProject(int id, Project project)
{
List projectsTasks;
if (project.isTransient()) {
return false;
} else {
projectsTasks = projectDao.loadProjectsTasks(project);
}

for (Iterator projTask = projectsTasks.iterator(); projTask.hasNext(); ) {
ProjectsTasks pTask = (ProjectsTasks)projTask.next();
int pTaskID = pTask.getTaskType().getId().intValue();
if (pTaskID == id) return true;
}
return false;
}
}



and i dont think this(under this line) code may have influence in dates validation, because when it checks project's status and in case it is "internal" it should not be executed at all. and it doesnt check client.id if it is internal and only cheks dates fields. so i think the problem is not in these lines


(if project is NOT "internal"){
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "client.id", "error.required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "endDate", "error.required");
}


maybe its possible to do some condition checking in initBinder or is some extra method which i should override. im not good in spring so im just thinking where could be a problem :)

thanks