View Javadoc

1   /**
2    * Copyright 2005-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.rice.krad.datadictionary.validation.result;
17  
18  import org.kuali.rice.krad.datadictionary.validation.AttributeValueReader;
19  import org.kuali.rice.krad.datadictionary.validation.ErrorLevel;
20  import org.kuali.rice.krad.datadictionary.validation.ValidationUtils;
21  
22  import java.util.Iterator;
23  import java.util.LinkedHashMap;
24  import java.util.Map;
25  
26  /**
27   * 
28   * @author Kuali Rice Team (rice.collab@kuali.org) 
29   */
30  public class DictionaryValidationResult implements Iterable<ConstraintValidationResult> {
31  	
32  	private Map<String, EntryValidationResult> entryValidationResultMap;
33  	private ErrorLevel errorLevel;
34  	
35  	private int numberOfErrors;
36  	private int numberOfWarnings;
37  	
38  	private Iterator<ConstraintValidationResult> iterator;
39  	
40  	public DictionaryValidationResult() {
41  		this.entryValidationResultMap = new LinkedHashMap<String, EntryValidationResult>();
42  		this.errorLevel = ErrorLevel.ERROR;
43  		this.numberOfErrors = 0;
44  		this.numberOfWarnings = 0;
45  	}
46  	
47  	public void addConstraintValidationResult(AttributeValueReader attributeValueReader, ConstraintValidationResult constraintValidationResult) {
48  		
49  		// Don't bother to store this if the error level of the constraint validation result is lower than the level this dictionary validation result is tracking
50  		if (constraintValidationResult.getStatus().getLevel() < errorLevel.getLevel())
51  			return;
52  		
53  		switch (constraintValidationResult.getStatus()) {
54  		case ERROR:
55  			numberOfErrors++;
56  			break;
57  		case WARN:
58  			numberOfWarnings++;
59  			break;
60  		default:
61  			// Do nothing
62  		}
63  		
64  		// Give the constraint a chance to override the entry and attribute name - important if the attribute name is not the same as the one in the attribute value reader!
65  		String entryName = constraintValidationResult.getEntryName();
66  		String attributeName = constraintValidationResult.getAttributeName();
67  		String attributePath = constraintValidationResult.getAttributePath();
68  		
69  		if (entryName == null){
70  			entryName = attributeValueReader.getEntryName();
71  		}
72  		
73  		if (attributeName == null){
74  			attributeName = attributeValueReader.getAttributeName();
75  		}
76  		
77  		if (attributePath == null){
78  		    attributePath = attributeValueReader.getPath();
79  		}
80  		
81  		constraintValidationResult.setEntryName(entryName);
82  		constraintValidationResult.setAttributeName(attributeName);
83  		constraintValidationResult.setAttributePath(attributePath);
84  		
85  		String entryKey = getEntryValdidationResultKey(entryName, attributePath);
86  		getEntryValidationResult(entryKey).getAttributeValidationResult(attributeName).addConstraintValidationResult(constraintValidationResult);
87  	}
88  	
89  	public ConstraintValidationResult addError(AttributeValueReader attributeValueReader, String constraintName, String errorKey, String... errorParameters) {
90  		ConstraintValidationResult constraintValidationResult = getConstraintValidationResult(attributeValueReader.getEntryName(), attributeValueReader.getAttributeName(), attributeValueReader.getPath(), constraintName);
91  		constraintValidationResult.setError(errorKey, errorParameters);
92  		numberOfErrors++;
93  		return constraintValidationResult;
94  	}
95  
96      public ConstraintValidationResult addError(String constraintLabelKey, AttributeValueReader attributeValueReader, String constraintName,  String errorKey, String... errorParameters) {
97          ConstraintValidationResult constraintValidationResult = getConstraintValidationResult(attributeValueReader.getEntryName(), attributeValueReader.getAttributeName(), attributeValueReader.getPath(), constraintName);
98          constraintValidationResult.setError(errorKey, errorParameters);
99          constraintValidationResult.setConstraintLabelKey(constraintLabelKey);
100         numberOfErrors++;
101         return constraintValidationResult;
102     }
103 	
104 	public ConstraintValidationResult addWarning(AttributeValueReader attributeValueReader, String constraintName, String errorKey, String... errorParameters) {
105 		if (errorLevel.getLevel() > ErrorLevel.WARN.getLevel())
106 			return new ConstraintValidationResult(constraintName, ErrorLevel.WARN);
107 		
108 		ConstraintValidationResult constraintValidationResult = getConstraintValidationResult(attributeValueReader.getEntryName(), attributeValueReader.getAttributeName(), attributeValueReader.getPath(), constraintName);
109 		constraintValidationResult.setWarning(errorKey, errorParameters);
110 		numberOfWarnings++;
111 		return constraintValidationResult;
112 	}
113 
114 	public ConstraintValidationResult addSuccess(AttributeValueReader attributeValueReader, String constraintName) {
115 		if (errorLevel.getLevel() > ErrorLevel.OK.getLevel())
116 			return new ConstraintValidationResult(constraintName, ErrorLevel.OK);
117 		
118 		return getConstraintValidationResult(attributeValueReader.getEntryName(), attributeValueReader.getAttributeName(), attributeValueReader.getPath(), constraintName);
119 	}
120 	
121 	public ConstraintValidationResult addSkipped(AttributeValueReader attributeValueReader, String constraintName) {
122 		if (errorLevel.getLevel() > ErrorLevel.OK.getLevel())
123 			return new ConstraintValidationResult(constraintName, ErrorLevel.INAPPLICABLE);
124 		
125 		ConstraintValidationResult constraintValidationResult = getConstraintValidationResult(attributeValueReader.getEntryName(), attributeValueReader.getAttributeName(), attributeValueReader.getPath(), constraintName);
126 		constraintValidationResult.setStatus(ErrorLevel.INAPPLICABLE);
127 		return constraintValidationResult;
128 	}
129 	
130 	public ConstraintValidationResult addNoConstraint(AttributeValueReader attributeValueReader, String constraintName) {
131 		if (errorLevel.getLevel() > ErrorLevel.OK.getLevel())
132 			return new ConstraintValidationResult(constraintName, ErrorLevel.NOCONSTRAINT);
133 		
134 		ConstraintValidationResult constraintValidationResult = getConstraintValidationResult(attributeValueReader.getEntryName(), attributeValueReader.getAttributeName(), attributeValueReader.getPath(), constraintName);
135 		constraintValidationResult.setStatus(ErrorLevel.NOCONSTRAINT);
136 		return constraintValidationResult;
137 	}
138 	
139 	public Iterator<ConstraintValidationResult> iterator() {
140 
141         iterator = new Iterator<ConstraintValidationResult>() {
142 
143             private Iterator<EntryValidationResult> entryIterator;
144             private Iterator<AttributeValidationResult> attributeIterator;
145             private Iterator<ConstraintValidationResult> constraintIterator;
146 
147             @Override
148             public boolean hasNext() {
149                 Iterator<ConstraintValidationResult> currentConstraintIterator = getCurrentConstraintIterator();
150                 return currentConstraintIterator != null && currentConstraintIterator.hasNext();
151             }
152 
153             @Override
154             public ConstraintValidationResult next() {
155                 Iterator<ConstraintValidationResult> currentConstraintIterator = getCurrentConstraintIterator();
156                 return currentConstraintIterator != null ? currentConstraintIterator.next() : null;
157             }
158 
159             @Override
160             public void remove() {
161                 throw new RuntimeException("Can't remove from this iterator!");
162             }
163 
164             private Iterator<ConstraintValidationResult> getCurrentConstraintIterator() {
165                 if (constraintIterator == null || constraintIterator.hasNext() == false) {
166                     Iterator<AttributeValidationResult> currentAttributeIterator = getCurrentAttributeIterator();
167                     if (currentAttributeIterator != null && currentAttributeIterator.hasNext()) {
168                         AttributeValidationResult currentAttributeValidationResult = currentAttributeIterator.next();
169                         constraintIterator = currentAttributeValidationResult.iterator();
170                     }
171                 }
172                 return constraintIterator;
173             }
174 
175             private Iterator<AttributeValidationResult> getCurrentAttributeIterator() {
176                 if (attributeIterator == null || attributeIterator.hasNext() == false) {
177                     Iterator<EntryValidationResult> currentEntryIterator = getCurrentEntryIterator();
178                     if (currentEntryIterator != null && currentEntryIterator.hasNext()) {
179                         EntryValidationResult currentEntryValidationResult = currentEntryIterator.next();
180                         attributeIterator = currentEntryValidationResult.iterator();
181                     }
182                 }
183                 return attributeIterator;
184             }
185 
186             private Iterator<EntryValidationResult> getCurrentEntryIterator() {
187                 if (entryIterator == null) // || entryIterator.hasNext() == false)
188                     entryIterator = entryValidationResultMap.values().iterator();
189                 return entryIterator;
190             }
191 
192         };
193 
194 		return iterator;
195 	}
196 	
197 	protected EntryValidationResult getEntryValidationResult(String entryName) {
198 		EntryValidationResult entryValidationResult = entryValidationResultMap.get(entryName);
199 		if (entryValidationResult == null) {
200 			entryValidationResult = new EntryValidationResult(entryName);
201 			entryValidationResultMap.put(entryName, entryValidationResult);
202 		}
203 		return entryValidationResult;
204 	}
205 	
206 	private ConstraintValidationResult getConstraintValidationResult(String entryName, String attributeName, String attributePath, String constraintName) {
207 	    String entryKey = getEntryValdidationResultKey(entryName, attributePath);
208 	    ConstraintValidationResult constraintValidationResult = getEntryValidationResult(entryKey).getAttributeValidationResult(attributeName).getConstraintValidationResult(constraintName);
209 		constraintValidationResult.setEntryName(entryName);
210 		constraintValidationResult.setAttributeName(attributeName);
211 		constraintValidationResult.setAttributePath(attributePath);
212 		return constraintValidationResult;
213 	}
214 		
215 	/**
216      * Returns the key to the EntryValidationResult entry in the EntryValidationResultMap.
217      * Most cases entry key will be the entryName, unless the attribute is part of a collection,
218      * in which case entry key will be suffixed with index of attribute's parent item.
219      * 
220      * @param entryName
221      * @param attributePath
222      * @return
223      */
224     private String getEntryValdidationResultKey(String entryName, String attributePath) {
225         if (attributePath.contains("[")){
226             return entryName + "[" + ValidationUtils.getLastPathIndex(attributePath) + "]";
227         } 
228         return entryName;
229     }
230 
231     /**
232 	 * @return the errorLevel
233 	 */
234 	public ErrorLevel getErrorLevel() {
235 		return this.errorLevel;
236 	}
237 
238 	/**
239 	 * @param errorLevel the errorLevel to set
240 	 */
241 	public void setErrorLevel(ErrorLevel errorLevel) {
242 		this.errorLevel = errorLevel;
243 	}
244 
245 	/**
246 	 * @return the numberOfErrors
247 	 */
248 	public int getNumberOfErrors() {
249 		return this.numberOfErrors;
250 	}
251 
252 	/**
253 	 * @return the numberOfWarnings
254 	 */
255 	public int getNumberOfWarnings() {
256 		return this.numberOfWarnings;
257 	}
258 	
259 }