1 16 17 package org.springframework.validation; 18 19 import java.io.Serializable ; 20 import java.util.Collections ; 21 import java.util.EmptyStackException ; 22 import java.util.HashMap ; 23 import java.util.HashSet ; 24 import java.util.Iterator ; 25 import java.util.LinkedList ; 26 import java.util.List ; 27 import java.util.Map ; 28 import java.util.Set ; 29 import java.util.Stack ; 30 31 import org.springframework.beans.PropertyEditorRegistry; 32 import org.springframework.util.StringUtils; 33 34 44 public abstract class AbstractBindingResult implements BindingResult, Serializable { 45 46 private final List errors = new LinkedList (); 47 48 private final String objectName; 49 50 private MessageCodesResolver messageCodesResolver = new DefaultMessageCodesResolver(); 51 52 private String nestedPath = ""; 53 54 private final Stack nestedPathStack = new Stack (); 55 56 private Set suppressedFields = new HashSet (); 57 58 59 64 protected AbstractBindingResult(String objectName) { 65 this.objectName = objectName; 66 } 67 68 73 public void setMessageCodesResolver(MessageCodesResolver messageCodesResolver) { 74 this.messageCodesResolver = messageCodesResolver; 75 } 76 77 80 public MessageCodesResolver getMessageCodesResolver() { 81 return this.messageCodesResolver; 82 } 83 84 85 89 public String getObjectName() { 90 return this.objectName; 91 } 92 93 public void setNestedPath(String nestedPath) { 94 doSetNestedPath(nestedPath); 95 this.nestedPathStack.clear(); 96 } 97 98 public String getNestedPath() { 99 return this.nestedPath; 100 } 101 102 public void pushNestedPath(String subPath) { 103 this.nestedPathStack.push(getNestedPath()); 104 doSetNestedPath(getNestedPath() + subPath); 105 } 106 107 public void popNestedPath() throws IllegalArgumentException { 108 try { 109 String formerNestedPath = (String ) this.nestedPathStack.pop(); 110 doSetNestedPath(formerNestedPath); 111 } 112 catch (EmptyStackException ex) { 113 throw new IllegalStateException ("Cannot pop nested path: no nested path on stack"); 114 } 115 } 116 117 121 protected void doSetNestedPath(String nestedPath) { 122 if (nestedPath == null) { 123 nestedPath = ""; 124 } 125 nestedPath = canonicalFieldName(nestedPath); 126 if (nestedPath.length() > 0 && !nestedPath.endsWith(Errors.NESTED_PATH_SEPARATOR)) { 127 nestedPath += Errors.NESTED_PATH_SEPARATOR; 128 } 129 this.nestedPath = nestedPath; 130 } 131 132 136 protected String fixedField(String field) { 137 if (StringUtils.hasLength(field)) { 138 return getNestedPath() + canonicalFieldName(field); 139 } 140 else { 141 String path = getNestedPath(); 142 return (path.endsWith(Errors.NESTED_PATH_SEPARATOR) ? 143 path.substring(0, path.length() - NESTED_PATH_SEPARATOR.length()) : path); 144 } 145 } 146 147 148 public void reject(String errorCode) { 149 reject(errorCode, null, null); 150 } 151 152 public void reject(String errorCode, String defaultMessage) { 153 reject(errorCode, null, defaultMessage); 154 } 155 156 public void reject(String errorCode, Object [] errorArgs, String defaultMessage) { 157 addError(new ObjectError(getObjectName(), resolveMessageCodes(errorCode), errorArgs, defaultMessage)); 158 } 159 160 public void rejectValue(String field, String errorCode) { 161 rejectValue(field, errorCode, null, null); 162 } 163 164 public void rejectValue(String field, String errorCode, String defaultMessage) { 165 rejectValue(field, errorCode, null, defaultMessage); 166 } 167 168 public void rejectValue(String field, String errorCode, Object [] errorArgs, String defaultMessage) { 169 if ("".equals(getNestedPath()) && !StringUtils.hasLength(field)) { 170 reject(errorCode, errorArgs, defaultMessage); 174 return; 175 } 176 String fixedField = fixedField(field); 177 Object newVal = getActualFieldValue(fixedField); 178 FieldError fe = new FieldError( 179 getObjectName(), fixedField, newVal, false, 180 resolveMessageCodes(errorCode, field), errorArgs, defaultMessage); 181 addError(fe); 182 } 183 184 191 public String [] resolveMessageCodes(String errorCode) { 192 return getMessageCodesResolver().resolveMessageCodes(errorCode, getObjectName()); 193 } 194 195 public String [] resolveMessageCodes(String errorCode, String field) { 196 String fixedField = fixedField(field); 197 Class fieldType = getFieldType(fixedField); 198 return getMessageCodesResolver().resolveMessageCodes(errorCode, getObjectName(), fixedField, fieldType); 199 } 200 201 public void addError(ObjectError error) { 202 this.errors.add(error); 203 } 204 205 public void addAllErrors(Errors errors) { 206 if (!errors.getObjectName().equals(getObjectName())) { 207 throw new IllegalArgumentException ("Errors object needs to have same object name"); 208 } 209 this.errors.addAll(errors.getAllErrors()); 210 } 211 212 213 public boolean hasErrors() { 214 return !this.errors.isEmpty(); 215 } 216 217 public int getErrorCount() { 218 return this.errors.size(); 219 } 220 221 public List getAllErrors() { 222 return Collections.unmodifiableList(this.errors); 223 } 224 225 public boolean hasGlobalErrors() { 226 return (getGlobalErrorCount() > 0); 227 } 228 229 public int getGlobalErrorCount() { 230 return getGlobalErrors().size(); 231 } 232 233 public List getGlobalErrors() { 234 List result = new LinkedList (); 235 for (Iterator it = this.errors.iterator(); it.hasNext();) { 236 Object error = it.next(); 237 if (!(error instanceof FieldError)) { 238 result.add(error); 239 } 240 } 241 return Collections.unmodifiableList(result); 242 } 243 244 public ObjectError getGlobalError() { 245 for (Iterator it = this.errors.iterator(); it.hasNext();) { 246 ObjectError objectError = (ObjectError) it.next(); 247 if (!(objectError instanceof FieldError)) { 248 return objectError; 249 } 250 } 251 return null; 252 } 253 254 public boolean hasFieldErrors() { 255 return (getFieldErrorCount() > 0); 256 } 257 258 public int getFieldErrorCount() { 259 return getFieldErrors().size(); 260 } 261 262 public List getFieldErrors() { 263 List result = new LinkedList (); 264 for (Iterator it = this.errors.iterator(); it.hasNext();) { 265 Object error = it.next(); 266 if (error instanceof FieldError) { 267 result.add(error); 268 } 269 } 270 return Collections.unmodifiableList(result); 271 } 272 273 public FieldError getFieldError() { 274 for (Iterator it = this.errors.iterator(); it.hasNext();) { 275 Object error = it.next(); 276 if (error instanceof FieldError) { 277 return (FieldError) error; 278 } 279 } 280 return null; 281 } 282 283 public boolean hasFieldErrors(String field) { 284 return (getFieldErrorCount(field) > 0); 285 } 286 287 public int getFieldErrorCount(String field) { 288 return getFieldErrors(field).size(); 289 } 290 291 public List getFieldErrors(String field) { 292 List result = new LinkedList (); 293 String fixedField = fixedField(field); 294 for (Iterator it = this.errors.iterator(); it.hasNext();) { 295 Object error = it.next(); 296 if (error instanceof FieldError && isMatchingFieldError(fixedField, ((FieldError) error))) { 297 result.add(error); 298 } 299 } 300 return Collections.unmodifiableList(result); 301 } 302 303 public FieldError getFieldError(String field) { 304 String fixedField = fixedField(field); 305 for (Iterator it = this.errors.iterator(); it.hasNext();) { 306 Object error = it.next(); 307 if (error instanceof FieldError) { 308 FieldError fe = (FieldError) error; 309 if (isMatchingFieldError(fixedField, fe)) { 310 return fe; 311 } 312 } 313 } 314 return null; 315 } 316 317 323 protected boolean isMatchingFieldError(String field, FieldError fieldError) { 324 return (field.equals(fieldError.getField()) || 325 (field.endsWith("*") && fieldError.getField().startsWith(field.substring(0, field.length() - 1)))); 326 } 327 328 329 public Object getFieldValue(String field) { 330 FieldError fe = getFieldError(field); 331 Object value = null; 333 if (fe != null) { 334 value = fe.getRejectedValue(); 335 } 336 else { 337 value = getActualFieldValue(fixedField(field)); 338 } 339 if (fe == null || !fe.isBindingFailure()) { 341 value = formatFieldValue(field, value); 342 } 343 return value; 344 } 345 346 352 public Class getFieldType(String field) { 353 Object value = getActualFieldValue(field); 354 if (value != null) { 355 return value.getClass(); 356 } 357 return null; 358 } 359 360 361 365 383 public Map getModel() { 384 Map model = new HashMap (); 385 model.put(BindingResult.MODEL_KEY_PREFIX + getObjectName(), this); 387 model.put(getObjectName(), getTarget()); 389 return model; 390 } 391 392 395 public PropertyEditorRegistry getPropertyEditorRegistry() { 396 throw new UnsupportedOperationException ( 397 "[" + getClass().getName() + "] does not support a PropertyEditorRegistry"); 398 } 399 400 406 public void recordSuppressedField(String fieldName) { 407 this.suppressedFields.add(fieldName); 408 } 409 410 416 public String [] getSuppressedFields() { 417 return StringUtils.toStringArray(this.suppressedFields); 418 } 419 420 421 public String toString() { 422 StringBuffer sb = new StringBuffer (getClass().getName()); 423 sb.append(": ").append(getErrorCount()).append(" errors"); 424 Iterator it = getAllErrors().iterator(); 425 while (it.hasNext()) { 426 sb.append('\n').append(it.next()); 427 } 428 return sb.toString(); 429 } 430 431 public boolean equals(Object other) { 432 if (this == other) { 433 return true; 434 } 435 if (!(other instanceof BindingResult)) { 436 return false; 437 } 438 BindingResult otherResult = (BindingResult) other; 439 return (getObjectName().equals(otherResult.getObjectName()) && 440 getTarget().equals(otherResult.getTarget()) && 441 getAllErrors().equals(otherResult.getAllErrors())); 442 } 443 444 public int hashCode() { 445 return getObjectName().hashCode() * 29 + getTarget().hashCode(); 446 } 447 448 449 453 456 public abstract Object getTarget(); 457 458 464 protected String canonicalFieldName(String field) { 465 return field; 466 } 467 468 473 protected abstract Object getActualFieldValue(String field); 474 475 483 protected Object formatFieldValue(String field, Object value) { 484 return value; 485 } 486 487 } 488 | Popular Tags |