001 /** 002 * Copyright 2005-2012 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.krad.datadictionary.validation.result; 017 018 import org.kuali.rice.krad.datadictionary.validation.AttributeValueReader; 019 import org.kuali.rice.krad.datadictionary.validation.ErrorLevel; 020 import org.kuali.rice.krad.datadictionary.validation.ValidationUtils; 021 022 import java.util.Iterator; 023 import java.util.LinkedHashMap; 024 import java.util.Map; 025 026 /** 027 * 028 * @author Kuali Rice Team (rice.collab@kuali.org) 029 */ 030 public class DictionaryValidationResult implements Iterable<ConstraintValidationResult> { 031 032 private Map<String, EntryValidationResult> entryValidationResultMap; 033 private ErrorLevel errorLevel; 034 035 private int numberOfErrors; 036 private int numberOfWarnings; 037 038 private Iterator<ConstraintValidationResult> iterator; 039 040 public DictionaryValidationResult() { 041 this.entryValidationResultMap = new LinkedHashMap<String, EntryValidationResult>(); 042 this.errorLevel = ErrorLevel.ERROR; 043 this.numberOfErrors = 0; 044 this.numberOfWarnings = 0; 045 } 046 047 public void addConstraintValidationResult(AttributeValueReader attributeValueReader, ConstraintValidationResult constraintValidationResult) { 048 049 // 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 050 if (constraintValidationResult.getStatus().getLevel() < errorLevel.getLevel()) 051 return; 052 053 switch (constraintValidationResult.getStatus()) { 054 case ERROR: 055 numberOfErrors++; 056 break; 057 case WARN: 058 numberOfWarnings++; 059 break; 060 default: 061 // Do nothing 062 } 063 064 // 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! 065 String entryName = constraintValidationResult.getEntryName(); 066 String attributeName = constraintValidationResult.getAttributeName(); 067 String attributePath = constraintValidationResult.getAttributePath(); 068 069 if (entryName == null){ 070 entryName = attributeValueReader.getEntryName(); 071 } 072 073 if (attributeName == null){ 074 attributeName = attributeValueReader.getAttributeName(); 075 } 076 077 if (attributePath == null){ 078 attributePath = attributeValueReader.getPath(); 079 } 080 081 constraintValidationResult.setEntryName(entryName); 082 constraintValidationResult.setAttributeName(attributeName); 083 constraintValidationResult.setAttributePath(attributePath); 084 085 String entryKey = getEntryValdidationResultKey(entryName, attributePath); 086 getEntryValidationResult(entryKey).getAttributeValidationResult(attributeName).addConstraintValidationResult(constraintValidationResult); 087 } 088 089 public ConstraintValidationResult addError(AttributeValueReader attributeValueReader, String constraintName, String errorKey, String... errorParameters) { 090 ConstraintValidationResult constraintValidationResult = getConstraintValidationResult(attributeValueReader.getEntryName(), attributeValueReader.getAttributeName(), attributeValueReader.getPath(), constraintName); 091 constraintValidationResult.setError(errorKey, errorParameters); 092 numberOfErrors++; 093 return constraintValidationResult; 094 } 095 096 public ConstraintValidationResult addError(String constraintLabelKey, AttributeValueReader attributeValueReader, String constraintName, String errorKey, String... errorParameters) { 097 ConstraintValidationResult constraintValidationResult = getConstraintValidationResult(attributeValueReader.getEntryName(), attributeValueReader.getAttributeName(), attributeValueReader.getPath(), constraintName); 098 constraintValidationResult.setError(errorKey, errorParameters); 099 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 }