1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.contract.model.validation;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Set;
23
24 import org.kuali.student.contract.model.SearchCriteria;
25 import org.kuali.student.contract.model.SearchCriteriaParameter;
26 import org.kuali.student.contract.model.SearchModel;
27 import org.kuali.student.contract.model.SearchResult;
28 import org.kuali.student.contract.model.SearchResultColumn;
29 import org.kuali.student.contract.model.SearchType;
30 import org.kuali.student.contract.model.util.ModelFinder;
31
32
33
34
35
36 public class SearchModelValidator implements ModelValidator {
37
38 private SearchModel model;
39
40 public SearchModelValidator(SearchModel model) {
41 this.model = model;
42 }
43 List<String> errors = new ArrayList();
44
45 @Override
46 public Collection<String> validate() {
47 errors = new ArrayList();
48 validateSearchTypes();
49 return errors;
50 }
51
52 private void validateSearchTypes() {
53 if (model.getSearchTypes().size() == 0) {
54 addError("No search types found");
55 }
56 validateForDuplicates();
57 for (SearchType st : model.getSearchTypes()) {
58 SearchTypeValidator stv = new SearchTypeValidator(st, model);
59 errors.addAll(stv.validate());
60 }
61 getValidateSearchCriteria(true);
62 getValidateSearchCriteriaParameters(true);
63 getValidateSearchResults(true);
64 getValidateSearchResultColumns(true);
65 }
66
67 private void validateForDuplicates() {
68 Set<String> keys = new HashSet();
69 for (SearchType st : model.getSearchTypes()) {
70 if (!keys.add(st.getKey())) {
71 SearchType st2 = new ModelFinder(model).findSearchType(st.getKey());
72 List<String> differences = findDifferences(st, st2);
73 if (differences.size() > 0) {
74 StringBuffer buf = new StringBuffer();
75 String comma = "";
76 for (String val : differences) {
77 buf.append(comma);
78 buf.append(val);
79 comma = ", ";
80 }
81 addError("Search type [" + st.getKey()
82 + "] is duplicated but differences were found: " + buf);
83 }
84 }
85 }
86 }
87
88 private List<String> findDifferences(SearchType st1, SearchType st2) {
89 List<String> differences = new ArrayList();
90 addIfDifferent(differences, st1.getKey(), st2.getKey(), "key");
91 addIfDifferent(differences, st1.getName(), st2.getName(), "name");
92 addIfDifferent(differences, st1.getDescription(), st2.getDescription(), "Description");
93 addIfDifferent(differences, st1.getService(), st2.getService(), "Service");
94
95 SearchCriteria sc1 = st1.getSearchCriteria();
96 SearchCriteria sc2 = st2.getSearchCriteria();
97 addIfDifferent(differences, sc1.getKey(), sc2.getKey(), "key");
98 addIfDifferent(differences, sc1.getName(), sc2.getName(), "name");
99 addIfDifferent(differences, sc1.getDescription(), sc2.getDescription(), "Description");
100
101 List<SearchCriteriaParameter> scp1s = sc1.getParameters();
102 List<SearchCriteriaParameter> scp2s = sc2.getParameters();
103 addIfDifferent(differences, scp1s.size(), scp2s.size(), "# of parameters");
104
105 if (scp1s.size() == scp2s.size()) {
106 for (int i = 0; i < scp1s.size(); i++) {
107 SearchCriteriaParameter scp1 = scp1s.get(i);
108 SearchCriteriaParameter scp2 = scp2s.get(i);
109 addIfDifferent(differences, scp1.getKey(), scp2.getKey(), "key");
110 addIfDifferent(differences, scp1.getName(), scp2.getName(), "name");
111 addIfDifferent(differences, scp1.getDescription(), scp2.getDescription(), "Description");
112 addIfDifferent(differences, scp1.getDataType(), scp2.getDataType(), "Datatype");
113 addIfDifferent(differences, scp1.getOptional(), scp2.getOptional(), "Optional");
114 addIfDifferent(differences, scp1.getCaseSensitive(), scp2.getCaseSensitive(), "case");
115 }
116 }
117
118
119 SearchResult sr1 = st1.getSearchResult();
120 SearchResult sr2 = st2.getSearchResult();
121 addIfDifferent(differences, sr1.getKey(), sr2.getKey(), "key");
122 addIfDifferent(differences, sr1.getName(), sr2.getName(), "name");
123 addIfDifferent(differences, sr1.getDescription(), sr2.getDescription(), "Description");
124 List<SearchResultColumn> src1s = sr1.getResultColumns();
125 List<SearchResultColumn> src2s = sr2.getResultColumns();
126 addIfDifferent(differences, src1s.size(), src2s.size(), "# of result columns");
127 if (src1s.size() == src2s.size()) {
128 for (int i = 0; i < src1s.size(); i++) {
129 SearchResultColumn src1 = src1s.get(i);
130 SearchResultColumn src2 = src2s.get(i);
131 addIfDifferent(differences, src1.getKey(), src2.getKey(), "key");
132 addIfDifferent(differences, src1.getName(), src2.getName(), "name");
133 addIfDifferent(differences, src1.getDescription(), src2.getDescription(), "Description");
134 addIfDifferent(differences, src1.getDataType(), src2.getDataType(), "Datatype");
135 addIfDifferent(differences, src1.getOptional(), src2.getOptional(), "Optional");
136 addIfDifferent(differences, src1.getCaseSensitive(), src2.getCaseSensitive(), "case");
137 }
138 }
139 return differences;
140 }
141
142 private void addIfDifferent(List<String> differences, Object val1, Object val2,
143 String difference) {
144 if (val1 == null && val2 == null) {
145 return;
146 }
147 if (val1 == null) {
148 differences.add(difference);
149 return;
150 }
151 if (!val1.equals(val2)) {
152 differences.add(difference);
153 }
154 }
155
156 private List<SearchResult> getValidateSearchResults(boolean validate) {
157 List<SearchResult> list = new ArrayList();
158 Set<String> keys = new HashSet();
159 for (SearchType st : model.getSearchTypes()) {
160 if (keys.add(st.getSearchResult().getKey())) {
161 list.add(st.getSearchResult());
162 } else {
163 if (validate) {
164 for (SearchResult result : list) {
165 if (result.getKey().equals(st.getSearchResult().getKey())) {
166 compareSearchResults(result, st.getSearchResult());
167 }
168 }
169 }
170 }
171 }
172 return list;
173 }
174
175 private void compareSearchResults(SearchResult result1, SearchResult result2) {
176 assert result1.getKey().equals(result2.getKey());
177 if (!result1.getName().equals(result2.getName())) {
178 addError("two results with the same key have different names, one is on row "
179 + result1.getRowNumber() + " the other is on row " + result2.getRowNumber());
180 }
181 if (!result1.getDescription().equals(result2.getDescription())) {
182 addError("Two results with the same key have different descriptions, one is on row "
183 + result1.getRowNumber() + " the other is on row " + result2.getRowNumber());
184 }
185 if (result1.getResultColumns().size() != result2.getResultColumns().size()) {
186 addError("two results with the same key have different number of result columns, one is on row "
187 + result1.getRowNumber() + " the other is on row " + result2.getRowNumber());
188 }
189 int i = 0;
190 for (SearchResultColumn col : result1.getResultColumns()) {
191 if (!col.getKey().equals(result2.getResultColumns().get(i).getKey())) {
192 addError("two results with the same key have different result columns, one is on row "
193 + result1.getRowNumber() + " the other is on row " + result2.getRowNumber()
194 + " the result columns that are different are on row " + col.getRowNumber());
195 }
196 i++;
197 }
198 }
199
200 private List<SearchResultColumn> getValidateSearchResultColumns(
201 boolean validate) {
202 List<SearchResultColumn> list = new ArrayList();
203 Set<String> keys = new HashSet();
204 for (SearchResult searchResult : getValidateSearchResults(false)) {
205 for (SearchResultColumn col : searchResult.getResultColumns()) {
206 if (keys.add(col.getKey())) {
207 list.add(col);
208 } else {
209 if (validate) {
210 for (SearchResultColumn resultCol : list) {
211 if (resultCol.getKey().equals(col.getKey())) {
212 compareSearchResultColumns(resultCol, col);
213 }
214 }
215 }
216 }
217 }
218 }
219 return list;
220 }
221
222 private void compareSearchResultColumns(SearchResultColumn col1,
223 SearchResultColumn col2) {
224 assert col1.getKey().equals(col2.getKey());
225 if (!col1.getName().equals(col2.getName())) {
226 addError("two result columns with the same key have different names, one is on row "
227 + col1.getRowNumber() + " the other is on row "
228 + col2.getRowNumber());
229 }
230 if (!col1.getDescription().equals(col2.getDescription())) {
231 addError("Two result columns with the same key have different descriptions, one is on row "
232 + col1.getRowNumber() + " the other is on row "
233 + col2.getRowNumber());
234 }
235 if (!col1.getDataType().equals(col2.getDataType())) {
236 addError("Two result columns with the same key have different data type, one is on row "
237 + col1.getRowNumber() + " the other is on row "
238 + col2.getRowNumber());
239 }
240 }
241
242 private List<SearchCriteria> getValidateSearchCriteria(boolean validate) {
243 List<SearchCriteria> list = new ArrayList();
244 Set<String> keys = new HashSet();
245 for (SearchType st : model.getSearchTypes()) {
246 if (keys.add(st.getSearchCriteria().getKey())) {
247 list.add(st.getSearchCriteria());
248 } else {
249 if (validate) {
250 for (SearchCriteria criteria : list) {
251 if (criteria.getKey().equals(st.getSearchCriteria().getKey())) {
252 compareSearchCriteria(criteria, st.getSearchCriteria());
253 }
254 }
255 }
256 }
257 }
258 return list;
259 }
260
261 private void compareSearchCriteria(SearchCriteria criteria1,
262 SearchCriteria criteria2) {
263 assert criteria1.getKey().equals(criteria2.getKey());
264 if (!criteria1.getName().equals(criteria2.getName())) {
265 addError("two criteria with the same key have different names, one is on row "
266 + criteria1.getRowNumber() + " the other is on row "
267 + criteria2.getRowNumber());
268 }
269 if (!criteria1.getDescription().equals(criteria2.getDescription())) {
270 addError("Two criteria with the same key have different descriptions, one is on row "
271 + criteria1.getRowNumber() + " the other is on row "
272 + criteria2.getRowNumber());
273 }
274 if (criteria1.getParameters().size() != criteria2.getParameters().size()) {
275 addError("two results with the same key have different number of result columns, one is on row "
276 + criteria1.getRowNumber() + " the other is on row "
277 + criteria2.getRowNumber());
278 }
279 int i = 0;
280 for (SearchCriteriaParameter param : criteria1.getParameters()) {
281 if (!param.getKey().equals(criteria2.getParameters().get(i).getKey())) {
282 addError("two criteria with the same key have different parameters, one is on row "
283 + criteria1.getRowNumber() + " the other is on row " + criteria2.getRowNumber()
284 + " the parameters that are different are on row " + param.getRowNumber());
285 }
286 i++;
287 }
288 }
289
290 private List<SearchCriteriaParameter> getValidateSearchCriteriaParameters(
291 boolean validate) {
292 List<SearchCriteriaParameter> list = new ArrayList();
293 Set<String> keys = new HashSet();
294 for (SearchCriteria criteria : getValidateSearchCriteria(false)) {
295 for (SearchCriteriaParameter parm : criteria.getParameters()) {
296 if (keys.add(parm.getKey())) {
297 list.add(parm);
298 } else {
299 if (validate) {
300 for (SearchCriteriaParameter param : list) {
301 if (param.getKey().equals(parm.getKey())) {
302 compareSearchCriteriaParameter(param, parm);
303 }
304 }
305 }
306 }
307 }
308 }
309 return list;
310 }
311
312 private void compareSearchCriteriaParameter(SearchCriteriaParameter param1,
313 SearchCriteriaParameter param2) {
314 assert param1.getKey().equals(param2.getKey());
315 if (!param1.getName().equals(param2.getName())) {
316 addError("two criteria parameters with the same key have different names, one is on row "
317 + param1.getRowNumber() + " the other is on row "
318 + param2.getRowNumber());
319 }
320 if (!param1.getDescription().equals(param2.getDescription())) {
321 addError("Two criteria parameters with the same key have different descriptions, one is on row "
322 + param1.getRowNumber() + " the other is on row "
323 + param2.getRowNumber());
324 }
325 if (!param1.getDataType().equals(param2.getDataType())) {
326 addError("Two criteria parameters with the same key have different data type, one is on row "
327 + param1.getRowNumber() + " the other is on row "
328 + param2.getRowNumber());
329 }
330 }
331
332 private void addError(String msg) {
333 String error = "Error in overall spreadsheet: " + msg;
334 if (!errors.contains(error)) {
335 errors.add(error);
336 }
337 }
338 }