1 16 17 package org.springframework.validation; 18 19 import java.beans.PropertyEditorSupport ; 20 import java.io.ByteArrayInputStream ; 21 import java.io.ByteArrayOutputStream ; 22 import java.io.ObjectInputStream ; 23 import java.io.ObjectOutputStream ; 24 import java.util.Locale ; 25 import java.util.Map ; 26 import java.util.Set ; 27 import java.util.TreeSet ; 28 29 import junit.framework.TestCase; 30 31 import org.springframework.beans.BeanWithObjectProperty; 32 import org.springframework.beans.DerivedTestBean; 33 import org.springframework.beans.ITestBean; 34 import org.springframework.beans.IndexedTestBean; 35 import org.springframework.beans.MutablePropertyValues; 36 import org.springframework.beans.NotWritablePropertyException; 37 import org.springframework.beans.PropertyValue; 38 import org.springframework.beans.SerializablePerson; 39 import org.springframework.beans.TestBean; 40 import org.springframework.beans.propertyeditors.CustomCollectionEditor; 41 import org.springframework.beans.propertyeditors.CustomNumberEditor; 42 import org.springframework.context.support.ResourceBundleMessageSource; 43 import org.springframework.context.support.StaticMessageSource; 44 import org.springframework.util.StringUtils; 45 46 50 public class DataBinderTests extends TestCase { 51 52 public void testBindingNoErrors() throws Exception { 53 TestBean rod = new TestBean(); 54 DataBinder binder = new DataBinder(rod, "person"); 55 assertTrue(binder.isIgnoreUnknownFields()); 56 MutablePropertyValues pvs = new MutablePropertyValues(); 57 pvs.addPropertyValue(new PropertyValue("name", "Rod")); 58 pvs.addPropertyValue(new PropertyValue("age", new Integer (32))); 59 pvs.addPropertyValue(new PropertyValue("nonExisting", "someValue")); 60 61 binder.bind(pvs); 62 binder.close(); 63 64 assertTrue("changed name correctly", rod.getName().equals("Rod")); 65 assertTrue("changed age correctly", rod.getAge() == 32); 66 67 Map m = binder.getErrors().getModel(); 68 assertTrue("There is one element in map", m.size() == 2); 69 TestBean tb = (TestBean) m.get("person"); 70 assertTrue("Same object", tb.equals(rod)); 71 } 72 73 public void testBindingNoErrorsNotIgnoreUnknown() throws Exception { 74 TestBean rod = new TestBean(); 75 DataBinder binder = new DataBinder(rod, "person"); 76 binder.setIgnoreUnknownFields(false); 77 MutablePropertyValues pvs = new MutablePropertyValues(); 78 pvs.addPropertyValue(new PropertyValue("name", "Rod")); 79 pvs.addPropertyValue(new PropertyValue("age", new Integer (32))); 80 pvs.addPropertyValue(new PropertyValue("nonExisting", "someValue")); 81 82 try { 83 binder.bind(pvs); 84 fail("Should have thrown NotWritablePropertyException"); 85 } 86 catch (NotWritablePropertyException ex) { 87 } 89 } 90 91 public void testBindingWithErrors() throws Exception { 92 TestBean rod = new TestBean(); 93 DataBinder binder = new DataBinder(rod, "person"); 94 MutablePropertyValues pvs = new MutablePropertyValues(); 95 pvs.addPropertyValue(new PropertyValue("name", "Rod")); 96 pvs.addPropertyValue(new PropertyValue("age", "32x")); 97 pvs.addPropertyValue(new PropertyValue("touchy", "m.y")); 98 binder.bind(pvs); 99 100 try { 101 binder.close(); 102 fail("Should have thrown BindException"); 103 } 104 catch (BindException ex) { 105 assertTrue("changed name correctly", rod.getName().equals("Rod")); 106 108 Map m = binder.getErrors().getModel(); 109 TestBean tb = (TestBean) m.get("person"); 111 assertTrue("Same object", tb.equals(rod)); 112 113 BindException be = (BindException) m.get(BindException.ERROR_KEY_PREFIX + "person"); 114 assertTrue("Added itself to map", ex == be); 115 assertTrue(be.hasErrors()); 116 assertTrue("Correct number of errors", be.getErrorCount() == 2); 117 118 assertTrue("Has age errors", be.hasFieldErrors("age")); 119 assertTrue("Correct number of age errors", be.getFieldErrorCount("age") == 1); 120 assertEquals("32x", binder.getErrors().getFieldValue("age")); 121 assertEquals("32x", binder.getErrors().getFieldError("age").getRejectedValue()); 122 assertEquals(0, tb.getAge()); 123 124 assertTrue("Has touchy errors", be.hasFieldErrors("touchy")); 125 assertTrue("Correct number of touchy errors", be.getFieldErrorCount("touchy") == 1); 126 assertEquals("m.y", binder.getErrors().getFieldValue("touchy")); 127 assertEquals("m.y", binder.getErrors().getFieldError("touchy").getRejectedValue()); 128 assertNull(tb.getTouchy()); 129 } 130 } 131 132 public void testBindingWithErrorsAndCustomEditors() throws Exception { 133 TestBean rod = new TestBean(); 134 DataBinder binder = new DataBinder(rod, "person"); 135 binder.registerCustomEditor(String .class, "touchy", new PropertyEditorSupport () { 136 public void setAsText(String text) throws IllegalArgumentException { 137 setValue("prefix_" + text); 138 } 139 public String getAsText() { 140 return getValue().toString().substring(7); 141 } 142 }); 143 binder.registerCustomEditor(TestBean.class, "spouse", new PropertyEditorSupport () { 144 public void setAsText(String text) throws IllegalArgumentException { 145 setValue(new TestBean(text, 0)); 146 } 147 public String getAsText() { 148 return ((TestBean) getValue()).getName(); 149 } 150 }); 151 MutablePropertyValues pvs = new MutablePropertyValues(); 152 pvs.addPropertyValue(new PropertyValue("name", "Rod")); 153 pvs.addPropertyValue(new PropertyValue("age", "32x")); 154 pvs.addPropertyValue(new PropertyValue("touchy", "m.y")); 155 pvs.addPropertyValue(new PropertyValue("spouse", "Kerry")); 156 binder.bind(pvs); 157 158 try { 159 binder.close(); 160 fail("Should have thrown BindException"); 161 } 162 catch (BindException ex) { 163 assertTrue("changed name correctly", rod.getName().equals("Rod")); 164 166 Map m = binder.getErrors().getModel(); 167 TestBean tb = (TestBean) m.get("person"); 169 assertTrue("Same object", tb.equals(rod)); 170 171 BindException be = (BindException) m.get(BindException.ERROR_KEY_PREFIX + "person"); 172 assertTrue("Added itself to map", ex == be); 173 assertTrue(be.hasErrors()); 174 assertTrue("Correct number of errors", be.getErrorCount() == 2); 175 176 assertTrue("Has age errors", be.hasFieldErrors("age")); 177 assertTrue("Correct number of age errors", be.getFieldErrorCount("age") == 1); 178 assertEquals("32x", binder.getErrors().getFieldValue("age")); 179 assertEquals("32x", binder.getErrors().getFieldError("age").getRejectedValue()); 180 assertEquals(0, tb.getAge()); 181 182 assertTrue("Has touchy errors", be.hasFieldErrors("touchy")); 183 assertTrue("Correct number of touchy errors", be.getFieldErrorCount("touchy") == 1); 184 assertEquals("m.y", binder.getErrors().getFieldValue("touchy")); 185 assertEquals("m.y", binder.getErrors().getFieldError("touchy").getRejectedValue()); 186 assertNull(tb.getTouchy()); 187 188 assertTrue("Does not have spouse errors", !be.hasFieldErrors("spouse")); 189 assertEquals("Kerry", binder.getErrors().getFieldValue("spouse")); 190 assertNotNull(tb.getSpouse()); 191 } 192 } 193 194 public void testBindingWithCustomEditorOnObjectField() { 195 BeanWithObjectProperty tb = new BeanWithObjectProperty(); 196 DataBinder binder = new DataBinder(tb, "tb"); 197 binder.registerCustomEditor(Integer .class, "object", new CustomNumberEditor(Integer .class, true)); 198 MutablePropertyValues pvs = new MutablePropertyValues(); 199 pvs.addPropertyValue(new PropertyValue("object", "1")); 200 binder.bind(pvs); 201 assertEquals(new Integer (1), tb.getObject()); 202 } 203 204 public void testBindingWithAllowedFields() throws Exception { 205 TestBean rod = new TestBean(); 206 DataBinder binder = new DataBinder(rod, "person"); 207 binder.setAllowedFields(new String []{"name", "myparam"}); 208 MutablePropertyValues pvs = new MutablePropertyValues(); 209 pvs.addPropertyValue(new PropertyValue("name", "Rod")); 210 pvs.addPropertyValue(new PropertyValue("age", "32x")); 211 212 binder.bind(pvs); 213 binder.close(); 214 215 assertTrue("changed name correctly", rod.getName().equals("Rod")); 216 assertTrue("did not change age", rod.getAge() == 0); 217 218 Map m = binder.getErrors().getModel(); 219 assertTrue("There is one element in map", m.size() == 2); 220 TestBean tb = (TestBean) m.get("person"); 221 assertTrue("Same object", tb.equals(rod)); 222 } 223 224 public void testBindingWithAllowedFieldsUsingAsterisks() throws Exception { 225 TestBean rod = new TestBean(); 226 DataBinder binder = new DataBinder(rod, "person"); 227 binder.setAllowedFields(new String []{"nam*", "*ouchy"}); 228 MutablePropertyValues pvs = new MutablePropertyValues(); 229 pvs.addPropertyValue(new PropertyValue("name", "Rod")); 230 pvs.addPropertyValue(new PropertyValue("touchy", "Rod")); 231 pvs.addPropertyValue(new PropertyValue("age", "32x")); 232 233 binder.bind(pvs); 234 binder.close(); 235 236 assertTrue("changed name correctly", "Rod".equals(rod.getName())); 237 assertTrue("changed touchy correctly", "Rod".equals(rod.getTouchy())); 238 assertTrue("did not change age", rod.getAge() == 0); 239 240 Map m = binder.getErrors().getModel(); 241 assertTrue("There is one element in map", m.size() == 2); 242 TestBean tb = (TestBean) m.get("person"); 243 assertTrue("Same object", tb.equals(rod)); 244 } 245 246 249 public void testBindingWithRequiredFields() throws Exception { 250 TestBean tb = new TestBean(); 251 tb.setSpouse(new TestBean()); 252 253 DataBinder binder = new DataBinder(tb, "person"); 254 binder.setRequiredFields(new String []{"touchy", "name", "age", "date", "spouse.name"}); 255 256 MutablePropertyValues pvs = new MutablePropertyValues(); 257 pvs.addPropertyValue(new PropertyValue("touchy", "")); 258 pvs.addPropertyValue(new PropertyValue("name", null)); 259 pvs.addPropertyValue(new PropertyValue("age", null)); 260 pvs.addPropertyValue(new PropertyValue("spouse.name", " ")); 261 262 binder.bind(pvs); 263 264 BindException ex = binder.getErrors(); 265 assertEquals("Wrong number of errors", 5, ex.getErrorCount()); 266 267 assertEquals("required", ex.getFieldError("touchy").getCode()); 268 assertEquals("", ex.getFieldValue("touchy")); 269 assertEquals("required", ex.getFieldError("name").getCode()); 270 assertEquals("", ex.getFieldValue("name")); 271 assertEquals("required", ex.getFieldError("age").getCode()); 272 assertEquals("", ex.getFieldValue("age")); 273 assertEquals("required", ex.getFieldError("date").getCode()); 274 assertEquals("", ex.getFieldValue("date")); 275 assertEquals("required", ex.getFieldError("spouse.name").getCode()); 276 assertEquals("", ex.getFieldValue("spouse.name")); 277 } 278 279 public void testBindingWithNestedObjectCreation() throws Exception { 280 TestBean tb = new TestBean(); 281 282 DataBinder binder = new DataBinder(tb, "person"); 283 binder.registerCustomEditor(ITestBean.class, new PropertyEditorSupport () { 284 public void setAsText(String text) throws IllegalArgumentException { 285 setValue(new TestBean()); 286 } 287 }); 288 289 MutablePropertyValues pvs = new MutablePropertyValues(); 290 pvs.addPropertyValue(new PropertyValue("spouse", "someValue")); 291 pvs.addPropertyValue(new PropertyValue("spouse.name", "test")); 292 binder.bind(pvs); 293 294 assertNotNull(tb.getSpouse()); 295 assertEquals("test", tb.getSpouse().getName()); 296 } 297 298 public void testCustomEditorForSingleProperty() { 299 TestBean tb = new TestBean(); 300 tb.setSpouse(new TestBean()); 301 DataBinder binder = new DataBinder(tb, "tb"); 302 303 binder.registerCustomEditor(String .class, "name", new PropertyEditorSupport () { 304 public void setAsText(String text) throws IllegalArgumentException { 305 setValue("prefix" + text); 306 } 307 public String getAsText() { 308 return ((String ) getValue()).substring(6); 309 } 310 }); 311 312 MutablePropertyValues pvs = new MutablePropertyValues(); 313 pvs.addPropertyValue(new PropertyValue("name", "value")); 314 pvs.addPropertyValue(new PropertyValue("touchy", "value")); 315 pvs.addPropertyValue(new PropertyValue("spouse.name", "sue")); 316 binder.bind(pvs); 317 318 binder.getErrors().rejectValue("name", "someCode", "someMessage"); 319 binder.getErrors().rejectValue("touchy", "someCode", "someMessage"); 320 binder.getErrors().rejectValue("spouse.name", "someCode", "someMessage"); 321 322 assertEquals("", binder.getErrors().getNestedPath()); 323 assertEquals("value", binder.getErrors().getFieldValue("name")); 324 assertEquals("prefixvalue", binder.getErrors().getFieldError("name").getRejectedValue()); 325 assertEquals("prefixvalue", tb.getName()); 326 assertEquals("value", binder.getErrors().getFieldValue("touchy")); 327 assertEquals("value", binder.getErrors().getFieldError("touchy").getRejectedValue()); 328 assertEquals("value", tb.getTouchy()); 329 330 assertTrue(binder.getErrors().hasFieldErrors("spouse.*")); 331 assertEquals(1, binder.getErrors().getFieldErrorCount("spouse.*")); 332 assertEquals("spouse.name", binder.getErrors().getFieldError("spouse.*").getField()); 333 } 334 335 public void testCustomEditorForPrimitiveProperty() { 336 TestBean tb = new TestBean(); 337 DataBinder binder = new DataBinder(tb, "tb"); 338 339 binder.registerCustomEditor(int.class, "age", new PropertyEditorSupport () { 340 public void setAsText(String text) throws IllegalArgumentException { 341 setValue(new Integer (99)); 342 } 343 public String getAsText() { 344 return "argh"; 345 } 346 }); 347 348 MutablePropertyValues pvs = new MutablePropertyValues(); 349 pvs.addPropertyValue(new PropertyValue("age", "")); 350 binder.bind(pvs); 351 352 assertEquals("argh", binder.getErrors().getFieldValue("age")); 353 assertEquals(99, tb.getAge()); 354 } 355 356 public void testCustomEditorForAllStringProperties() { 357 TestBean tb = new TestBean(); 358 DataBinder binder = new DataBinder(tb, "tb"); 359 360 binder.registerCustomEditor(String .class, null, new PropertyEditorSupport () { 361 public void setAsText(String text) throws IllegalArgumentException { 362 setValue("prefix" + text); 363 } 364 public String getAsText() { 365 return ((String ) getValue()).substring(6); 366 } 367 }); 368 369 MutablePropertyValues pvs = new MutablePropertyValues(); 370 pvs.addPropertyValue(new PropertyValue("name", "value")); 371 pvs.addPropertyValue(new PropertyValue("touchy", "value")); 372 binder.bind(pvs); 373 374 binder.getErrors().rejectValue("name", "someCode", "someMessage"); 375 binder.getErrors().rejectValue("touchy", "someCode", "someMessage"); 376 377 assertEquals("value", binder.getErrors().getFieldValue("name")); 378 assertEquals("prefixvalue", binder.getErrors().getFieldError("name").getRejectedValue()); 379 assertEquals("prefixvalue", tb.getName()); 380 assertEquals("value", binder.getErrors().getFieldValue("touchy")); 381 assertEquals("prefixvalue", binder.getErrors().getFieldError("touchy").getRejectedValue()); 382 assertEquals("prefixvalue", tb.getTouchy()); 383 } 384 385 public void testValidatorNoErrors() { 386 TestBean tb = new TestBean(); 387 tb.setAge(33); 388 tb.setName("Rod"); 389 try { 390 tb.setTouchy("Rod"); 391 } 392 catch (Exception e) { 393 fail("Should not throw any Exception"); 394 } 395 TestBean tb2 = new TestBean(); 396 tb2.setAge(34); 397 tb.setSpouse(tb2); 398 DataBinder db = new DataBinder(tb, "tb"); 399 MutablePropertyValues pvs = new MutablePropertyValues(); 400 pvs.addPropertyValue("spouse.age", "argh"); 401 db.bind(pvs); 402 Errors errors = db.getErrors(); 403 Validator testValidator = new TestBeanValidator(); 404 testValidator.validate(tb, errors); 405 406 errors.setNestedPath("spouse"); 407 assertEquals("spouse.", errors.getNestedPath()); 408 assertEquals("argh", errors.getFieldValue("age")); 409 Validator spouseValidator = new SpouseValidator(); 410 spouseValidator.validate(tb.getSpouse(), errors); 411 412 errors.setNestedPath(""); 413 assertEquals("", errors.getNestedPath()); 414 errors.pushNestedPath("spouse"); 415 assertEquals("spouse.", errors.getNestedPath()); 416 errors.pushNestedPath("spouse"); 417 assertEquals("spouse.spouse.", errors.getNestedPath()); 418 errors.popNestedPath(); 419 assertEquals("spouse.", errors.getNestedPath()); 420 errors.popNestedPath(); 421 assertEquals("", errors.getNestedPath()); 422 try { 423 errors.popNestedPath(); 424 } 425 catch (IllegalStateException ex) { 426 } 428 errors.pushNestedPath("spouse"); 429 assertEquals("spouse.", errors.getNestedPath()); 430 errors.setNestedPath(""); 431 assertEquals("", errors.getNestedPath()); 432 try { 433 errors.popNestedPath(); 434 } 435 catch (IllegalStateException ex) { 436 } 438 439 errors.pushNestedPath("spouse"); 440 assertEquals("spouse.", errors.getNestedPath()); 441 442 assertEquals(1, errors.getErrorCount()); 443 assertTrue(!errors.hasGlobalErrors()); 444 assertEquals(1, errors.getFieldErrorCount("age")); 445 assertTrue(!errors.hasFieldErrors("name")); 446 } 447 448 public void testValidatorWithErrors() { 449 TestBean tb = new TestBean(); 450 tb.setSpouse(new TestBean()); 451 Errors errors = new BindException(tb, "tb"); 452 Validator testValidator = new TestBeanValidator(); 453 testValidator.validate(tb, errors); 454 errors.setNestedPath("spouse."); 455 assertEquals("spouse.", errors.getNestedPath()); 456 Validator spouseValidator = new SpouseValidator(); 457 spouseValidator.validate(tb.getSpouse(), errors); 458 459 errors.setNestedPath(""); 460 assertEquals(6, errors.getErrorCount()); 461 assertEquals(2, errors.getGlobalErrorCount()); 462 assertEquals("NAME_TOUCHY_MISMATCH", errors.getGlobalError().getCode()); 463 assertEquals("NAME_TOUCHY_MISMATCH", ((ObjectError) errors.getGlobalErrors().get(0)).getCode()); 464 assertEquals("NAME_TOUCHY_MISMATCH.tb", ((ObjectError) errors.getGlobalErrors().get(0)).getCodes()[0]); 465 assertEquals("NAME_TOUCHY_MISMATCH", ((ObjectError) errors.getGlobalErrors().get(0)).getCodes()[1]); 466 assertEquals("tb", ((ObjectError) errors.getGlobalErrors().get(0)).getObjectName()); 467 assertEquals("GENERAL_ERROR", ((ObjectError) errors.getGlobalErrors().get(1)).getCode()); 468 assertEquals("GENERAL_ERROR.tb", ((ObjectError) errors.getGlobalErrors().get(1)).getCodes()[0]); 469 assertEquals("GENERAL_ERROR", ((ObjectError) errors.getGlobalErrors().get(1)).getCodes()[1]); 470 assertEquals("msg", ((ObjectError) errors.getGlobalErrors().get(1)).getDefaultMessage()); 471 assertEquals("arg", ((ObjectError) errors.getGlobalErrors().get(1)).getArguments()[0]); 472 assertEquals(2, errors.getFieldErrorCount("age")); 473 assertEquals("TOO_YOUNG", errors.getFieldError("age").getCode()); 474 assertEquals("TOO_YOUNG", ((FieldError) errors.getFieldErrors("age").get(0)).getCode()); 475 assertEquals("tb", ((FieldError) errors.getFieldErrors("age").get(0)).getObjectName()); 476 assertEquals("age", ((FieldError) errors.getFieldErrors("age").get(0)).getField()); 477 assertEquals(new Integer (0), ((FieldError) errors.getFieldErrors("age").get(0)).getRejectedValue()); 478 assertEquals("AGE_NOT_ODD", ((FieldError) errors.getFieldErrors("age").get(1)).getCode()); 479 assertEquals(1, errors.getFieldErrorCount("name")); 480 assertEquals("NOT_ROD", errors.getFieldError("name").getCode()); 481 assertEquals("NOT_ROD.tb.name", errors.getFieldError("name").getCodes()[0]); 482 assertEquals("NOT_ROD.name", errors.getFieldError("name").getCodes()[1]); 483 assertEquals("NOT_ROD.java.lang.String", errors.getFieldError("name").getCodes()[2]); 484 assertEquals("NOT_ROD", errors.getFieldError("name").getCodes()[3]); 485 assertEquals("name", ((FieldError) errors.getFieldErrors("name").get(0)).getField()); 486 assertEquals(null, ((FieldError) errors.getFieldErrors("name").get(0)).getRejectedValue()); 487 assertEquals(1, errors.getFieldErrorCount("spouse.age")); 488 assertEquals("TOO_YOUNG", errors.getFieldError("spouse.age").getCode()); 489 assertEquals("tb", ((FieldError) errors.getFieldErrors("spouse.age").get(0)).getObjectName()); 490 assertEquals(new Integer (0), ((FieldError) errors.getFieldErrors("spouse.age").get(0)).getRejectedValue()); 491 } 492 493 public void testBindingStringArrayToIntegerSet() { 494 IndexedTestBean tb = new IndexedTestBean(); 495 DataBinder binder = new DataBinder(tb, "tb"); 496 binder.registerCustomEditor(Set .class, new CustomCollectionEditor(TreeSet .class) { 497 protected Object convertElement(Object element) { 498 return new Integer (element.toString()); 499 } 500 }); 501 MutablePropertyValues pvs = new MutablePropertyValues(); 502 pvs.addPropertyValue("set", new String [] {"10", "20", "30"}); 503 binder.bind(pvs); 504 505 assertEquals(tb.getSet(), binder.getErrors().getFieldValue("set")); 506 assertTrue(tb.getSet() instanceof TreeSet ); 507 assertEquals(3, tb.getSet().size()); 508 assertTrue(tb.getSet().contains(new Integer (10))); 509 assertTrue(tb.getSet().contains(new Integer (20))); 510 assertTrue(tb.getSet().contains(new Integer (30))); 511 } 512 513 public void testBindingToIndexedField() { 514 IndexedTestBean tb = new IndexedTestBean(); 515 DataBinder binder = new DataBinder(tb, "tb"); 516 binder.registerCustomEditor(String .class, "array.name", new PropertyEditorSupport () { 517 public void setAsText(String text) throws IllegalArgumentException { 518 setValue("array" + text); 519 } 520 }); 521 MutablePropertyValues pvs = new MutablePropertyValues(); 522 pvs.addPropertyValue("array[0]", "a"); 523 binder.bind(pvs); 524 Errors errors = binder.getErrors(); 525 errors.rejectValue("array[0].name", "NOT_ROD", "are you sure you're not Rod?"); 526 errors.rejectValue("map[key1].name", "NOT_ROD", "are you sure you're not Rod?"); 527 528 assertEquals(1, errors.getFieldErrorCount("array[0].name")); 529 assertEquals("NOT_ROD", errors.getFieldError("array[0].name").getCode()); 530 assertEquals("NOT_ROD.tb.array[0].name", errors.getFieldError("array[0].name").getCodes()[0]); 531 assertEquals("NOT_ROD.tb.array.name", errors.getFieldError("array[0].name").getCodes()[1]); 532 assertEquals("NOT_ROD.array[0].name", errors.getFieldError("array[0].name").getCodes()[2]); 533 assertEquals("NOT_ROD.array.name", errors.getFieldError("array[0].name").getCodes()[3]); 534 assertEquals("NOT_ROD.name", errors.getFieldError("array[0].name").getCodes()[4]); 535 assertEquals("NOT_ROD.java.lang.String", errors.getFieldError("array[0].name").getCodes()[5]); 536 assertEquals("NOT_ROD", errors.getFieldError("array[0].name").getCodes()[6]); 537 assertEquals(1, errors.getFieldErrorCount("map[key1].name")); 538 assertEquals("NOT_ROD", errors.getFieldError("map[key1].name").getCode()); 539 assertEquals("NOT_ROD.tb.map[key1].name", errors.getFieldError("map[key1].name").getCodes()[0]); 540 assertEquals("NOT_ROD.tb.map.name", errors.getFieldError("map[key1].name").getCodes()[1]); 541 assertEquals("NOT_ROD.map[key1].name", errors.getFieldError("map[key1].name").getCodes()[2]); 542 assertEquals("NOT_ROD.map.name", errors.getFieldError("map[key1].name").getCodes()[3]); 543 assertEquals("NOT_ROD.name", errors.getFieldError("map[key1].name").getCodes()[4]); 544 assertEquals("NOT_ROD.java.lang.String", errors.getFieldError("map[key1].name").getCodes()[5]); 545 assertEquals("NOT_ROD", errors.getFieldError("map[key1].name").getCodes()[6]); 546 } 547 548 public void testBindingToNestedIndexedField() { 549 IndexedTestBean tb = new IndexedTestBean(); 550 tb.getArray()[0].setNestedIndexedBean(new IndexedTestBean()); 551 tb.getArray()[1].setNestedIndexedBean(new IndexedTestBean()); 552 DataBinder binder = new DataBinder(tb, "tb"); 553 binder.registerCustomEditor(String .class, "array.nestedIndexedBean.list.name", new PropertyEditorSupport () { 554 public void setAsText(String text) throws IllegalArgumentException { 555 setValue("list" + text); 556 } 557 }); 558 MutablePropertyValues pvs = new MutablePropertyValues(); 559 pvs.addPropertyValue("array[0].nestedIndexedBean.list[0].name", "a"); 560 binder.bind(pvs); 561 Errors errors = binder.getErrors(); 562 errors.rejectValue("array[0].nestedIndexedBean.list[0].name", "NOT_ROD", "are you sure you're not Rod?"); 563 564 assertEquals(1, errors.getFieldErrorCount("array[0].nestedIndexedBean.list[0].name")); 565 assertEquals("NOT_ROD", errors.getFieldError("array[0].nestedIndexedBean.list[0].name").getCode()); 566 assertEquals("NOT_ROD.tb.array[0].nestedIndexedBean.list[0].name", 567 errors.getFieldError("array[0].nestedIndexedBean.list[0].name").getCodes()[0]); 568 assertEquals("NOT_ROD.tb.array[0].nestedIndexedBean.list.name", 569 errors.getFieldError("array[0].nestedIndexedBean.list[0].name").getCodes()[1]); 570 assertEquals("NOT_ROD.tb.array.nestedIndexedBean.list.name", 571 errors.getFieldError("array[0].nestedIndexedBean.list[0].name").getCodes()[2]); 572 assertEquals("NOT_ROD.array[0].nestedIndexedBean.list[0].name", 573 errors.getFieldError("array[0].nestedIndexedBean.list[0].name").getCodes()[3]); 574 assertEquals("NOT_ROD.array[0].nestedIndexedBean.list.name", 575 errors.getFieldError("array[0].nestedIndexedBean.list[0].name").getCodes()[4]); 576 assertEquals("NOT_ROD.array.nestedIndexedBean.list.name", 577 errors.getFieldError("array[0].nestedIndexedBean.list[0].name").getCodes()[5]); 578 assertEquals("NOT_ROD.name", errors.getFieldError("array[0].nestedIndexedBean.list[0].name").getCodes()[6]); 579 assertEquals("NOT_ROD.java.lang.String", 580 errors.getFieldError("array[0].nestedIndexedBean.list[0].name").getCodes()[7]); 581 assertEquals("NOT_ROD", errors.getFieldError("array[0].nestedIndexedBean.list[0].name").getCodes()[8]); 582 } 583 584 public void testEditorForNestedIndexedField() { 585 IndexedTestBean tb = new IndexedTestBean(); 586 tb.getArray()[0].setNestedIndexedBean(new IndexedTestBean()); 587 tb.getArray()[1].setNestedIndexedBean(new IndexedTestBean()); 588 DataBinder binder = new DataBinder(tb, "tb"); 589 binder.registerCustomEditor(String .class, "array.nestedIndexedBean.list.name", new PropertyEditorSupport () { 590 public void setAsText(String text) throws IllegalArgumentException { 591 setValue("list" + text); 592 } 593 public String getAsText() { 594 return ((String ) getValue()).substring(4); 595 } 596 }); 597 MutablePropertyValues pvs = new MutablePropertyValues(); 598 pvs.addPropertyValue("array[0].nestedIndexedBean.list[0].name", "test1"); 599 pvs.addPropertyValue("array[1].nestedIndexedBean.list[1].name", "test2"); 600 binder.bind(pvs); 601 assertEquals("listtest1", ((TestBean) tb.getArray()[0].getNestedIndexedBean().getList().get(0)).getName()); 602 assertEquals("listtest2", ((TestBean) tb.getArray()[1].getNestedIndexedBean().getList().get(1)).getName()); 603 assertEquals("test1", binder.getErrors().getFieldValue("array[0].nestedIndexedBean.list[0].name")); 604 assertEquals("test2", binder.getErrors().getFieldValue("array[1].nestedIndexedBean.list[1].name")); 605 } 606 607 public void testSpecificEditorForNestedIndexedField() { 608 IndexedTestBean tb = new IndexedTestBean(); 609 tb.getArray()[0].setNestedIndexedBean(new IndexedTestBean()); 610 tb.getArray()[1].setNestedIndexedBean(new IndexedTestBean()); 611 DataBinder binder = new DataBinder(tb, "tb"); 612 binder.registerCustomEditor(String .class, "array[0].nestedIndexedBean.list.name", new PropertyEditorSupport () { 613 public void setAsText(String text) throws IllegalArgumentException { 614 setValue("list" + text); 615 } 616 public String getAsText() { 617 return ((String ) getValue()).substring(4); 618 } 619 }); 620 MutablePropertyValues pvs = new MutablePropertyValues(); 621 pvs.addPropertyValue("array[0].nestedIndexedBean.list[0].name", "test1"); 622 pvs.addPropertyValue("array[1].nestedIndexedBean.list[1].name", "test2"); 623 binder.bind(pvs); 624 assertEquals("listtest1", ((TestBean) tb.getArray()[0].getNestedIndexedBean().getList().get(0)).getName()); 625 assertEquals("test2", ((TestBean) tb.getArray()[1].getNestedIndexedBean().getList().get(1)).getName()); 626 assertEquals("test1", binder.getErrors().getFieldValue("array[0].nestedIndexedBean.list[0].name")); 627 assertEquals("test2", binder.getErrors().getFieldValue("array[1].nestedIndexedBean.list[1].name")); 628 } 629 630 public void testInnerSpecificEditorForNestedIndexedField() { 631 IndexedTestBean tb = new IndexedTestBean(); 632 tb.getArray()[0].setNestedIndexedBean(new IndexedTestBean()); 633 tb.getArray()[1].setNestedIndexedBean(new IndexedTestBean()); 634 DataBinder binder = new DataBinder(tb, "tb"); 635 binder.registerCustomEditor(String .class, "array.nestedIndexedBean.list[0].name", new PropertyEditorSupport () { 636 public void setAsText(String text) throws IllegalArgumentException { 637 setValue("list" + text); 638 } 639 public String getAsText() { 640 return ((String ) getValue()).substring(4); 641 } 642 }); 643 MutablePropertyValues pvs = new MutablePropertyValues(); 644 pvs.addPropertyValue("array[0].nestedIndexedBean.list[0].name", "test1"); 645 pvs.addPropertyValue("array[1].nestedIndexedBean.list[1].name", "test2"); 646 binder.bind(pvs); 647 assertEquals("listtest1", ((TestBean) tb.getArray()[0].getNestedIndexedBean().getList().get(0)).getName()); 648 assertEquals("test2", ((TestBean) tb.getArray()[1].getNestedIndexedBean().getList().get(1)).getName()); 649 assertEquals("test1", binder.getErrors().getFieldValue("array[0].nestedIndexedBean.list[0].name")); 650 assertEquals("test2", binder.getErrors().getFieldValue("array[1].nestedIndexedBean.list[1].name")); 651 } 652 653 public void testDirectBindingToIndexedField() { 654 IndexedTestBean tb = new IndexedTestBean(); 655 DataBinder binder = new DataBinder(tb, "tb"); 656 binder.registerCustomEditor(TestBean.class, "array", new PropertyEditorSupport () { 657 public void setAsText(String text) throws IllegalArgumentException { 658 DerivedTestBean tb = new DerivedTestBean(); 659 tb.setName("array" + text); 660 setValue(tb); 661 } 662 public String getAsText() { 663 return ((TestBean) getValue()).getName(); 664 } 665 }); 666 MutablePropertyValues pvs = new MutablePropertyValues(); 667 pvs.addPropertyValue("array[0]", "a"); 668 binder.bind(pvs); 669 Errors errors = binder.getErrors(); 670 errors.rejectValue("array[0]", "NOT_ROD", "are you sure you're not Rod?"); 671 errors.rejectValue("map[key1]", "NOT_ROD", "are you sure you're not Rod?"); 672 errors.rejectValue("map[key0]", "NOT_NULL", "should not be null"); 673 674 assertEquals("arraya", errors.getFieldValue("array[0]")); 675 assertEquals(1, errors.getFieldErrorCount("array[0]")); 676 assertEquals("NOT_ROD", errors.getFieldError("array[0]").getCode()); 677 assertEquals("NOT_ROD.tb.array[0]", errors.getFieldError("array[0]").getCodes()[0]); 678 assertEquals("NOT_ROD.tb.array", errors.getFieldError("array[0]").getCodes()[1]); 679 assertEquals("NOT_ROD.array[0]", errors.getFieldError("array[0]").getCodes()[2]); 680 assertEquals("NOT_ROD.array", errors.getFieldError("array[0]").getCodes()[3]); 681 assertEquals("NOT_ROD.org.springframework.beans.DerivedTestBean", errors.getFieldError("array[0]").getCodes()[4]); 682 assertEquals("NOT_ROD", errors.getFieldError("array[0]").getCodes()[5]); 683 assertEquals("arraya", errors.getFieldValue("array[0]")); 684 685 assertEquals(1, errors.getFieldErrorCount("map[key1]")); 686 assertEquals("NOT_ROD", errors.getFieldError("map[key1]").getCode()); 687 assertEquals("NOT_ROD.tb.map[key1]", errors.getFieldError("map[key1]").getCodes()[0]); 688 assertEquals("NOT_ROD.tb.map", errors.getFieldError("map[key1]").getCodes()[1]); 689 assertEquals("NOT_ROD.map[key1]", errors.getFieldError("map[key1]").getCodes()[2]); 690 assertEquals("NOT_ROD.map", errors.getFieldError("map[key1]").getCodes()[3]); 691 assertEquals("NOT_ROD.org.springframework.beans.TestBean", errors.getFieldError("map[key1]").getCodes()[4]); 692 assertEquals("NOT_ROD", errors.getFieldError("map[key1]").getCodes()[5]); 693 694 assertEquals(1, errors.getFieldErrorCount("map[key0]")); 695 assertEquals("NOT_NULL", errors.getFieldError("map[key0]").getCode()); 696 assertEquals("NOT_NULL.tb.map[key0]", errors.getFieldError("map[key0]").getCodes()[0]); 697 assertEquals("NOT_NULL.tb.map", errors.getFieldError("map[key0]").getCodes()[1]); 698 assertEquals("NOT_NULL.map[key0]", errors.getFieldError("map[key0]").getCodes()[2]); 699 assertEquals("NOT_NULL.map", errors.getFieldError("map[key0]").getCodes()[3]); 700 assertEquals("NOT_NULL", errors.getFieldError("map[key0]").getCodes()[4]); 701 } 702 703 public void testCustomEditorWithSubclass() { 704 IndexedTestBean tb = new IndexedTestBean(); 705 DataBinder binder = new DataBinder(tb, "tb"); 706 binder.registerCustomEditor(TestBean.class, new PropertyEditorSupport () { 707 public void setAsText(String text) throws IllegalArgumentException { 708 DerivedTestBean tb = new DerivedTestBean(); 709 tb.setName("array" + text); 710 setValue(tb); 711 } 712 public String getAsText() { 713 return ((TestBean) getValue()).getName(); 714 } 715 }); 716 MutablePropertyValues pvs = new MutablePropertyValues(); 717 pvs.addPropertyValue("array[0]", "a"); 718 binder.bind(pvs); 719 Errors errors = binder.getErrors(); 720 errors.rejectValue("array[0]", "NOT_ROD", "are you sure you're not Rod?"); 721 722 assertEquals("arraya", errors.getFieldValue("array[0]")); 723 assertEquals(1, errors.getFieldErrorCount("array[0]")); 724 assertEquals("NOT_ROD", errors.getFieldError("array[0]").getCode()); 725 assertEquals("NOT_ROD.tb.array[0]", errors.getFieldError("array[0]").getCodes()[0]); 726 assertEquals("NOT_ROD.tb.array", errors.getFieldError("array[0]").getCodes()[1]); 727 assertEquals("NOT_ROD.array[0]", errors.getFieldError("array[0]").getCodes()[2]); 728 assertEquals("NOT_ROD.array", errors.getFieldError("array[0]").getCodes()[3]); 729 assertEquals("NOT_ROD.org.springframework.beans.DerivedTestBean", errors.getFieldError("array[0]").getCodes()[4]); 730 assertEquals("NOT_ROD", errors.getFieldError("array[0]").getCodes()[5]); 731 assertEquals("arraya", errors.getFieldValue("array[0]")); 732 } 733 734 public void testBindToStringArrayWithArrayEditor() { 735 TestBean tb = new TestBean(); 736 DataBinder binder = new DataBinder(tb, "tb"); 737 binder.registerCustomEditor(String [].class, "stringArray", new PropertyEditorSupport () { 738 public void setAsText(String text) throws IllegalArgumentException { 739 setValue(StringUtils.delimitedListToStringArray(text, "-")); 740 } 741 }); 742 MutablePropertyValues pvs = new MutablePropertyValues(); 743 pvs.addPropertyValue("stringArray", "a1-b2"); 744 binder.bind(pvs); 745 assertTrue(!binder.getErrors().hasErrors()); 746 assertEquals(2, tb.getStringArray().length); 747 assertEquals("a1", tb.getStringArray()[0]); 748 assertEquals("b2", tb.getStringArray()[1]); 749 } 750 751 public void testBindToStringArrayWithComponentEditor() { 752 TestBean tb = new TestBean(); 753 DataBinder binder = new DataBinder(tb, "tb"); 754 binder.registerCustomEditor(String .class, "stringArray", new PropertyEditorSupport () { 755 public void setAsText(String text) throws IllegalArgumentException { 756 setValue("X" + text); 757 } 758 }); 759 MutablePropertyValues pvs = new MutablePropertyValues(); 760 pvs.addPropertyValue("stringArray", new String [] {"a1", "b2"}); 761 binder.bind(pvs); 762 assertTrue(!binder.getErrors().hasErrors()); 763 assertEquals(2, tb.getStringArray().length); 764 assertEquals("Xa1", tb.getStringArray()[0]); 765 assertEquals("Xb2", tb.getStringArray()[1]); 766 } 767 768 public void testBindingErrors() { 769 TestBean rod = new TestBean(); 770 DataBinder binder = new DataBinder(rod, "person"); 771 MutablePropertyValues pvs = new MutablePropertyValues(); 772 pvs.addPropertyValue(new PropertyValue("age", "32x")); 773 binder.bind(pvs); 774 Errors errors = binder.getErrors(); 775 FieldError ageError = errors.getFieldError("age"); 776 assertEquals("typeMismatch", ageError.getCode()); 777 778 ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); 779 messageSource.setBasename("org.springframework.validation.messages1"); 780 String msg = messageSource.getMessage(ageError, Locale.getDefault()); 781 assertEquals("Field age did not have correct type", msg); 782 783 messageSource = new ResourceBundleMessageSource(); 784 messageSource.setBasename("org.springframework.validation.messages2"); 785 msg = messageSource.getMessage(ageError, Locale.getDefault()); 786 assertEquals("Field Age did not have correct type", msg); 787 788 messageSource = new ResourceBundleMessageSource(); 789 messageSource.setBasename("org.springframework.validation.messages3"); 790 msg = messageSource.getMessage(ageError, Locale.getDefault()); 791 assertEquals("Field Person Age did not have correct type", msg); 792 } 793 794 public void testAddAllErrors() { 795 TestBean rod = new TestBean(); 796 DataBinder binder = new DataBinder(rod, "person"); 797 MutablePropertyValues pvs = new MutablePropertyValues(); 798 pvs.addPropertyValue(new PropertyValue("age", "32x")); 799 binder.bind(pvs); 800 Errors errors = binder.getErrors(); 801 802 BindException errors2 = new BindException(rod, "person"); 803 errors.rejectValue("name", "badName"); 804 errors.addAllErrors(errors2); 805 806 FieldError ageError = errors.getFieldError("age"); 807 assertEquals("typeMismatch", ageError.getCode()); 808 FieldError nameError = errors.getFieldError("name"); 809 assertEquals("badName", nameError.getCode()); 810 } 811 812 public void testBindingWithResortedList() { 813 IndexedTestBean tb = new IndexedTestBean(); 814 DataBinder binder = new DataBinder(tb, "tb"); 815 MutablePropertyValues pvs = new MutablePropertyValues(); 816 TestBean tb1 = new TestBean("tb1", 99); 817 TestBean tb2 = new TestBean("tb2", 99); 818 pvs.addPropertyValue("list[0]", tb1); 819 pvs.addPropertyValue("list[1]", tb2); 820 binder.bind(pvs); 821 assertEquals(tb1.getName(), binder.getErrors().getFieldValue("list[0].name")); 822 assertEquals(tb2.getName(), binder.getErrors().getFieldValue("list[1].name")); 823 tb.getList().set(0, tb2); 824 tb.getList().set(1, tb1); 825 assertEquals(tb2.getName(), binder.getErrors().getFieldValue("list[0].name")); 826 assertEquals(tb1.getName(), binder.getErrors().getFieldValue("list[1].name")); 827 } 828 829 public void testRejectWithoutDefaultMessage() throws Exception { 830 TestBean tb = new TestBean(); 831 tb.setName("myName"); 832 tb.setAge(99); 833 834 BindException ex = new BindException(tb, "tb"); 835 ex.reject("invalid"); 836 ex.rejectValue("age", "invalidField"); 837 838 StaticMessageSource ms = new StaticMessageSource(); 839 ms.addMessage("invalid", Locale.US, "general error"); 840 ms.addMessage("invalidField", Locale.US, "invalid field"); 841 842 assertEquals("general error", ms.getMessage(ex.getGlobalError(), Locale.US)); 843 assertEquals("invalid field", ms.getMessage(ex.getFieldError("age"), Locale.US)); 844 } 845 846 public void testBindExceptionSerializable() throws Exception { 847 SerializablePerson tb = new SerializablePerson(); 848 tb.setName("myName"); 849 tb.setAge(99); 850 851 BindException ex = new BindException(tb, "tb"); 852 ex.reject("invalid", "someMessage"); 853 ex.rejectValue("age", "invalidField", "someMessage"); 854 855 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 856 ObjectOutputStream oos = new ObjectOutputStream (baos); 857 oos.writeObject(ex); 858 ByteArrayInputStream bais = new ByteArrayInputStream (baos.toByteArray()); 859 ObjectInputStream ois = new ObjectInputStream (bais); 860 861 BindException ex2 = (BindException) ois.readObject(); 862 assertTrue(ex2.hasGlobalErrors()); 863 assertEquals("invalid", ex2.getGlobalError().getCode()); 864 assertTrue(ex2.hasFieldErrors("age")); 865 assertEquals("invalidField", ex2.getFieldError("age").getCode()); 866 assertEquals(new Integer (99), ex2.getFieldValue("age")); 867 868 ex2.rejectValue("name", "invalidField", "someMessage"); 869 assertTrue(ex2.hasFieldErrors("name")); 870 assertEquals("invalidField", ex2.getFieldError("name").getCode()); 871 assertEquals("myName", ex2.getFieldValue("name")); 872 } 873 874 875 private static class TestBeanValidator implements Validator { 876 877 public boolean supports(Class clazz) { 878 return TestBean.class.isAssignableFrom(clazz); 879 } 880 881 public void validate(Object obj, Errors errors) { 882 TestBean tb = (TestBean) obj; 883 if (tb.getAge() < 32) { 884 errors.rejectValue("age", "TOO_YOUNG", null, "simply too young"); 885 } 886 if (tb.getAge() % 2 == 0) { 887 errors.rejectValue("age", "AGE_NOT_ODD", null, "your age isn't odd"); 888 } 889 if (tb.getName() == null || !tb.getName().equals("Rod")) { 890 errors.rejectValue("name", "NOT_ROD", "are you sure you're not Rod?"); 891 } 892 if (tb.getTouchy() == null || !tb.getTouchy().equals(tb.getName())) { 893 errors.reject("NAME_TOUCHY_MISMATCH", "name and touchy do not match"); 894 } 895 if (tb.getAge() == 0) { 896 errors.reject("GENERAL_ERROR", new String []{"arg"}, "msg"); 897 } 898 } 899 } 900 901 902 private static class SpouseValidator implements Validator { 903 904 public boolean supports(Class clazz) { 905 return TestBean.class.isAssignableFrom(clazz); 906 } 907 908 public void validate(Object obj, Errors errors) { 909 TestBean tb = (TestBean) obj; 910 if (tb.getAge() < 32) { 911 errors.rejectValue("age", "TOO_YOUNG", null, "simply too young"); 912 } 913 } 914 } 915 916 } 917 | Popular Tags |