Clover Coverage Report - Kuali Student 1.2-M6-SNAPSHOT (Aggregated)
Coverage timestamp: Mon Sep 12 2011 05:03:53 EDT
../../../../../../../img/srcFileCovDistChart3.png 41% of files have more coverage
344   730   190   11.86
202   553   0.55   29
29     6.55  
1    
 
  DataModelValidator       Line # 40 344 0% 190 416 27.7% 0.27652174
 
  (1)
 
1    /**
2    * Copyright 2010 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10    * software distributed under the License is distributed on an "AS IS"
11    * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12    * or implied. See the License for the specific language governing
13    * permissions and limitations under the License.
14    */
15   
16    package org.kuali.student.common.ui.client.validator;
17   
18    import com.google.gwt.i18n.client.DateTimeFormat;
19   
20    import org.kuali.student.common.assembly.data.ConstraintMetadata;
21    import org.kuali.student.common.assembly.data.Data;
22    import org.kuali.student.common.assembly.data.Metadata;
23    import org.kuali.student.common.assembly.data.QueryPath;
24    import org.kuali.student.common.assembly.data.Data.DataType;
25    import org.kuali.student.common.assembly.data.Data.StringKey;
26    import org.kuali.student.common.ui.client.application.Application;
27    import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
28    import org.kuali.student.common.ui.client.mvc.DataModel;
29    import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
30    import org.kuali.student.common.ui.client.util.UtilConstants;
31    import org.kuali.student.common.util.MessageUtils;
32    import org.kuali.student.common.validation.dto.ValidationResultInfo;
33    import org.kuali.student.common.validator.DateParser;
34   
35    import java.util.*;
36   
37    import static org.kuali.student.common.assembly.data.MetadataInterrogator.*;
38    import static org.kuali.student.common.ui.client.validator.ValidationMessageKeys.*;
39   
 
40    public class DataModelValidator {
41   
42    private static final String RUNTIME_DELETED_KEY = "_runtimeData/deleted";
43   
44    private DateParser dateParser = null;
45    private boolean validateNextState = false;
46   
47    /**
48    * @return the dateParser
49    */
 
50  0 toggle public DateParser getDateParser() {
51  0 return dateParser;
52    }
53   
54    /**
55    * @param dateParser the dateParser to set
56    */
 
57  0 toggle public void setDateParser(DateParser dateParser) {
58  0 this.dateParser = dateParser;
59    }
60   
61   
62    /**
63    * Use to validate the entire DataModel structure against constraints defined in the metadata.
64    *
65    * @param model
66    * @return
67    */
 
68  4 toggle public List<ValidationResultInfo> validate(final DataModel model) {
69  4 validateNextState = false;
70  4 List<ValidationResultInfo> results = new ArrayList<ValidationResultInfo>();
71  4 DataModelDefinition def = (DataModelDefinition) model.getDefinition();
72  4 doValidate(model, def.getMetadata(), new QueryPath(), results);
73  4 return results;
74    }
75   
76    /**
77    * Use to validate the entire DataModel structure against constraints defined in the metadata
78    * for the current state and the "next" state.
79    *
80    * @param model
81    * @return
82    */
 
83  0 toggle public List<ValidationResultInfo> validateNextState(final DataModel model) {
84  0 validateNextState = true;
85  0 List<ValidationResultInfo> results = new ArrayList<ValidationResultInfo>();
86  0 DataModelDefinition def = (DataModelDefinition) model.getDefinition();
87  0 doValidate(model, def.getMetadata(), new QueryPath(), results);
88   
89  0 return results;
90    }
91   
92    /**
93    * Use to validate the entire DataModel structure against constraints defined in the metadata
94    * for the given metadata
95    *
96    * @param metadata
97    * @param model
98    * @return
99    */
 
100  0 toggle public List<ValidationResultInfo> validateForMetadata(Metadata metadata, final DataModel model) {
101  0 validateNextState = true;
102  0 List<ValidationResultInfo> results = new ArrayList<ValidationResultInfo>();
103  0 doValidate(model, metadata, new QueryPath(), results);
104  0 return results;
105    }
106   
107    /**
108    * Use to validated a single field within the data model against constraints defined in the metadata
109    *
110    * @param fd
111    * @param model
112    * @return
113    */
 
114  0 toggle public List<ValidationResultInfo> validate(FieldDescriptor fd,
115    DataModel model) {
116  0 validateNextState = false;
117  0 List<ValidationResultInfo> results = new ArrayList<ValidationResultInfo>();
118  0 if (fd != null && fd.getMetadata() != null && fd.getFieldKey() != null) {
119  0 doValidate(model, fd.getMetadata(), QueryPath.parse(fd.getFieldKey()), results);
120    }
121   
122  0 return results;
123    }
124   
 
125  15 toggle private void doValidate(final DataModel model, final Metadata meta, final QueryPath path, List<ValidationResultInfo> results) {
126  15 switch (meta.getDataType()) {
127  5 case DATA:
128    // intentional fallthrough case
129  3 case LIST:
130  8 doValidateComplex(model, meta, path, results);
131  8 break;
132    }
133   
134  15 if (meta.getConstraints() != null) {
135  15 switch (meta.getDataType()) {
136   
137  0 case BOOLEAN:
138  0 doValidateBoolean(model, meta, path, results);
139  0 break;
140   
141  0 case DATE:
142    // intentional fallthrough case
143  0 case TRUNCATED_DATE:
144  0 doValidateDate(model, meta, path, results);
145  0 break;
146   
147  0 case DOUBLE:
148  0 doValidateDouble(model, meta, path, results);
149  0 break;
150   
151  0 case FLOAT:
152  0 doValidateFloat(model, meta, path, results);
153  0 break;
154   
155  0 case INTEGER:
156  0 doValidateInteger(model, meta, path, results);
157  0 break;
158   
159  0 case LONG:
160  0 doValidateLong(model, meta, path, results);
161  0 break;
162   
163  7 case STRING:
164  7 doValidateString(model, meta, path, results);
165  7 break;
166   
167  8 default:
168    // do nothing
169    }
170    }
171    }
172   
 
173  3 toggle private void addError(List<ValidationResultInfo> list, QueryPath element, ValidationMessageKeys msgKey, Map<String, Object> constraintInfo) {
174  3 ValidationResultInfo v = new ValidationResultInfo();
175  3 String rawMsg = getValidationMessage(msgKey.getKey());
176  3 v.setElement(element.toString());
177  3 v.setError(MessageUtils.interpolate(rawMsg, constraintInfo));
178  3 list.add(v);
179    }
180   
 
181  0 toggle private void addError(List<ValidationResultInfo> list, QueryPath element, ValidationMessageKeys msgKey, Object value) {
182  0 ValidationResultInfo v = new ValidationResultInfo();
183  0 String rawMsg = getValidationMessage(msgKey.getKey());
184  0 v.setElement(element.toString());
185  0 v.setError(MessageUtils.interpolate(rawMsg, msgKey.getProperty(), value));
186  0 list.add(v);
187    }
188   
 
189  0 toggle protected String getValidationMessage(String msgKey) {
190  0 return Application.getApplicationContext().getMessage(msgKey);
191    }
192   
 
193  0 toggle private void addError(List<ValidationResultInfo> list, QueryPath element, ValidationMessageKeys msgKey) {
194  0 addError(list, element, msgKey.getKey());
195    }
196   
 
197  0 toggle private void addError(List<ValidationResultInfo> list, QueryPath element, String msgKey) {
198  0 ValidationResultInfo v = new ValidationResultInfo();
199  0 v.setElement(element.toString());
200  0 v.setError(getValidationMessage(msgKey));
201  0 list.add(v);
202    }
203   
 
204  3 toggle private void addRangeError(List<ValidationResultInfo> list, QueryPath element, ValidationMessageKeys msgKey, Object minValue, Object maxValue) {
205  3 Map<String, Object> constraintInfo = new HashMap<String, Object>();
206   
207  3 put(constraintInfo, MIN_VALUE.getProperty(), minValue);
208  3 put(constraintInfo, MAX_VALUE.getProperty(), maxValue);
209   
210  3 addError(list, element, msgKey, constraintInfo);
211    }
212   
 
213  8 toggle private boolean isRequiredCheck(Metadata meta) {
214  8 if (validateNextState) {
215  0 return (isRequired(meta) || isRequiredForNextState(meta));
216    } else {
217  8 return isRequired(meta);
218    }
219    }
220   
 
221  7 toggle private void doValidateString(DataModel model, Metadata meta,
222    QueryPath path, List<ValidationResultInfo> results) {
223   
224  7 Map<QueryPath, Object> values = model.query(path);
225   
226  7 if (values.isEmpty() && isRequiredCheck(meta)) {
227  0 addError(results, path, REQUIRED);
228    } else {
229  7 Object[] keys = values.keySet().toArray();
230  14 for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
231  7 QueryPath element = (QueryPath) keys[keyIndex];
232   
233  7 String s = (values.get(element) == null) ? "" : values.get(element).toString();
234  7 doValidateString(s, element, meta, results);
235   
236    }
237    }
238    }
239   
240   
 
241  7 toggle public void doValidateString(String s, QueryPath element, Metadata meta,
242    List<ValidationResultInfo> results) {
243  7 if (s.isEmpty() && isRequiredCheck(meta)) {
244  0 addError(results, element, REQUIRED);
245  7 } else if (!s.isEmpty()) {
246  5 if (s.equals(UtilConstants.IMPOSSIBLE_CHARACTERS)) {
247  0 QueryPath path = new QueryPath();
248  0 path.add(new StringKey(element.get(0).toString()));
249  0 addError(results, path, INVALID_VALUE);
250    } else {
251  5 int len = s.length();
252  5 Integer minLength = getLargestMinLength(meta);
253  5 Integer maxLength = getSmallestMaxLength(meta);
254   
255  5 if (minLength != null && maxLength != null) {
256  5 if (len < minLength || len > maxLength) {
257  3 addRangeError(results, element, LENGTH_OUT_OF_RANGE, minLength, maxLength);
258    }
259  0 } else if (minLength != null && len < minLength) {
260  0 addError(results, element, MIN_LENGTH, minLength);
261  0 } else if (maxLength != null && len > maxLength) {
262  0 addError(results, element, MAX_LENGTH, maxLength);
263    }
264   
265    // process valid chars constraint
266  5 if (meta.getConstraints() != null) {
267  5 boolean failed = false;
268  5 List<ConstraintMetadata> constraints = meta.getConstraints();
269   
270  10 for (int consIdx = 0; consIdx < constraints.size(); consIdx++) {
271  5 ConstraintMetadata cons = constraints.get(consIdx);
272  5 if (failed) {
273  0 break;
274    }
275  5 String validChars = cons.getValidChars();
276  5 validChars = (validChars == null) ? "" : validChars.trim();
277  5 if (!validChars.isEmpty()) {
278  0 if (validChars.startsWith("regex:")) {
279  0 validChars = validChars.substring(6);
280  0 if (!s.matches(validChars)) {
281  0 if (cons.getValidCharsMessageId() != null) {
282  0 addError(results, element, cons.getValidCharsMessageId());
283    } else {
284  0 addError(results, element, VALID_CHARS);
285    }
286  0 failed = true;
287  0 break;
288    }
289    } else {
290  0 for (char c : s.toCharArray()) {
291  0 if (!validChars.contains(String.valueOf(c))) {
292  0 if (cons.getValidCharsMessageId() != null) {
293  0 addError(results, element, cons.getValidCharsMessageId());
294    } else {
295  0 addError(results, element, VALID_CHARS);
296    }
297  0 failed = true;
298  0 break;
299    }
300    }
301    }
302    }
303    }
304    }
305    }
306    }
307   
308    }
309   
 
310  0 toggle private void doValidateInteger(DataModel model, Metadata meta,
311    QueryPath path, List<ValidationResultInfo> results) {
312   
313  0 Map<QueryPath, Object> values = model.query(path);
314   
315  0 if (values.isEmpty() && isRequiredCheck(meta)) {
316  0 addError(results, path, REQUIRED);
317    } else {
318  0 Object[] keys = values.keySet().toArray();
319  0 for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
320  0 QueryPath element = (QueryPath) keys[keyIndex];
321   
322  0 Object o = values.get(element);
323   
324  0 if (o == null) {
325  0 if (isRequiredCheck(meta)) {
326  0 addError(results, element, REQUIRED);
327    }
328    } else {
329  0 Integer i = null;
330  0 try {
331  0 i = (o instanceof Integer) ? (Integer) o : Integer.valueOf(o.toString());
332    } catch (Exception ex) {
333  0 addError(results, element, INTEGER);
334    }
335   
336  0 if (i != null) {
337  0 Long min = getLargestMinValue(meta);
338  0 Long max = getSmallestMaxValue(meta);
339   
340  0 if (min != null && max != null) {
341  0 if (i < min || i > max) {
342  0 addRangeError(results, element, OUT_OF_RANGE, min, max);
343    }
344  0 } else if (min != null && i < min) {
345  0 addError(results, element, MIN_VALUE, min);
346  0 } else if (max != null && i > max) {
347  0 addError(results, element, MAX_VALUE, max);
348    }
349    }
350    }
351    }
352    }
353    }
354   
 
355  0 toggle private void doValidateLong(DataModel model, Metadata meta,
356    QueryPath path, List<ValidationResultInfo> results) {
357   
358  0 Map<QueryPath, Object> values = model.query(path);
359   
360  0 if (values.isEmpty() && isRequiredCheck(meta)) {
361  0 addError(results, path, REQUIRED);
362    } else {
363  0 Object[] keys = values.keySet().toArray();
364  0 for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
365  0 QueryPath element = (QueryPath) keys[keyIndex];
366   
367  0 Object o = values.get(element);
368   
369  0 if (o == null) {
370  0 if (isRequiredCheck(meta)) {
371  0 addError(results, element, REQUIRED);
372    }
373    } else {
374  0 Long i = null;
375  0 try {
376  0 i = (o instanceof Long) ? (Long) o : Long.valueOf(o.toString());
377    } catch (Exception ex) {
378  0 addError(results, element, LONG);
379    }
380   
381   
382  0 if (i != null) {
383  0 Long min = getLargestMinValue(meta);
384  0 Long max = getSmallestMaxValue(meta);
385   
386  0 if (min != null && max != null) {
387  0 if (i < min || i > max) {
388  0 addRangeError(results, element, OUT_OF_RANGE, min, max);
389    }
390  0 } else if (min != null && i < min) {
391  0 addError(results, element, MIN_VALUE, min);
392  0 } else if (max != null && i > max) {
393  0 addError(results, element, MAX_VALUE, max);
394    }
395    }
396    }
397    }
398    }
399    }
400   
 
401  0 toggle private void doValidateDouble(DataModel model, Metadata meta,
402    QueryPath path, List<ValidationResultInfo> results) {
403   
404  0 Map<QueryPath, Object> values = model.query(path);
405   
406  0 if (values.isEmpty() && isRequiredCheck(meta)) {
407  0 addError(results, path, REQUIRED);
408    } else {
409  0 Object[] keys = values.keySet().toArray();
410  0 for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
411  0 QueryPath element = (QueryPath) keys[keyIndex];
412   
413  0 Object o = values.get(element);
414   
415  0 if (o == null) {
416  0 if (isRequiredCheck(meta)) {
417  0 addError(results, element, REQUIRED);
418    }
419    } else {
420  0 Double d = null;
421  0 try {
422  0 d = (o instanceof Double) ? (Double) o : Double.valueOf(o.toString());
423    } catch (Exception ex) {
424  0 addError(results, element, DOUBLE);
425    }
426   
427   
428  0 if (d != null) {
429  0 Double min = getLargestMinValueDouble(meta);
430  0 Double max = getSmallestMaxValueDouble(meta);
431   
432  0 if (min != null && max != null) {
433  0 if (d < min || d > max) {
434  0 addRangeError(results, element, OUT_OF_RANGE, min, max);
435    }
436  0 } else if (min != null && d < min) {
437  0 addError(results, element, MIN_VALUE, min);
438  0 } else if (max != null && d > max) {
439  0 addError(results, element, MAX_VALUE, max);
440    }
441    }
442    }
443    }
444    }
445    }
446   
 
447  0 toggle private void doValidateFloat(DataModel model, Metadata meta,
448    QueryPath path, List<ValidationResultInfo> results) {
449   
450  0 Map<QueryPath, Object> values = model.query(path);
451   
452  0 if (values.isEmpty() && isRequiredCheck(meta)) {
453  0 addError(results, path, REQUIRED);
454    } else {
455  0 Object[] keys = values.keySet().toArray();
456  0 for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
457  0 QueryPath element = (QueryPath) keys[keyIndex];
458   
459  0 Object o = values.get(element);
460   
461  0 if (o == null) {
462  0 if (isRequiredCheck(meta)) {
463  0 addError(results, element, REQUIRED);
464    }
465    } else {
466  0 Float d = null;
467  0 try {
468  0 d = (o instanceof Float) ? (Float) o : Float.valueOf(o.toString());
469    } catch (Exception ex) {
470  0 addError(results, element, FLOAT);
471    }
472   
473   
474  0 if (d != null) {
475  0 Double min = getLargestMinValueDouble(meta);
476  0 Double max = getSmallestMaxValueDouble(meta);
477   
478  0 if (min != null && max != null) {
479  0 if (d < min || d > max) {
480  0 addRangeError(results, element, OUT_OF_RANGE, min, max);
481    }
482  0 } else if (min != null && d < min) {
483  0 addError(results, element, MIN_VALUE, min);
484  0 } else if (max != null && d > max) {
485  0 addError(results, element, MAX_VALUE, max);
486    }
487    }
488    }
489    }
490    }
491    }
492   
 
493  0 toggle private void doValidateDate(DataModel model, Metadata meta,
494    QueryPath path, List<ValidationResultInfo> results) {
495   
496  0 Map<QueryPath, Object> values = model.query(path);
497   
498  0 if (values.isEmpty() && isRequiredCheck(meta)) {
499  0 addError(results, path, REQUIRED);
500    } else {
501  0 Object[] keys = values.keySet().toArray();
502  0 for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
503  0 QueryPath element = (QueryPath) keys[keyIndex];
504  0 Object o = values.get(element);
505   
506  0 if (o == null) {
507  0 if (isRequiredCheck(meta)) {
508  0 addError(results, element, REQUIRED);
509    }
510    } else {
511  0 Date d = null;
512  0 try {
513  0 d = (o instanceof Date) ? (Date) o : dateParser.parseDate(o.toString());
514    } catch (Exception ex) {
515  0 addError(results, element, DATE);
516    }
517   
518   
519  0 if (d != null) {
520    //Get defined min/max value constraint
521  0 Date min = getLargestMinValueDate(meta, dateParser, getCrossFieldMinValue(model, element, meta));
522  0 Date max = getSmallestMaxValueDate(meta, dateParser, getCrossFieldMaxValue(model, element, meta));
523   
524  0 if (min != null && max != null) {
525  0 if (d.getTime() < min.getTime() || d.getTime() > max.getTime()) {
526  0 addRangeError(results, element, OUT_OF_RANGE, asDateString(min), asDateString(max));
527    }
528  0 } else if (min != null && d.getTime() < min.getTime()) {
529  0 addError(results, element, MIN_VALUE, asDateString(min));
530  0 } else if (max != null && d.getTime() > max.getTime()) {
531  0 addError(results, element, MAX_VALUE, asDateString(max));
532    }
533    }
534    }
535    }
536    }
537    }
538   
539   
 
540  0 toggle private void doValidateBoolean(DataModel model, Metadata meta,
541    QueryPath path, List<ValidationResultInfo> results) {
542   
543  0 Map<QueryPath, Object> values = model.query(path);
544   
545  0 if (values.isEmpty() && isRequiredCheck(meta)) {
546  0 addError(results, path, REQUIRED);
547    } else {
548   
549  0 Object[] keys = values.keySet().toArray();
550  0 for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
551  0 QueryPath element = (QueryPath) keys[keyIndex];
552   
553  0 Object o = values.get(element);
554   
555  0 if (o == null) {
556  0 if (isRequiredCheck(meta)) {
557  0 addError(results, element, REQUIRED);
558    }
559    } else {
560  0 if (o instanceof Boolean == false) {
561  0 addError(results, element, BOOLEAN);
562    }
563    }
564    }
565    }
566    }
567   
 
568  8 toggle private void doValidateComplex(final DataModel model, final Metadata meta, final QueryPath path, List<ValidationResultInfo> results) {
569  8 Map<QueryPath, Object> values = model.query(path);
570  8 boolean hasChildElements = true;
571   
572    //Check if complex object is required and/or meets min/max occurs requirements
573  8 if (values.isEmpty() && isRequiredCheck(meta)) {
574  0 addError(results, path, REQUIRED);
575  0 hasChildElements = false;
576  8 } else if (meta.getDataType().equals(DataType.LIST)) {
577  3 hasChildElements = false;
578  3 for (Map.Entry<QueryPath, Object> e : values.entrySet()) {
579  3 QueryPath listPath = QueryPath.parse(e.getKey().toString());
580  3 listPath.add(Data.WILDCARD_KEY);
581  3 values = model.query(listPath);
582   
583  3 if (!values.isEmpty()) {
584  1 hasChildElements = true;
585    }
586   
587  3 if (values.isEmpty() && isRequiredCheck(meta)) {
588  0 addError(results, e.getKey(), REQUIRED);
589    } else {
590    // do min/max occurs checks
591  3 validateOccurs(e.getKey(), values, meta, results);
592    }
593    }
594    }
595   
596    // Validate child elements when child elements exist in data or when validating root path
597  8 if (hasChildElements || path.toString().isEmpty()) {
598  6 String basePath = path.toString();
599  6 if (meta.getProperties() != null) {
600  6 Object[] keys = meta.getProperties().keySet().toArray();
601  6 parentElementLoop:
602  17 for (int keyIndex = 0; keyIndex < keys.length; keyIndex++) {
603  11 String element = (String) keys[keyIndex];
604  11 if (!element.contains("runtimeData")) {
605  11 QueryPath childPath = QueryPath.concat(basePath, element);
606  11 Map<QueryPath, Object> childValues = model.query(childPath);
607  11 if (!childValues.isEmpty()) {
608  11 Object[] childKeys = childValues.keySet().toArray();
609  22 for (int childKeyIndex = 0; childKeyIndex < childKeys.length; childKeyIndex++) {
610  11 QueryPath childElement = (QueryPath) childKeys[childKeyIndex];
611  11 QueryPath childElementDeletePath = QueryPath.parse(childElement.toString() + QueryPath.getPathSeparator() + RUNTIME_DELETED_KEY);
612  11 try {
613  11 Boolean childDeletedObject = model.get(childElementDeletePath);
614  6 if (childDeletedObject != null && childDeletedObject) {
615  0 continue parentElementLoop;
616    }
617    } catch (Exception e) {
618    //ignore exception
619    }
620    }
621    }
622  11 doValidate(model, meta.getProperties().get(element), childPath, results);
623    }
624    }
625    }
626    }
627    }
628   
 
629  3 toggle private boolean validateOccurs(QueryPath path, Map<QueryPath, Object> values, Metadata meta, List<ValidationResultInfo> results) {
630   
631  3 int size = getListSize(values, meta);
632   
633  3 Integer min = getLargestMinOccurs(meta);
634  3 boolean minValid = min == null || min <= size;
635   
636  3 Integer max = getSmallestMaxOccurs(meta);
637  3 boolean maxValid = (max == null || max == -1 || max >= size);
638   
639   
640  3 if (!minValid || !maxValid) {
641  0 if (!minValid && !maxValid) {
642  0 addRangeError(results, path, OCCURS, min, max);
643  0 } else if (!minValid) {
644  0 addError(results, path, MIN_OCCURS, min);
645    } else {
646  0 addError(results, path, MAX_OCCURS, max);
647    }
648    }
649   
650  3 return minValid && maxValid;
651    }
652   
 
653  3 toggle private int getListSize(Map<QueryPath, Object> values, Metadata meta) {
654  3 int size = 0;
655   
656    //Check to see if a complex data element in list has been deleted
657  3 Map<String, Metadata> properties = meta.getProperties();
658  3 if (properties.containsKey(Data.WILDCARD_KEY.toString())) {
659  3 Metadata listMeta = properties.get(Data.WILDCARD_KEY.toString());
660  3 if (listMeta != null && listMeta.getDataType().equals(DataType.DATA)) {
661  3 Object[] valueList = values.values().toArray();
662  4 for (int i = 0; i < valueList.length; i++) {
663  1 Object value = valueList[i];
664  1 Data d = (Data) value;
665  1 Boolean deleted = d.query(RUNTIME_DELETED_KEY);
666  1 if (deleted == null || !deleted) {
667  1 size++;
668    }
669    }
670    } else {
671  0 size = values.size();
672    }
673    } else {
674  0 size = values.size();
675    }
676   
677  3 return size;
678    }
679   
680    //FIXME: This is a temp solution for getting cross field min value
681   
 
682  0 toggle private Object getCrossFieldMinValue(DataModel model, QueryPath path, Metadata meta) {
683  0 Object v = null;
684  0 List<ConstraintMetadata> constraints = meta.getConstraints();
685  0 for (int i = 0; i < constraints.size(); i++) {
686  0 ConstraintMetadata cons = constraints.get(i);
687  0 if (cons.getMinValue() != null && cons.getMinValue().contains("../")) {
688  0 QueryPath crossFieldPath = QueryPath.parse(path.toString());
689  0 String crossFieldKey = cons.getMinValue().substring(3);
690  0 crossFieldPath.remove(crossFieldPath.size() - 1);
691  0 crossFieldPath.add(new StringKey(crossFieldKey));
692  0 v = model.get(crossFieldPath);
693    }
694    }
695   
696  0 return v;
697    }
698   
699    //FIXME: This is a temp solution for getting cross field max value
700   
 
701  0 toggle private Object getCrossFieldMaxValue(DataModel model, QueryPath path, Metadata meta) {
702  0 Object v = null;
703  0 List<ConstraintMetadata> constraints = meta.getConstraints();
704  0 for (int i = 0; i < constraints.size(); i++) {
705  0 ConstraintMetadata cons = constraints.get(i);
706  0 if (cons.getMaxValue() != null && cons.getMaxValue().contains("../")) {
707  0 QueryPath crossFieldPath = QueryPath.parse(path.toString());
708  0 String crossFieldKey = cons.getMinValue().substring(3);
709  0 crossFieldPath.remove(crossFieldPath.size() - 1);
710  0 crossFieldPath.add(new StringKey(crossFieldKey));
711  0 v = model.get(crossFieldPath);
712    }
713    }
714   
715  0 return v;
716    }
717   
 
718  6 toggle private void put(Map<String, Object> m, String key, Object value) {
719  6 if (value != null) {
720  6 m.put(key, value);
721    }
722    }
723   
 
724  0 toggle private String asDateString(Date date) {
725  0 DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("MM/dd/yyyy");
726  0 return dateTimeFormat.format(date);
727    }
728   
729   
730    }