View Javadoc
1   /**
2    * Copyright 2004-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.student.contract.model.validation;
17  
18  import org.kuali.student.contract.model.Constraint;
19  import org.kuali.student.contract.model.Dictionary;
20  import org.kuali.student.contract.model.DictionaryModel;
21  import org.kuali.student.contract.model.Field;
22  import org.kuali.student.contract.model.XmlType;
23  import org.kuali.student.contract.model.impl.ServiceContractModelPescXsdLoader;
24  import org.kuali.student.contract.model.util.ModelFinder;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  
28  import java.util.ArrayList;
29  import java.util.Collection;
30  import java.util.HashSet;
31  import java.util.List;
32  import java.util.Set;
33  
34  /**
35   * This validates a single dictinoary entry
36   * @author nwright
37   */
38  public class DictionaryValidator implements ModelValidator {
39      
40      private static Logger log = LoggerFactory.getLogger(DictionaryValidator.class);
41  
42      private Dictionary dict;
43      private DictionaryModel model;
44      private ModelFinder finder;
45  
46      public DictionaryValidator(Dictionary dict, DictionaryModel model) {
47          this.dict = dict;
48          this.model = model;
49          this.finder = new ModelFinder(model);
50      }
51      private Collection errors;
52  
53      @Override
54      public Collection<String> validate() {
55          ConstraintValidator cv = new ConstraintValidator(dict.getInlineConstraint());
56          errors = cv.validate();
57          validateForDuplicates();
58          if (dict.getPrimitive().equalsIgnoreCase(XmlType.COMPLEX)) {
59              for (Constraint cons : getAllConstraints()) {
60                  validateComplexConstraint(cons);
61              }
62          }
63          return errors;
64      }
65  
66      private List<Constraint> getAllConstraints() {
67          List<Constraint> list = getFieldNamedConstraints();
68          Field field = findField();
69          if (field != null) {
70              list.add(field.getInlineConstraint());
71          }
72          list.addAll(getDictionaryAdditionalConstraints());
73          list.add(dict.getInlineConstraint());
74          return list;
75      }
76  
77      private List<Constraint> getAllNamedConstraints() {
78          List<Constraint> list = getFieldNamedConstraints();
79          list.addAll(getDictionaryAdditionalConstraints());
80          return list;
81      }
82  
83      private List<Constraint> getFieldNamedConstraints() {
84          List<Constraint> list = new ArrayList();
85          Field field = findField();
86          if (field != null) {
87              for (String id : field.getConstraintIds()) {
88                  Constraint cons = findConstraint(id);
89                  if (cons != null) {
90                      list.add(cons);
91                  }
92              }
93          }
94          return list;
95      }
96  
97      private List<Constraint> getDictionaryAdditionalConstraints() {
98          List<Constraint> list = new ArrayList();
99          for (String id : dict.getAdditionalConstraintIds()) {
100             Constraint cons = findConstraint(id);
101             if (cons != null) {
102                 list.add(cons);
103             }
104         }
105         list.add(dict.getInlineConstraint());
106         return list;
107     }
108 
109     private Constraint findConstraint(String id) {
110         Constraint cons = new ModelFinder(this.model).findConstraint(id);
111         if (cons != null) {
112             return cons;
113         }
114         log.info("id=[" + id + "]");
115         if (id == null) {
116             log.info("id is null");
117         } else if (id.equals("")) {
118             log.info("id is empty string");
119         } else {
120             int i = 0;
121             for (byte b : id.getBytes()) {
122                 i++;
123                 log.info(i + ":" + b);
124             }
125         }
126         addError("Dictionary constraint id, " + id
127                 + " is not defined in the bank of constraints");
128         return null;
129     }
130 
131     private Field findField() {
132         Field field = finder.findField(dict);
133         if (field != null) {
134             return field;
135         }
136         addError("Dictionary with id , " + dict.getId()
137                 + " does not have a corresponding field defined in the message structure.");
138         return null;
139     }
140 
141     private String getConstraintId(Constraint cons) {
142         if (cons.getId().equals("")) {
143             return cons.getKey();
144         }
145         return cons.getId();
146     }
147 
148     private void validateComplexConstraint(Constraint cons) {
149         if (!cons.getMinLength().equals("")) {
150             addError(getConstraintId(cons)
151                     + " has a minLength which does not make sense on a complex field");
152         }
153         if (!cons.getMaxLength().equals("")) {
154             addError(getConstraintId(cons)
155                     + " has a maxLength which does not make sense on a complex field");
156         }
157         if (!cons.getMinValue().equals("")) {
158             addError(getConstraintId(cons)
159                     + " has a minValue which does not make sense on a complex field");
160         }
161         if (!cons.getMaxValue().equals("")) {
162             addError(getConstraintId(cons)
163                     + " has a maxValue which does not make sense on a complex field");
164         }
165         if (!cons.getValidChars().equals("")) {
166             addError(getConstraintId(cons)
167                     + " has validChars which does not make sense on a complex field");
168         }
169         if (!cons.getLookup().equals("")) {
170             addError(getConstraintId(cons)
171                     + " has a lookup which does not make sense on a complex field");
172         }
173     }
174 
175     private void validateForDuplicates() {
176         Set<String> ids = new HashSet();
177         for (Constraint cons : getAllNamedConstraints()) {
178             if (!ids.add(cons.getId())) {
179                 // optional is OK to be duplicated because it is is used to override
180                 // the 'required' setting
181                 if (!cons.getId().equals("optional")) {
182                     addError("Constraint with id of [" + cons.getId() + "] is duplicated");
183                 }
184             }
185         }
186     }
187 
188     private void addError(String msg) {
189         String error = "Error in dictionary entry: " + dict.getId() + ": " + msg;
190         if (!errors.contains(error)) {
191             errors.add(error);
192         }
193     }
194 }