001// Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 002// The Molly framework is freely distributable under the terms of an 003// MIT-style license. For details, see the molly pages web site at: 004// http://www.mollypages.org/. Use, modify, have fun ! 005 006package fc.web.forms; 007 008import javax.servlet.*; 009import javax.servlet.http.*; 010import java.io.*; 011import java.util.*; 012import java.util.regex.*; 013 014import fc.jdbc.*; 015import fc.io.*; 016import fc.util.*; 017 018 019/** 020Validates that a group of fields is filled by the user. By default, every 021field must be filled. However, optionally it can be specified that every 022field in the group is not filled (all empty), only 1 field is filled or 0231 or more fields (greater than zero) are filled. 024 025@author hursh jain 026**/ 027public final class VFilledGroup extends FormValidator 028{ 029Field[] fields; 030 031boolean allFilledOrEmpty; 032boolean onlyOneEmpty; 033boolean onlyOneFilled; 034boolean oneOrMoreFilled; 035 036static final boolean dbg = false; 037 038 039/** 040@param fields a non-empty list containting fields to be 041 checked. 042**/ 043public VFilledGroup(Form f, String name, String errorMessage, List fields) 044 { 045 //we must make a copy of the fields because the caller 046 //can change the list behind our back (by re-using the 047 //list variable during form creation) 048 049 this(f, name, errorMessage, 050 (Field[]) fields.toArray(new Field[0])); 051 } 052 053/** 054@param fields a non-empty array containting fields to be 055 checked. 056**/ 057public VFilledGroup(Form f, 058 String name, String errorMessage, Field[] fields) 059 { 060 super(f, name, errorMessage); 061 Argcheck.istrue(fields.length > 0, "specified field list was empty"); 062 this.fields = fields; 063 allFilledOrEmpty = true; 064 onlyOneEmpty = false; 065 onlyOneFilled = false; 066 oneOrMoreFilled = false; 067 } 068 069/** 070Calling this method will result in requiring that all fields 071must be filled except for any one empty field. Calling 072this method overrides any other methods that were called 073previously. 074*/ 075public VFilledGroup onlyOneEmpty() 076 { 077 allFilledOrEmpty = false; 078 onlyOneEmpty = true; 079 onlyOneFilled = false; 080 oneOrMoreFilled = false; 081 082 return this; 083 } 084 085/** 086Calling this method will result in requiring that all fields be 087empty except for exactly one filled field (any field). Calling 088this method overrides any other methods that were called 089previously. 090*/ 091public VFilledGroup onlyOneFilled() 092 { 093 allFilledOrEmpty = false; 094 onlyOneEmpty = false; 095 onlyOneFilled = true; 096 oneOrMoreFilled = false; 097 098 return this; 099 } 100 101/** 102Calling this method will result in requiring that one or more 103fields by filled (all the fields cannot be empty). Calling 104this method overrides any other methods that were called 105previously. 106*/ 107public VFilledGroup oneOrMoreFilled() 108 { 109 allFilledOrEmpty = false; 110 onlyOneEmpty = false; 111 onlyOneFilled = false; 112 oneOrMoreFilled = true; 113 114 return this; 115 } 116 117/** 118This is the default mode. Requires that all fields must be 119filled. Calling this method overrides any other methods that were 120called previously. 121*/ 122public VFilledGroup allFilledOrEmpty() 123 { 124 allFilledOrEmpty = true; 125 onlyOneEmpty = false; 126 onlyOneFilled = false; 127 oneOrMoreFilled = false; 128 129 return this; 130 } 131 132public boolean validate(FormData fd, HttpServletRequest req) 133 { 134 if (oneOrMoreFilled) 135 return v_oneOrMoreFilled(fd); 136 else if (onlyOneEmpty) 137 return v_onlyOneEmpty(fd); 138 else if (onlyOneFilled) 139 return v_onlyOneFilled(fd); 140 else 141 return v_allFilledOrEmpty(fd); 142 } 143 144private boolean v_oneOrMoreFilled(FormData fd) 145 { 146 int count = fields.length; 147 for (int n = 0; n < count; n++) 148 { 149 Field f = fields[n]; 150 if (f.isFilled(fd)) 151 return true; 152 } 153 154 return false; 155 } 156 157 158private boolean v_onlyOneFilled(FormData fd) 159 { 160 int count = fields.length; 161 boolean one_filled = false; 162 163 for (int n = 0; n < count; n++) 164 { 165 Field f = fields[n]; 166 if (dbg) System.out.println("field " + f.name + " isFilled()=" + f.isFilled(fd)); 167 if (f.isFilled(fd)) 168 { 169 if (one_filled) 170 return false; 171 one_filled = true; //latch 172 } 173 } 174 175 return true; 176 } 177 178 179private boolean v_onlyOneEmpty(FormData fd) 180 { 181 int count = fields.length; 182 boolean one_empty = false; 183 184 for (int n = 0; n < count; n++) 185 { 186 Field f = fields[n]; 187 if (dbg) System.out.println("field " + f.name + " isFilled()=" + f.isFilled(fd)); 188 if (! f.isFilled(fd)) 189 { 190 if (one_empty) 191 return false; 192 one_empty = true; //latch 193 } 194 } 195 196 return true; 197 } 198 199 200private boolean v_allFilledOrEmpty(FormData fd) 201 { 202 int count = fields.length; 203 boolean allempty = true; 204 boolean allfilled = true; 205 206 boolean result = true; 207 208 for (int n = 0; n < count; n++) 209 { 210 Field f = fields[n]; 211 if (dbg) System.out.println("field " + f.name + " isFilled()=" + f.isFilled(fd)); 212 if (f.isFilled(fd)) { //field is filled 213 allempty = false; //latch 214 } 215 else{ //field is not filled 216 //all othe fields must also be empty (we have to 217 //go thru the entire list) 218 allfilled = false; //latch 219 } 220 } 221 222 return (allempty || allfilled); 223 } 224 225 226}