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
006 package fc.web.forms;
007
008 import javax.servlet.*;
009 import javax.servlet.http.*;
010 import java.io.*;
011 import java.util.*;
012 import java.util.regex.*;
013
014 import fc.jdbc.*;
015 import fc.io.*;
016 import fc.util.*;
017
018
019 /**
020 Validates that a group of fields is filled by the user. By default, every
021 field must be filled. However, optionally it can be specified that every
022 field in the group is not filled (all empty), only 1 field is filled or
023 1 or more fields (greater than zero) are filled.
024
025 @author hursh jain
026 **/
027 public final class VFilledGroup extends FormValidator
028 {
029 Field[] fields;
030
031 boolean allFilledOrEmpty;
032 boolean onlyOneEmpty;
033 boolean onlyOneFilled;
034 boolean oneOrMoreFilled;
035
036 static final boolean dbg = false;
037
038
039 /**
040 @param fields a non-empty list containting fields to be
041 checked.
042 **/
043 public 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 **/
057 public 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 /**
070 Calling this method will result in requiring that all fields
071 must be filled except for any one empty field. Calling
072 this method overrides any other methods that were called
073 previously.
074 */
075 public VFilledGroup onlyOneEmpty()
076 {
077 allFilledOrEmpty = false;
078 onlyOneEmpty = true;
079 onlyOneFilled = false;
080 oneOrMoreFilled = false;
081
082 return this;
083 }
084
085 /**
086 Calling this method will result in requiring that all fields be
087 empty except for exactly one filled field (any field). Calling
088 this method overrides any other methods that were called
089 previously.
090 */
091 public VFilledGroup onlyOneFilled()
092 {
093 allFilledOrEmpty = false;
094 onlyOneEmpty = false;
095 onlyOneFilled = true;
096 oneOrMoreFilled = false;
097
098 return this;
099 }
100
101 /**
102 Calling this method will result in requiring that one or more
103 fields by filled (all the fields cannot be empty). Calling
104 this method overrides any other methods that were called
105 previously.
106 */
107 public VFilledGroup oneOrMoreFilled()
108 {
109 allFilledOrEmpty = false;
110 onlyOneEmpty = false;
111 onlyOneFilled = false;
112 oneOrMoreFilled = true;
113
114 return this;
115 }
116
117 /**
118 This is the default mode. Requires that all fields must be
119 filled. Calling this method overrides any other methods that were
120 called previously.
121 */
122 public VFilledGroup allFilledOrEmpty()
123 {
124 allFilledOrEmpty = true;
125 onlyOneEmpty = false;
126 onlyOneFilled = false;
127 oneOrMoreFilled = false;
128
129 return this;
130 }
131
132 public 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
144 private 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
158 private 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
179 private 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
200 private 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 }