1 8 9 package com.sleepycat.persist.test; 10 11 import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE; 12 import static com.sleepycat.persist.model.Relationship.ONE_TO_MANY; 13 import static com.sleepycat.persist.model.Relationship.ONE_TO_ONE; 14 15 import java.io.File ; 16 import java.io.IOException ; 17 import java.lang.reflect.Array ; 18 import java.lang.reflect.Field ; 19 import java.math.BigInteger ; 20 import java.util.ArrayList ; 21 import java.util.Arrays ; 22 import java.util.Collection ; 23 import java.util.Comparator ; 24 import java.util.Date ; 25 import java.util.HashMap ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 import java.util.Locale ; 31 import java.util.Map ; 32 import java.util.Set ; 33 import java.util.TreeMap ; 34 import java.util.TreeSet ; 35 36 import junit.framework.TestCase; 37 38 import com.sleepycat.bind.EntryBinding; 39 import com.sleepycat.je.DatabaseConfig; 40 import com.sleepycat.je.DatabaseEntry; 41 import com.sleepycat.je.DatabaseException; 42 import com.sleepycat.je.Environment; 43 import com.sleepycat.je.EnvironmentConfig; 44 import com.sleepycat.je.ForeignMultiKeyNullifier; 45 import com.sleepycat.je.SecondaryKeyCreator; 46 import com.sleepycat.je.SecondaryMultiKeyCreator; 47 import com.sleepycat.je.util.TestUtils; 48 import com.sleepycat.persist.impl.PersistCatalog; 49 import com.sleepycat.persist.impl.PersistComparator; 50 import com.sleepycat.persist.impl.PersistEntityBinding; 51 import com.sleepycat.persist.impl.PersistKeyBinding; 52 import com.sleepycat.persist.impl.PersistKeyCreator; 53 import com.sleepycat.persist.impl.SimpleCatalog; 54 import com.sleepycat.persist.model.AnnotationModel; 55 import com.sleepycat.persist.model.ClassMetadata; 56 import com.sleepycat.persist.model.Entity; 57 import com.sleepycat.persist.model.EntityMetadata; 58 import com.sleepycat.persist.model.EntityModel; 59 import com.sleepycat.persist.model.KeyField; 60 import com.sleepycat.persist.model.Persistent; 61 import com.sleepycat.persist.model.PersistentProxy; 62 import com.sleepycat.persist.model.PrimaryKey; 63 import com.sleepycat.persist.model.PrimaryKeyMetadata; 64 import com.sleepycat.persist.model.SecondaryKey; 65 import com.sleepycat.persist.model.SecondaryKeyMetadata; 66 import com.sleepycat.persist.raw.RawField; 67 import com.sleepycat.persist.raw.RawObject; 68 import com.sleepycat.persist.raw.RawType; 69 70 73 public class BindingTest extends TestCase { 74 75 private static final String STORE_PREFIX = "persist#foo#"; 76 77 private File envHome; 78 private Environment env; 79 private EntityModel model; 80 private PersistCatalog catalog; 81 private DatabaseEntry keyEntry; 82 private DatabaseEntry dataEntry; 83 84 public void setUp() 85 throws IOException { 86 87 envHome = new File (System.getProperty(TestUtils.DEST_DIR)); 88 keyEntry = new DatabaseEntry(); 89 dataEntry = new DatabaseEntry(); 90 TestUtils.removeLogFiles("Setup", envHome, false); 91 } 92 93 public void tearDown() 94 throws IOException { 95 96 if (env != null) { 97 try { 98 env.close(); 99 } catch (DatabaseException e) { 100 System.out.println("During tearDown: " + e); 101 } 102 } 103 try { 104 TestUtils.removeLogFiles("TearDown", envHome, false); 105 } catch (Error e) { 106 System.out.println("During tearDown: " + e); 107 } 108 envHome = null; 109 env = null; 110 catalog = null; 111 keyEntry = null; 112 dataEntry = null; 113 } 114 115 private void open() 116 throws DatabaseException { 117 118 EnvironmentConfig envConfig = new EnvironmentConfig(); 119 envConfig.setAllowCreate(true); 120 env = new Environment(envHome, envConfig); 121 122 openCatalog(); 123 } 124 125 private void openCatalog() 126 throws DatabaseException { 127 128 model = new AnnotationModel(); 129 model.registerClass(LocalizedTextProxy.class); 130 model.registerClass(LocaleProxy.class); 131 132 DatabaseConfig dbConfig = new DatabaseConfig(); 133 dbConfig.setAllowCreate(true); 134 catalog = new PersistCatalog 135 (null, env, STORE_PREFIX, "catalog", dbConfig, model, null, 136 false , null ); 137 } 138 139 private void close() 140 throws DatabaseException { 141 142 143 catalog.close(); 144 PersistCatalog.expectNoClassChanges = true; 145 try { 146 openCatalog(); 147 } finally { 148 PersistCatalog.expectNoClassChanges = false; 149 } 150 catalog.close(); 151 catalog = null; 152 153 env.close(); 154 env = null; 155 } 156 157 public void testBasic() 158 throws DatabaseException { 159 160 open(); 161 162 checkEntity(Basic.class, 163 new Basic(1, "one", 2.2, "three")); 164 checkEntity(Basic.class, 165 new Basic(0, null, 0, null)); 166 checkEntity(Basic.class, 167 new Basic(-1, "xxx", -2, "xxx")); 168 169 checkMetadata(Basic.class.getName(), new String [][] { 170 {"id", "long"}, 171 {"one", "java.lang.String"}, 172 {"two", "double"}, 173 {"three", "java.lang.String"}, 174 }, 175 0 , null); 176 177 close(); 178 } 179 180 @Entity 181 static class Basic implements MyEntity { 182 183 @PrimaryKey 184 private long id; 185 private String one; 186 private double two; 187 private String three; 188 189 private Basic() { } 190 191 private Basic(long id, String one, double two, String three) { 192 this.id = id; 193 this.one = one; 194 this.two = two; 195 this.three = three; 196 } 197 198 public String getBasicOne() { 199 return one; 200 } 201 202 public Object getPriKeyObject() { 203 return id; 204 } 205 206 public void validate(Object other) { 207 Basic o = (Basic) other; 208 TestCase.assertEquals(id, o.id); 209 TestCase.assertTrue(nullOrEqual(one, o.one)); 210 TestCase.assertEquals(two, o.two); 211 TestCase.assertTrue(nullOrEqual(three, o.three)); 212 if (one == three) { 213 TestCase.assertSame(o.one, o.three); 214 } 215 } 216 217 @Override 218 public String toString() { 219 return "" + id + ' ' + one + ' ' + two; 220 } 221 } 222 223 public void testSimpleTypes() 224 throws DatabaseException { 225 226 open(); 227 228 checkEntity(SimpleTypes.class, new SimpleTypes()); 229 230 checkMetadata(SimpleTypes.class.getName(), new String [][] { 231 {"f0", "boolean"}, 232 {"f1", "char"}, 233 {"f2", "byte"}, 234 {"f3", "short"}, 235 {"f4", "int"}, 236 {"f5", "long"}, 237 {"f6", "float"}, 238 {"f7", "double"}, 239 {"f8", "java.lang.String"}, 240 {"f9", "java.math.BigInteger"}, 241 {"f11", "java.util.Date"}, 243 {"f12", "java.lang.Boolean"}, 244 {"f13", "java.lang.Character"}, 245 {"f14", "java.lang.Byte"}, 246 {"f15", "java.lang.Short"}, 247 {"f16", "java.lang.Integer"}, 248 {"f17", "java.lang.Long"}, 249 {"f18", "java.lang.Float"}, 250 {"f19", "java.lang.Double"}, 251 }, 252 0 , null); 253 254 close(); 255 } 256 257 @Entity 258 static class SimpleTypes implements MyEntity { 259 260 @PrimaryKey 261 private boolean f0 = true; 262 private char f1 = 'a'; 263 private byte f2 = 123; 264 private short f3 = 123; 265 private int f4 = 123; 266 private long f5 = 123; 267 private float f6 = 123.4f; 268 private double f7 = 123.4; 269 private String f8 = "xxx"; 270 private BigInteger f9 = BigInteger.valueOf(123); 271 private Date f11 = new Date (); 273 private Boolean f12 = true; 274 private Character f13 = 'a'; 275 private Byte f14 = 123; 276 private Short f15 = 123; 277 private Integer f16 = 123; 278 private Long f17 = 123L; 279 private Float f18 = 123.4f; 280 private Double f19 = 123.4; 281 282 SimpleTypes() { } 283 284 public Object getPriKeyObject() { 285 return f0; 286 } 287 288 public void validate(Object other) { 289 SimpleTypes o = (SimpleTypes) other; 290 TestCase.assertEquals(f0, o.f0); 291 TestCase.assertEquals(f1, o.f1); 292 TestCase.assertEquals(f2, o.f2); 293 TestCase.assertEquals(f3, o.f3); 294 TestCase.assertEquals(f4, o.f4); 295 TestCase.assertEquals(f5, o.f5); 296 TestCase.assertEquals(f6, o.f6); 297 TestCase.assertEquals(f7, o.f7); 298 TestCase.assertEquals(f8, o.f8); 299 TestCase.assertEquals(f9, o.f9); 300 TestCase.assertEquals(f11, o.f11); 302 TestCase.assertEquals(f12, o.f12); 303 TestCase.assertEquals(f13, o.f13); 304 TestCase.assertEquals(f14, o.f14); 305 TestCase.assertEquals(f15, o.f15); 306 TestCase.assertEquals(f16, o.f16); 307 TestCase.assertEquals(f17, o.f17); 308 TestCase.assertEquals(f18, o.f18); 309 TestCase.assertEquals(f19, o.f19); 310 } 311 } 312 313 public void testArrayTypes() 314 throws DatabaseException { 315 316 open(); 317 318 checkEntity(ArrayTypes.class, new ArrayTypes()); 319 320 checkMetadata(ArrayTypes.class.getName(), new String [][] { 321 {"id", "int"}, 322 {"f0", boolean[].class.getName()}, 323 {"f1", char[].class.getName()}, 324 {"f2", byte[].class.getName()}, 325 {"f3", short[].class.getName()}, 326 {"f4", int[].class.getName()}, 327 {"f5", long[].class.getName()}, 328 {"f6", float[].class.getName()}, 329 {"f7", double[].class.getName()}, 330 {"f8", String [].class.getName()}, 331 {"f9", Address[].class.getName()}, 332 {"f10", boolean[][][].class.getName()}, 333 {"f11", String [][][].class.getName()}, 334 }, 335 0 , null); 336 337 close(); 338 } 339 340 @Entity 341 static class ArrayTypes implements MyEntity { 342 343 @PrimaryKey 344 private int id = 1; 345 private boolean[] f0 = {false, true}; 346 private char[] f1 = {'a', 'b'}; 347 private byte[] f2 = {1, 2}; 348 private short[] f3 = {1, 2}; 349 private int[] f4 = {1, 2}; 350 private long[] f5 = {1, 2}; 351 private float[] f6 = {1.1f, 2.2f}; 352 private double[] f7 = {1.1, 2,2}; 353 private String [] f8 = {"xxx", null, "yyy"}; 354 private Address[] f9 = {new Address("city", "state", 123), 355 null, 356 new Address("x", "y", 444)}; 357 private boolean[][][] f10 = 358 { 359 { 360 {false, true}, 361 {false, true}, 362 }, 363 null, 364 { 365 {false, true}, 366 {false, true}, 367 }, 368 }; 369 private String [][][] f11 = 370 { 371 { 372 {"xxx", null, "yyy"}, 373 null, 374 {"xxx", null, "yyy"}, 375 }, 376 null, 377 { 378 {"xxx", null, "yyy"}, 379 null, 380 {"xxx", null, "yyy"}, 381 }, 382 }; 383 384 ArrayTypes() { } 385 386 public Object getPriKeyObject() { 387 return id; 388 } 389 390 public void validate(Object other) { 391 ArrayTypes o = (ArrayTypes) other; 392 TestCase.assertEquals(id, o.id); 393 TestCase.assertTrue(Arrays.equals(f0, o.f0)); 394 TestCase.assertTrue(Arrays.equals(f1, o.f1)); 395 TestCase.assertTrue(Arrays.equals(f2, o.f2)); 396 TestCase.assertTrue(Arrays.equals(f3, o.f3)); 397 TestCase.assertTrue(Arrays.equals(f4, o.f4)); 398 TestCase.assertTrue(Arrays.equals(f5, o.f5)); 399 TestCase.assertTrue(Arrays.equals(f6, o.f6)); 400 TestCase.assertTrue(Arrays.equals(f7, o.f7)); 401 TestCase.assertTrue(Arrays.equals(f8, o.f8)); 402 TestCase.assertTrue(Arrays.deepEquals(f9, o.f9)); 403 TestCase.assertTrue(Arrays.deepEquals(f10, o.f10)); 404 TestCase.assertTrue(Arrays.deepEquals(f11, o.f11)); 405 } 406 } 407 408 public void testEnumTypes() 409 throws DatabaseException { 410 411 open(); 412 413 checkEntity(EnumTypes.class, new EnumTypes()); 414 415 checkMetadata(EnumTypes.class.getName(), new String [][] { 416 {"f0", "int"}, 417 {"f1", Thread.State .class.getName()}, 418 {"f2", EnumTypes.MyEnum.class.getName()}, 419 {"f3", Object .class.getName()}, 420 }, 421 0 , null); 422 423 close(); 424 } 425 426 @Entity 427 static class EnumTypes implements MyEntity { 428 429 private static enum MyEnum { ONE, TWO }; 430 431 @PrimaryKey 432 private int f0 = 1; 433 private Thread.State f1 = Thread.State.RUNNABLE; 434 private MyEnum f2 = MyEnum.ONE; 435 private Object f3 = MyEnum.TWO; 436 437 EnumTypes() { } 438 439 public Object getPriKeyObject() { 440 return f0; 441 } 442 443 public void validate(Object other) { 444 EnumTypes o = (EnumTypes) other; 445 TestCase.assertEquals(f0, o.f0); 446 TestCase.assertSame(f1, o.f1); 447 TestCase.assertSame(f2, o.f2); 448 TestCase.assertSame(f3, o.f3); 449 } 450 } 451 452 public void testProxyTypes() 453 throws DatabaseException { 454 455 open(); 456 457 checkEntity(ProxyTypes.class, new ProxyTypes()); 458 459 checkMetadata(ProxyTypes.class.getName(), new String [][] { 460 {"f0", "int"}, 461 {"f1", Locale .class.getName()}, 462 {"f2", Set .class.getName()}, 463 {"f3", Set .class.getName()}, 464 {"f4", Object .class.getName()}, 465 {"f5", HashMap .class.getName()}, 466 {"f6", TreeMap .class.getName()}, 467 {"f7", List .class.getName()}, 468 {"f8", LinkedList .class.getName()}, 469 {"f9", LocalizedText.class.getName()}, 470 }, 471 0 , null); 472 473 close(); 474 } 475 476 @Entity 477 static class ProxyTypes implements MyEntity { 478 479 @PrimaryKey 480 private int f0 = 1; 481 private Locale f1 = Locale.getDefault(); 482 private Set <Integer > f2 = new HashSet <Integer >(); 483 private Set <Integer > f3 = new TreeSet <Integer >(); 484 private Object f4 = new HashSet <Address>(); 485 private HashMap <String ,Integer > f5 = new HashMap <String ,Integer >(); 486 private TreeMap <String ,Address> f6 = new TreeMap <String ,Address>(); 487 private List <Integer > f7 = new ArrayList <Integer >(); 488 private LinkedList <Integer > f8 = new LinkedList <Integer >(); 489 private LocalizedText f9 = new LocalizedText(f1, "xyz"); 490 491 ProxyTypes() { 492 f2.add(123); 493 f2.add(456); 494 f3.add(456); 495 f3.add(123); 496 HashSet <Address> s = (HashSet ) f4; 497 s.add(new Address("city", "state", 11111)); 498 s.add(new Address("city2", "state2", 22222)); 499 s.add(new Address("city3", "state3", 33333)); 500 f5.put("one", 111); 501 f5.put("two", 222); 502 f5.put("three", 333); 503 f6.put("one", new Address("city", "state", 11111)); 504 f6.put("two", new Address("city2", "state2", 22222)); 505 f6.put("three", new Address("city3", "state3", 33333)); 506 f7.add(123); 507 f7.add(456); 508 f8.add(123); 509 f8.add(456); 510 } 511 512 public Object getPriKeyObject() { 513 return f0; 514 } 515 516 public void validate(Object other) { 517 ProxyTypes o = (ProxyTypes) other; 518 TestCase.assertEquals(f0, o.f0); 519 TestCase.assertEquals(f1, o.f1); 520 TestCase.assertEquals(f2, o.f2); 521 TestCase.assertEquals(f3, o.f3); 522 TestCase.assertEquals(f4, o.f4); 523 TestCase.assertEquals(f5, o.f5); 524 TestCase.assertEquals(f6, o.f6); 525 TestCase.assertEquals(f7, o.f7); 526 TestCase.assertEquals(f8, o.f8); 527 TestCase.assertEquals(f9, o.f9); 528 } 529 } 530 531 @Persistent(proxyFor=Locale .class) 532 static class LocaleProxy implements PersistentProxy<Locale > { 533 534 String language; 535 String country; 536 String variant; 537 538 private LocaleProxy() {} 539 540 public void initializeProxy(Locale object) { 541 language = object.getLanguage(); 542 country = object.getCountry(); 543 variant = object.getVariant(); 544 } 545 546 public Locale convertProxy() { 547 return new Locale (language, country, variant); 548 } 549 } 550 551 static class LocalizedText { 552 553 Locale locale; 554 String text; 555 556 LocalizedText(Locale locale, String text) { 557 this.locale = locale; 558 this.text = text; 559 } 560 561 @Override 562 public boolean equals(Object other) { 563 LocalizedText o = (LocalizedText) other; 564 return text.equals(o.text) && 565 locale.equals(o.locale); 566 } 567 } 568 569 @Persistent(proxyFor=LocalizedText.class) 570 static class LocalizedTextProxy implements PersistentProxy<LocalizedText> { 571 572 Locale locale; 573 String text; 574 575 private LocalizedTextProxy() {} 576 577 public void initializeProxy(LocalizedText object) { 578 locale = object.locale; 579 text = object.text; 580 } 581 582 public LocalizedText convertProxy() { 583 return new LocalizedText(locale, text); 584 } 585 } 586 587 public void testEmbedded() 588 throws DatabaseException { 589 590 open(); 591 592 Address a1 = new Address("city", "state", 123); 593 Address a2 = new Address("Wikieup", "AZ", 85360); 594 595 checkEntity(Embedded.class, 596 new Embedded("x", a1, a2)); 597 checkEntity(Embedded.class, 598 new Embedded("y", a1, null)); 599 checkEntity(Embedded.class, 600 new Embedded("", a2, a2)); 601 602 checkMetadata(Embedded.class.getName(), new String [][] { 603 {"id", "java.lang.String"}, 604 {"idShadow", "java.lang.String"}, 605 {"one", Address.class.getName()}, 606 {"two", Address.class.getName()}, 607 }, 608 0 , null); 609 610 checkMetadata(Address.class.getName(), new String [][] { 611 {"street", "java.lang.String"}, 612 {"city", "java.lang.String"}, 613 {"zip", "int"}, 614 }, 615 -1 , null); 616 617 close(); 618 } 619 620 @Entity 621 static class Embedded implements MyEntity { 622 623 @PrimaryKey 624 private String id; 625 private String idShadow; 626 private Address one; 627 private Address two; 628 629 private Embedded() { } 630 631 private Embedded(String id, Address one, Address two) { 632 this.id = id; 633 idShadow = id; 634 this.one = one; 635 this.two = two; 636 } 637 638 public Object getPriKeyObject() { 639 return id; 640 } 641 642 public void validate(Object other) { 643 Embedded o = (Embedded) other; 644 TestCase.assertEquals(id, o.id); 645 if (one != null) { 646 one.validate(o.one); 647 } else { 648 assertNull(o.one); 649 } 650 if (two != null) { 651 two.validate(o.two); 652 } else { 653 assertNull(o.two); 654 } 655 TestCase.assertSame(o.id, o.idShadow); 656 if (one == two) { 657 TestCase.assertSame(o.one, o.two); 658 } 659 } 660 661 @Override 662 public String toString() { 663 return "" + id + ' ' + one + ' ' + two; 664 } 665 } 666 667 @Persistent 668 static class Address { 669 670 private String street; 671 private String city; 672 private int zip; 673 674 private Address() {} 675 676 Address(String street, String city, int zip) { 677 this.street = street; 678 this.city = city; 679 this.zip = zip; 680 } 681 682 void validate(Address o) { 683 TestCase.assertTrue(nullOrEqual(street, o.street)); 684 TestCase.assertTrue(nullOrEqual(city, o.city)); 685 TestCase.assertEquals(zip, o.zip); 686 } 687 688 @Override 689 public String toString() { 690 return "" + street + ' ' + city + ' ' + zip; 691 } 692 693 @Override 694 public boolean equals(Object other) { 695 if (other == null) { 696 return false; 697 } 698 Address o = (Address) other; 699 return nullOrEqual(street, o.street) && 700 nullOrEqual(city, o.city) && 701 nullOrEqual(zip, o.zip); 702 } 703 704 @Override 705 public int hashCode() { 706 return zip; 707 } 708 } 709 710 public void testSubclass() 711 throws DatabaseException { 712 713 open(); 714 715 checkEntity(Basic.class, 716 new Subclass(-1, "xxx", -2, "xxx", "xxx", true)); 717 718 checkMetadata(Basic.class.getName(), new String [][] { 719 {"id", "long"}, 720 {"one", "java.lang.String"}, 721 {"two", "double"}, 722 {"three", "java.lang.String"}, 723 }, 724 0 , null); 725 checkMetadata(Subclass.class.getName(), new String [][] { 726 {"one", "java.lang.String"}, 727 {"two", "boolean"}, 728 }, 729 -1 , Basic.class.getName()); 730 731 close(); 732 } 733 734 @Persistent 735 static class Subclass extends Basic { 736 737 private String one; 738 private boolean two; 739 740 private Subclass() { 741 } 742 743 private Subclass(long id, String one, double two, String three, 744 String subOne, boolean subTwo) { 745 super(id, one, two, three); 746 this.one = subOne; 747 this.two = subTwo; 748 } 749 750 public void validate(Object other) { 751 super.validate(other); 752 Subclass o = (Subclass) other; 753 TestCase.assertTrue(nullOrEqual(one, o.one)); 754 TestCase.assertEquals(two, o.two); 755 if (one == getBasicOne()) { 756 TestCase.assertSame(o.one, o.getBasicOne()); 757 } 758 } 759 } 760 761 public void testSuperclass() 762 throws DatabaseException { 763 764 open(); 765 766 checkEntity(UseSuperclass.class, 767 new UseSuperclass(33, "xxx")); 768 769 checkMetadata(Superclass.class.getName(), new String [][] { 770 {"id", "int"}, 771 {"one", "java.lang.String"}, 772 }, 773 0 , null); 774 checkMetadata(UseSuperclass.class.getName(), new String [][] { 775 }, 776 -1 , Superclass.class.getName()); 777 778 close(); 779 } 780 781 @Persistent 782 static class Superclass implements MyEntity { 783 784 @PrimaryKey 785 private int id; 786 private String one; 787 788 private Superclass() { } 789 790 private Superclass(int id, String one) { 791 this.id = id; 792 this.one = one; 793 } 794 795 public Object getPriKeyObject() { 796 return id; 797 } 798 799 public void validate(Object other) { 800 Superclass o = (Superclass) other; 801 TestCase.assertEquals(id, o.id); 802 TestCase.assertTrue(nullOrEqual(one, o.one)); 803 } 804 } 805 806 @Entity 807 static class UseSuperclass extends Superclass { 808 809 private UseSuperclass() { } 810 811 private UseSuperclass(int id, String one) { 812 super(id, one); 813 } 814 } 815 816 public void testAbstract() 817 throws DatabaseException { 818 819 open(); 820 821 checkEntity(EntityUseAbstract.class, 822 new EntityUseAbstract(33, "xxx")); 823 824 checkMetadata(Abstract.class.getName(), new String [][] { 825 {"one", "java.lang.String"}, 826 }, 827 -1 , null); 828 checkMetadata(EmbeddedUseAbstract.class.getName(), new String [][] { 829 {"two", "java.lang.String"}, 830 }, 831 -1 , Abstract.class.getName()); 832 checkMetadata(EntityUseAbstract.class.getName(), new String [][] { 833 {"id", "int"}, 834 {"f1", EmbeddedUseAbstract.class.getName()}, 835 {"f2", Abstract.class.getName()}, 836 {"f3", Object .class.getName()}, 837 {"f4", Interface.class.getName()}, 838 {"a1", EmbeddedUseAbstract[].class.getName()}, 839 {"a2", Abstract[].class.getName()}, 840 {"a3", Abstract[].class.getName()}, 841 {"a4", Object [].class.getName()}, 842 {"a5", Interface[].class.getName()}, 843 {"a6", Interface[].class.getName()}, 844 {"a7", Interface[].class.getName()}, 845 }, 846 0 , Abstract.class.getName()); 847 848 close(); 849 } 850 851 @Persistent 852 static abstract class Abstract implements Interface { 853 854 String one; 855 856 private Abstract() { } 857 858 private Abstract(String one) { 859 this.one = one; 860 } 861 862 public void validate(Object other) { 863 Abstract o = (Abstract) other; 864 TestCase.assertTrue(nullOrEqual(one, o.one)); 865 } 866 867 @Override 868 public boolean equals(Object other) { 869 Abstract o = (Abstract) other; 870 return nullOrEqual(one, o.one); 871 } 872 } 873 874 interface Interface { 875 void validate(Object other); 876 } 877 878 @Persistent 879 static class EmbeddedUseAbstract extends Abstract { 880 881 private String two; 882 883 private EmbeddedUseAbstract() { } 884 885 private EmbeddedUseAbstract(String one, String two) { 886 super(one); 887 this.two = two; 888 } 889 890 @Override 891 public void validate(Object other) { 892 super.validate(other); 893 EmbeddedUseAbstract o = (EmbeddedUseAbstract) other; 894 TestCase.assertTrue(nullOrEqual(two, o.two)); 895 } 896 897 @Override 898 public boolean equals(Object other) { 899 if (!super.equals(other)) { 900 return false; 901 } 902 EmbeddedUseAbstract o = (EmbeddedUseAbstract) other; 903 return nullOrEqual(two, o.two); 904 } 905 } 906 907 @Entity 908 static class EntityUseAbstract extends Abstract implements MyEntity { 909 910 @PrimaryKey 911 private int id; 912 913 private EmbeddedUseAbstract f1; 914 private Abstract f2; 915 private Object f3; 916 private Interface f4; 917 private EmbeddedUseAbstract[] a1; 918 private Abstract[] a2; 919 private Abstract[] a3; 920 private Object [] a4; 921 private Interface[] a5; 922 private Interface[] a6; 923 private Interface[] a7; 924 925 private EntityUseAbstract() { } 926 927 private EntityUseAbstract(int id, String one) { 928 super(one); 929 this.id = id; 930 f1 = new EmbeddedUseAbstract(one, one); 931 f2 = new EmbeddedUseAbstract(one + "x", one + "y"); 932 f3 = new EmbeddedUseAbstract(null, null); 933 f4 = new EmbeddedUseAbstract(null, null); 934 a1 = new EmbeddedUseAbstract[3]; 935 a2 = new EmbeddedUseAbstract[3]; 936 a3 = new Abstract[3]; 937 a4 = new Object [3]; 938 a5 = new EmbeddedUseAbstract[3]; 939 a6 = new Abstract[3]; 940 a7 = new Interface[3]; 941 for (int i = 0; i < 3; i += 1) { 942 a1[i] = new EmbeddedUseAbstract("1" + i, null); 943 a2[i] = new EmbeddedUseAbstract("2" + i, null); 944 a3[i] = new EmbeddedUseAbstract("3" + i, null); 945 a4[i] = new EmbeddedUseAbstract("4" + i, null); 946 a5[i] = new EmbeddedUseAbstract("5" + i, null); 947 a6[i] = new EmbeddedUseAbstract("6" + i, null); 948 a7[i] = new EmbeddedUseAbstract("7" + i, null); 949 } 950 } 951 952 public Object getPriKeyObject() { 953 return id; 954 } 955 956 @Override 957 public void validate(Object other) { 958 super.validate(other); 959 EntityUseAbstract o = (EntityUseAbstract) other; 960 TestCase.assertEquals(id, o.id); 961 f1.validate(o.f1); 962 assertSame(o.one, o.f1.one); 963 assertSame(o.f1.one, o.f1.two); 964 f2.validate(o.f2); 965 ((Abstract) f3).validate(o.f3); 966 f4.validate(o.f4); 967 assertTrue(arrayToString(a1) + ' ' + arrayToString(o.a1), 968 Arrays.equals(a1, o.a1)); 969 assertTrue(Arrays.equals(a2, o.a2)); 970 assertTrue(Arrays.equals(a3, o.a3)); 971 assertTrue(Arrays.equals(a4, o.a4)); 972 assertTrue(Arrays.equals(a5, o.a5)); 973 assertTrue(Arrays.equals(a6, o.a6)); 974 assertTrue(Arrays.equals(a7, o.a7)); 975 assertSame(EmbeddedUseAbstract.class, f2.getClass()); 976 assertSame(EmbeddedUseAbstract.class, f3.getClass()); 977 assertSame(EmbeddedUseAbstract[].class, a1.getClass()); 978 assertSame(EmbeddedUseAbstract[].class, a2.getClass()); 979 assertSame(Abstract[].class, a3.getClass()); 980 assertSame(Object [].class, a4.getClass()); 981 assertSame(EmbeddedUseAbstract[].class, a5.getClass()); 982 assertSame(Abstract[].class, a6.getClass()); 983 assertSame(Interface[].class, a7.getClass()); 984 } 985 } 986 987 public void testCompositeKey() 988 throws DatabaseException { 989 990 open(); 991 992 CompositeKey key = 993 new CompositeKey(123, 456L, "xyz", BigInteger.valueOf(789)); 994 checkEntity(UseCompositeKey.class, 995 new UseCompositeKey(key, "one")); 996 997 checkMetadata(UseCompositeKey.class.getName(), new String [][] { 998 {"key", CompositeKey.class.getName()}, 999 {"one", "java.lang.String"}, 1000 }, 1001 0 , null); 1002 1003 checkMetadata(CompositeKey.class.getName(), new String [][] { 1004 {"f1", "int"}, 1005 {"f2", "java.lang.Long"}, 1006 {"f3", "java.lang.String"}, 1007 {"f4", "java.math.BigInteger"}, 1008 }, 1009 -1 , null); 1010 1011 close(); 1012 } 1013 1014 @Persistent 1015 static class CompositeKey { 1016 @KeyField(3) 1017 private int f1; 1018 @KeyField(2) 1019 private Long f2; 1020 @KeyField(1) 1021 private String f3; 1022 @KeyField(4) 1023 private BigInteger f4; 1024 1025 private CompositeKey() {} 1026 1027 CompositeKey(int f1, Long f2, String f3, BigInteger f4) { 1028 this.f1 = f1; 1029 this.f2 = f2; 1030 this.f3 = f3; 1031 this.f4 = f4; 1032 } 1033 1034 void validate(CompositeKey o) { 1035 TestCase.assertEquals(f1, o.f1); 1036 TestCase.assertTrue(nullOrEqual(f2, o.f2)); 1037 TestCase.assertTrue(nullOrEqual(f3, o.f3)); 1038 TestCase.assertTrue(nullOrEqual(f4, o.f4)); 1039 } 1040 1041 @Override 1042 public boolean equals(Object other) { 1043 CompositeKey o = (CompositeKey) other; 1044 return f1 == o.f1 && 1045 nullOrEqual(f2, o.f2) && 1046 nullOrEqual(f3, o.f3) && 1047 nullOrEqual(f4, o.f4); 1048 } 1049 1050 @Override 1051 public int hashCode() { 1052 return f1; 1053 } 1054 1055 @Override 1056 public String toString() { 1057 return "" + f1 + ' ' + f2 + ' ' + f3 + ' ' + f4; 1058 } 1059 } 1060 1061 @Entity 1062 static class UseCompositeKey implements MyEntity { 1063 1064 @PrimaryKey 1065 private CompositeKey key; 1066 private String one; 1067 1068 private UseCompositeKey() { } 1069 1070 private UseCompositeKey(CompositeKey key, String one) { 1071 this.key = key; 1072 this.one = one; 1073 } 1074 1075 public Object getPriKeyObject() { 1076 return key; 1077 } 1078 1079 public void validate(Object other) { 1080 UseCompositeKey o = (UseCompositeKey) other; 1081 TestCase.assertNotNull(key); 1082 TestCase.assertNotNull(o.key); 1083 key.validate(o.key); 1084 TestCase.assertTrue(nullOrEqual(one, o.one)); 1085 } 1086 } 1087 1088 public void testComparableKey() 1089 throws DatabaseException { 1090 1091 open(); 1092 1093 ComparableKey key = new ComparableKey(123, 456); 1094 checkEntity(UseComparableKey.class, 1095 new UseComparableKey(key, "one")); 1096 1097 checkMetadata(UseComparableKey.class.getName(), new String [][] { 1098 {"key", ComparableKey.class.getName()}, 1099 {"one", "java.lang.String"}, 1100 }, 1101 0 , null); 1102 1103 checkMetadata(ComparableKey.class.getName(), new String [][] { 1104 {"f1", "int"}, 1105 {"f2", "int"}, 1106 }, 1107 -1 , null); 1108 1109 ClassMetadata classMeta = 1110 model.getClassMetadata(UseComparableKey.class.getName()); 1111 assertNotNull(classMeta); 1112 1113 PersistKeyBinding binding = new PersistKeyBinding 1114 (catalog, ComparableKey.class.getName(), false); 1115 1116 PersistComparator comparator = new PersistComparator 1117 (ComparableKey.class.getName(), 1118 classMeta.getCompositeKeyFields(), 1119 binding); 1120 1121 compareKeys(comparator, binding, new ComparableKey(1, 1), 1122 new ComparableKey(1, 1), 0); 1123 compareKeys(comparator, binding, new ComparableKey(1, 2), 1124 new ComparableKey(1, 1), -1); 1125 compareKeys(comparator, binding, new ComparableKey(2, 1), 1126 new ComparableKey(1, 1), -1); 1127 compareKeys(comparator, binding, new ComparableKey(2, 1), 1128 new ComparableKey(3, 1), 1); 1129 1130 close(); 1131 } 1132 1133 private void compareKeys(Comparator <Object > comparator, 1134 EntryBinding binding, 1135 Object key1, 1136 Object key2, 1137 int expectResult) { 1138 DatabaseEntry entry1 = new DatabaseEntry(); 1139 DatabaseEntry entry2 = new DatabaseEntry(); 1140 binding.objectToEntry(key1, entry1); 1141 binding.objectToEntry(key2, entry2); 1142 int result = comparator.compare(entry1.getData(), entry2.getData()); 1143 assertEquals(expectResult, result); 1144 } 1145 1146 @Persistent 1147 static class ComparableKey implements Comparable <ComparableKey> { 1148 @KeyField(2) 1149 private int f1; 1150 @KeyField(1) 1151 private int f2; 1152 1153 private ComparableKey() {} 1154 1155 ComparableKey(int f1, int f2) { 1156 this.f1 = f1; 1157 this.f2 = f2; 1158 } 1159 1160 void validate(ComparableKey o) { 1161 TestCase.assertEquals(f1, o.f1); 1162 TestCase.assertEquals(f2, o.f2); 1163 } 1164 1165 @Override 1166 public boolean equals(Object other) { 1167 ComparableKey o = (ComparableKey) other; 1168 return f1 == o.f1 && f2 == o.f2; 1169 } 1170 1171 @Override 1172 public int hashCode() { 1173 return f1 + f2; 1174 } 1175 1176 @Override 1177 public String toString() { 1178 return "" + f1 + ' ' + f2; 1179 } 1180 1181 1182 public int compareTo(ComparableKey o) { 1183 if (f1 != o.f1) { 1184 return o.f1 - f1; 1185 } else { 1186 return o.f2 - f2; 1187 } 1188 } 1189 } 1190 1191 @Entity 1192 static class UseComparableKey implements MyEntity { 1193 1194 @PrimaryKey 1195 private ComparableKey key; 1196 private String one; 1197 1198 private UseComparableKey() { } 1199 1200 private UseComparableKey(ComparableKey key, String one) { 1201 this.key = key; 1202 this.one = one; 1203 } 1204 1205 public Object getPriKeyObject() { 1206 return key; 1207 } 1208 1209 public void validate(Object other) { 1210 UseComparableKey o = (UseComparableKey) other; 1211 TestCase.assertNotNull(key); 1212 TestCase.assertNotNull(o.key); 1213 key.validate(o.key); 1214 TestCase.assertTrue(nullOrEqual(one, o.one)); 1215 } 1216 } 1217 1218 public void testSecKeys() 1219 throws DatabaseException { 1220 1221 open(); 1222 1223 SecKeys obj = new SecKeys(); 1224 checkEntity(SecKeys.class, obj); 1225 1226 checkMetadata(SecKeys.class.getName(), new String [][] { 1227 {"id", "long"}, 1228 {"f0", "boolean"}, 1229 {"g0", "boolean"}, 1230 {"f1", "char"}, 1231 {"g1", "char"}, 1232 {"f2", "byte"}, 1233 {"g2", "byte"}, 1234 {"f3", "short"}, 1235 {"g3", "short"}, 1236 {"f4", "int"}, 1237 {"g4", "int"}, 1238 {"f5", "long"}, 1239 {"g5", "long"}, 1240 {"f6", "float"}, 1241 {"g6", "float"}, 1242 {"f7", "double"}, 1243 {"g7", "double"}, 1244 {"f8", "java.lang.String"}, 1245 {"g8", "java.lang.String"}, 1246 {"f9", "java.math.BigInteger"}, 1247 {"g9", "java.math.BigInteger"}, 1248 {"f11", "java.util.Date"}, 1251 {"g11", "java.util.Date"}, 1252 {"f12", "java.lang.Boolean"}, 1253 {"g12", "java.lang.Boolean"}, 1254 {"f13", "java.lang.Character"}, 1255 {"g13", "java.lang.Character"}, 1256 {"f14", "java.lang.Byte"}, 1257 {"g14", "java.lang.Byte"}, 1258 {"f15", "java.lang.Short"}, 1259 {"g15", "java.lang.Short"}, 1260 {"f16", "java.lang.Integer"}, 1261 {"g16", "java.lang.Integer"}, 1262 {"f17", "java.lang.Long"}, 1263 {"g17", "java.lang.Long"}, 1264 {"f18", "java.lang.Float"}, 1265 {"g18", "java.lang.Float"}, 1266 {"f19", "java.lang.Double"}, 1267 {"g19", "java.lang.Double"}, 1268 {"f20", CompositeKey.class.getName()}, 1269 {"g20", CompositeKey.class.getName()}, 1270 {"f21", int[].class.getName()}, 1271 {"g21", int[].class.getName()}, 1272 {"f22", Integer [].class.getName()}, 1273 {"g22", Integer [].class.getName()}, 1274 {"f23", Set .class.getName()}, 1275 {"g23", Set .class.getName()}, 1276 {"f24", CompositeKey[].class.getName()}, 1277 {"g24", CompositeKey[].class.getName()}, 1278 {"f25", Set .class.getName()}, 1279 {"g25", Set .class.getName()}, 1280 {"f31", "java.util.Date"}, 1281 {"f32", "java.lang.Boolean"}, 1282 {"f33", "java.lang.Character"}, 1283 {"f34", "java.lang.Byte"}, 1284 {"f35", "java.lang.Short"}, 1285 {"f36", "java.lang.Integer"}, 1286 {"f37", "java.lang.Long"}, 1287 {"f38", "java.lang.Float"}, 1288 {"f39", "java.lang.Double"}, 1289 {"f40", CompositeKey.class.getName()}, 1290 }, 1291 0 , null); 1292 1293 checkSecKey(obj, "f0", obj.f0, Boolean .class); 1294 checkSecKey(obj, "f1", obj.f1, Character .class); 1295 checkSecKey(obj, "f2", obj.f2, Byte .class); 1296 checkSecKey(obj, "f3", obj.f3, Short .class); 1297 checkSecKey(obj, "f4", obj.f4, Integer .class); 1298 checkSecKey(obj, "f5", obj.f5, Long .class); 1299 checkSecKey(obj, "f6", obj.f6, Float .class); 1300 checkSecKey(obj, "f7", obj.f7, Double .class); 1301 checkSecKey(obj, "f8", obj.f8, String .class); 1302 checkSecKey(obj, "f9", obj.f9, BigInteger .class); 1303 checkSecKey(obj, "f11", obj.f11, Date .class); 1305 checkSecKey(obj, "f12", obj.f12, Boolean .class); 1306 checkSecKey(obj, "f13", obj.f13, Character .class); 1307 checkSecKey(obj, "f14", obj.f14, Byte .class); 1308 checkSecKey(obj, "f15", obj.f15, Short .class); 1309 checkSecKey(obj, "f16", obj.f16, Integer .class); 1310 checkSecKey(obj, "f17", obj.f17, Long .class); 1311 checkSecKey(obj, "f18", obj.f18, Float .class); 1312 checkSecKey(obj, "f19", obj.f19, Double .class); 1313 checkSecKey(obj, "f20", obj.f20, CompositeKey.class); 1314 1315 checkSecMultiKey(obj, "f21", toSet(obj.f21), Integer .class); 1316 checkSecMultiKey(obj, "f22", toSet(obj.f22), Integer .class); 1317 checkSecMultiKey(obj, "f23", toSet(obj.f23), Integer .class); 1318 checkSecMultiKey(obj, "f24", toSet(obj.f24), CompositeKey.class); 1319 checkSecMultiKey(obj, "f25", toSet(obj.f25), CompositeKey.class); 1320 1321 nullifySecKey(obj, "f8", obj.f8, String .class); 1322 nullifySecKey(obj, "f9", obj.f9, BigInteger .class); 1323 nullifySecKey(obj, "f11", obj.f11, Date .class); 1325 nullifySecKey(obj, "f12", obj.f12, Boolean .class); 1326 nullifySecKey(obj, "f13", obj.f13, Character .class); 1327 nullifySecKey(obj, "f14", obj.f14, Byte .class); 1328 nullifySecKey(obj, "f15", obj.f15, Short .class); 1329 nullifySecKey(obj, "f16", obj.f16, Integer .class); 1330 nullifySecKey(obj, "f17", obj.f17, Long .class); 1331 nullifySecKey(obj, "f18", obj.f18, Float .class); 1332 nullifySecKey(obj, "f19", obj.f19, Double .class); 1333 nullifySecKey(obj, "f20", obj.f20, CompositeKey.class); 1334 1335 nullifySecMultiKey(obj, "f21", obj.f21, Integer .class); 1336 nullifySecMultiKey(obj, "f22", obj.f22, Integer .class); 1337 nullifySecMultiKey(obj, "f23", obj.f23, Integer .class); 1338 nullifySecMultiKey(obj, "f24", obj.f24, CompositeKey.class); 1339 nullifySecMultiKey(obj, "f25", obj.f25, CompositeKey.class); 1340 1341 nullifySecKey(obj, "f31", obj.f31, Date .class); 1342 nullifySecKey(obj, "f32", obj.f32, Boolean .class); 1343 nullifySecKey(obj, "f33", obj.f33, Character .class); 1344 nullifySecKey(obj, "f34", obj.f34, Byte .class); 1345 nullifySecKey(obj, "f35", obj.f35, Short .class); 1346 nullifySecKey(obj, "f36", obj.f36, Integer .class); 1347 nullifySecKey(obj, "f37", obj.f37, Long .class); 1348 nullifySecKey(obj, "f38", obj.f38, Float .class); 1349 nullifySecKey(obj, "f39", obj.f39, Double .class); 1350 nullifySecKey(obj, "f40", obj.f40, CompositeKey.class); 1351 1352 close(); 1353 } 1354 1355 static Set toSet(int[] a) { 1356 Set set = new HashSet (); 1357 for (int i : a) { 1358 set.add(i); 1359 } 1360 return set; 1361 } 1362 1363 static Set toSet(Object [] a) { 1364 return new HashSet (Arrays.asList(a)); 1365 } 1366 1367 static Set toSet(Set s) { 1368 return s; 1369 } 1370 1371 @Entity 1372 static class SecKeys implements MyEntity { 1373 1374 @PrimaryKey 1375 long id; 1376 1377 @SecondaryKey(relate=MANY_TO_ONE) 1378 private boolean f0 = false; 1379 private boolean g0 = false; 1380 1381 @SecondaryKey(relate=MANY_TO_ONE) 1382 private char f1 = '1'; 1383 private char g1 = '1'; 1384 1385 @SecondaryKey(relate=MANY_TO_ONE) 1386 private byte f2 = 2; 1387 private byte g2 = 2; 1388 1389 @SecondaryKey(relate=MANY_TO_ONE) 1390 private short f3 = 3; 1391 private short g3 = 3; 1392 1393 @SecondaryKey(relate=MANY_TO_ONE) 1394 private int f4 = 4; 1395 private int g4 = 4; 1396 1397 @SecondaryKey(relate=MANY_TO_ONE) 1398 private long f5 = 5; 1399 private long g5 = 5; 1400 1401 @SecondaryKey(relate=MANY_TO_ONE) 1402 private float f6 = 6.6f; 1403 private float g6 = 6.6f; 1404 1405 @SecondaryKey(relate=MANY_TO_ONE) 1406 private double f7 = 7.7; 1407 private double g7 = 7.7; 1408 1409 @SecondaryKey(relate=MANY_TO_ONE) 1410 private String f8 = "8"; 1411 private String g8 = "8"; 1412 1413 @SecondaryKey(relate=MANY_TO_ONE) 1414 private BigInteger f9; 1415 private BigInteger g9; 1416 1417 1421 @SecondaryKey(relate=MANY_TO_ONE) 1422 private Date f11 = new Date (11); 1423 private Date g11 = new Date (11); 1424 1425 @SecondaryKey(relate=MANY_TO_ONE) 1426 private Boolean f12 = true; 1427 private Boolean g12 = true; 1428 1429 @SecondaryKey(relate=MANY_TO_ONE) 1430 private Character f13 = '3'; 1431 private Character g13 = '3'; 1432 1433 @SecondaryKey(relate=MANY_TO_ONE) 1434 private Byte f14 = 14; 1435 private Byte g14 = 14; 1436 1437 @SecondaryKey(relate=MANY_TO_ONE) 1438 private Short f15 = 15; 1439 private Short g15 = 15; 1440 1441 @SecondaryKey(relate=MANY_TO_ONE) 1442 private Integer f16 = 16; 1443 private Integer g16 = 16; 1444 1445 @SecondaryKey(relate=MANY_TO_ONE) 1446 private Long f17= 17L; 1447 private Long g17= 17L; 1448 1449 @SecondaryKey(relate=MANY_TO_ONE) 1450 private Float f18 = 18.18f; 1451 private Float g18 = 18.18f; 1452 1453 @SecondaryKey(relate=MANY_TO_ONE) 1454 private Double f19 = 19.19; 1455 private Double g19 = 19.19; 1456 1457 @SecondaryKey(relate=MANY_TO_ONE) 1458 private CompositeKey f20 = 1459 new CompositeKey(20, 20L, "20", BigInteger.valueOf(20)); 1460 private CompositeKey g20 = 1461 new CompositeKey(20, 20L, "20", BigInteger.valueOf(20)); 1462 1463 private static int[] arrayOfInt = { 100, 101, 102 }; 1464 1465 private static Integer [] arrayOfInteger = { 100, 101, 102 }; 1466 1467 private static CompositeKey[] arrayOfCompositeKey = { 1468 new CompositeKey(100, 100L, "100", BigInteger.valueOf(100)), 1469 new CompositeKey(101, 101L, "101", BigInteger.valueOf(101)), 1470 new CompositeKey(102, 102L, "102", BigInteger.valueOf(102)), 1471 }; 1472 1473 @SecondaryKey(relate=ONE_TO_MANY) 1474 private int[] f21 = arrayOfInt; 1475 private int[] g21 = f21; 1476 1477 @SecondaryKey(relate=ONE_TO_MANY) 1478 private Integer [] f22 = arrayOfInteger; 1479 private Integer [] g22 = f22; 1480 1481 @SecondaryKey(relate=ONE_TO_MANY) 1482 private Set <Integer > f23 = toSet(arrayOfInteger); 1483 private Set <Integer > g23 = f23; 1484 1485 @SecondaryKey(relate=ONE_TO_MANY) 1486 private CompositeKey[] f24 = arrayOfCompositeKey; 1487 private CompositeKey[] g24 = f24; 1488 1489 @SecondaryKey(relate=ONE_TO_MANY) 1490 private Set <CompositeKey> f25 = toSet(arrayOfCompositeKey); 1491 private Set <CompositeKey> g25 = f25; 1492 1493 1494 1495 @SecondaryKey(relate=MANY_TO_ONE) 1496 private Date f31 = f11; 1497 1498 @SecondaryKey(relate=MANY_TO_ONE) 1499 private Boolean f32 = f12; 1500 1501 @SecondaryKey(relate=MANY_TO_ONE) 1502 private Character f33 = f13; 1503 1504 @SecondaryKey(relate=MANY_TO_ONE) 1505 private Byte f34 = f14; 1506 1507 @SecondaryKey(relate=MANY_TO_ONE) 1508 private Short f35 = f15; 1509 1510 @SecondaryKey(relate=MANY_TO_ONE) 1511 private Integer f36 = f16; 1512 1513 @SecondaryKey(relate=MANY_TO_ONE) 1514 private Long f37= f17; 1515 1516 @SecondaryKey(relate=MANY_TO_ONE) 1517 private Float f38 = f18; 1518 1519 @SecondaryKey(relate=MANY_TO_ONE) 1520 private Double f39 = f19; 1521 1522 @SecondaryKey(relate=MANY_TO_ONE) 1523 private CompositeKey f40 = f20; 1524 1525 public Object getPriKeyObject() { 1526 return id; 1527 } 1528 1529 public void validate(Object other) { 1530 SecKeys o = (SecKeys) other; 1531 TestCase.assertEquals(id, o.id); 1532 1533 TestCase.assertEquals(f0, o.f0); 1534 TestCase.assertEquals(f1, o.f1); 1535 TestCase.assertEquals(f2, o.f2); 1536 TestCase.assertEquals(f3, o.f3); 1537 TestCase.assertEquals(f4, o.f4); 1538 TestCase.assertEquals(f5, o.f5); 1539 TestCase.assertEquals(f6, o.f6); 1540 TestCase.assertEquals(f7, o.f7); 1541 TestCase.assertEquals(f8, o.f8); 1542 TestCase.assertEquals(f9, o.f9); 1543 TestCase.assertEquals(f11, o.f11); 1545 TestCase.assertEquals(f12, o.f12); 1546 TestCase.assertEquals(f13, o.f13); 1547 TestCase.assertEquals(f14, o.f14); 1548 TestCase.assertEquals(f15, o.f15); 1549 TestCase.assertEquals(f16, o.f16); 1550 TestCase.assertEquals(f17, o.f17); 1551 TestCase.assertEquals(f18, o.f18); 1552 TestCase.assertEquals(f19, o.f19); 1553 TestCase.assertEquals(f20, o.f20); 1554 TestCase.assertTrue(Arrays.equals(f21, o.f21)); 1555 TestCase.assertTrue(Arrays.equals(f22, o.f22)); 1556 TestCase.assertEquals(f23, o.f23); 1557 TestCase.assertTrue(Arrays.equals(f24, o.f24)); 1558 TestCase.assertEquals(f25, o.f25); 1559 1560 TestCase.assertEquals(g0, o.g0); 1561 TestCase.assertEquals(g1, o.g1); 1562 TestCase.assertEquals(g2, o.g2); 1563 TestCase.assertEquals(g3, o.g3); 1564 TestCase.assertEquals(g4, o.g4); 1565 TestCase.assertEquals(g5, o.g5); 1566 TestCase.assertEquals(g6, o.g6); 1567 TestCase.assertEquals(g7, o.g7); 1568 TestCase.assertEquals(g8, o.g8); 1569 TestCase.assertEquals(g9, o.g9); 1570 TestCase.assertEquals(g11, o.g11); 1572 TestCase.assertEquals(g12, o.g12); 1573 TestCase.assertEquals(g13, o.g13); 1574 TestCase.assertEquals(g14, o.g14); 1575 TestCase.assertEquals(g15, o.g15); 1576 TestCase.assertEquals(g16, o.g16); 1577 TestCase.assertEquals(g17, o.g17); 1578 TestCase.assertEquals(g18, o.g18); 1579 TestCase.assertEquals(g19, o.g19); 1580 TestCase.assertEquals(g20, o.g20); 1581 TestCase.assertTrue(Arrays.equals(g21, o.g21)); 1582 TestCase.assertTrue(Arrays.equals(g22, o.g22)); 1583 TestCase.assertEquals(g23, o.g23); 1584 TestCase.assertTrue(Arrays.equals(g24, o.g24)); 1585 TestCase.assertEquals(g25, o.g25); 1586 1587 TestCase.assertEquals(f31, o.f31); 1588 TestCase.assertEquals(f32, o.f32); 1589 TestCase.assertEquals(f33, o.f33); 1590 TestCase.assertEquals(f34, o.f34); 1591 TestCase.assertEquals(f35, o.f35); 1592 TestCase.assertEquals(f36, o.f36); 1593 TestCase.assertEquals(f37, o.f37); 1594 TestCase.assertEquals(f38, o.f38); 1595 TestCase.assertEquals(f39, o.f39); 1596 TestCase.assertEquals(f40, o.f40); 1597 1598 checkSameIfNonNull(o.f31, o.f11); 1599 checkSameIfNonNull(o.f32, o.f12); 1600 checkSameIfNonNull(o.f33, o.f13); 1601 checkSameIfNonNull(o.f34, o.f14); 1602 checkSameIfNonNull(o.f35, o.f15); 1603 checkSameIfNonNull(o.f36, o.f16); 1604 checkSameIfNonNull(o.f37, o.f17); 1605 checkSameIfNonNull(o.f38, o.f18); 1606 checkSameIfNonNull(o.f39, o.f19); 1607 checkSameIfNonNull(o.f40, o.f20); 1608 } 1609 } 1610 1611 public void testSecKeyRefToPriKey() 1612 throws DatabaseException { 1613 1614 open(); 1615 1616 SecKeyRefToPriKey obj = new SecKeyRefToPriKey(); 1617 checkEntity(SecKeyRefToPriKey.class, obj); 1618 1619 checkMetadata(SecKeyRefToPriKey.class.getName(), new String [][] { 1620 {"priKey", "java.lang.String"}, 1621 {"secKey1", "java.lang.String"}, 1622 {"secKey2", String [].class.getName()}, 1623 {"secKey3", Set .class.getName()}, 1624 }, 1625 0 , null); 1626 1627 checkSecKey(obj, "secKey1", obj.secKey1, String .class); 1628 checkSecMultiKey(obj, "secKey2", toSet(obj.secKey2), String .class); 1629 checkSecMultiKey(obj, "secKey3", toSet(obj.secKey3), String .class); 1630 1631 close(); 1632 } 1633 1634 @Entity 1635 static class SecKeyRefToPriKey implements MyEntity { 1636 1637 @PrimaryKey 1638 private String priKey; 1639 1640 @SecondaryKey(relate=ONE_TO_ONE) 1641 private String secKey1; 1642 1643 @SecondaryKey(relate=ONE_TO_MANY) 1644 private String [] secKey2; 1645 1646 @SecondaryKey(relate=ONE_TO_MANY) 1647 private Set <String > secKey3 = new HashSet <String >(); 1648 1649 private SecKeyRefToPriKey() { 1650 priKey = "sharedValue"; 1651 secKey1 = priKey; 1652 secKey2 = new String [] { priKey }; 1653 secKey3.add(priKey); 1654 } 1655 1656 public Object getPriKeyObject() { 1657 return priKey; 1658 } 1659 1660 public void validate(Object other) { 1661 SecKeyRefToPriKey o = (SecKeyRefToPriKey) other; 1662 TestCase.assertEquals(priKey, o.priKey); 1663 TestCase.assertNotNull(o.secKey1); 1664 TestCase.assertEquals(1, o.secKey2.length); 1665 TestCase.assertEquals(1, o.secKey3.size()); 1666 TestCase.assertSame(o.secKey1, o.priKey); 1667 TestCase.assertSame(o.secKey2[0], o.priKey); 1668 TestCase.assertSame(o.secKey3.iterator().next(), o.priKey); 1669 } 1670 } 1671 1672 public void testSecKeyInSuperclass() 1673 throws DatabaseException { 1674 1675 open(); 1676 1677 SecKeyInSuperclassEntity obj = new SecKeyInSuperclassEntity(); 1678 checkEntity(SecKeyInSuperclassEntity.class, obj); 1679 1680 checkMetadata(SecKeyInSuperclass.class.getName(), new String [][] { 1681 {"priKey", "java.lang.String"}, 1682 {"secKey1", String .class.getName()}, 1683 }, 1684 0, null); 1685 1686 checkMetadata(SecKeyInSuperclassEntity.class.getName(), new String [][] { 1687 {"secKey2", "java.lang.String"}, 1688 }, 1689 -1 , SecKeyInSuperclass.class.getName()); 1690 1691 checkSecKey 1692 (obj, SecKeyInSuperclassEntity.class, "secKey1", obj.secKey1, 1693 String .class); 1694 checkSecKey 1695 (obj, SecKeyInSuperclassEntity.class, "secKey2", obj.secKey2, 1696 String .class); 1697 1698 close(); 1699 } 1700 1701 @Persistent 1702 static class SecKeyInSuperclass implements MyEntity { 1703 1704 @PrimaryKey 1705 String priKey = "1"; 1706 1707 @SecondaryKey(relate=ONE_TO_ONE) 1708 String secKey1 = "1"; 1709 1710 public Object getPriKeyObject() { 1711 return priKey; 1712 } 1713 1714 public void validate(Object other) { 1715 SecKeyInSuperclass o = (SecKeyInSuperclass) other; 1716 TestCase.assertEquals(secKey1, o.secKey1); 1717 } 1718 } 1719 1720 @Entity 1721 static class SecKeyInSuperclassEntity extends SecKeyInSuperclass { 1722 1723 @SecondaryKey(relate=ONE_TO_ONE) 1724 String secKey2 = "2"; 1725 1726 public void validate(Object other) { 1727 super.validate(other); 1728 SecKeyInSuperclassEntity o = (SecKeyInSuperclassEntity) other; 1729 TestCase.assertEquals(priKey, o.priKey); 1730 TestCase.assertEquals(secKey2, o.secKey2); 1731 } 1732 } 1733 1734 public void testSecKeyInSubclass() 1735 throws DatabaseException { 1736 1737 open(); 1738 1739 SecKeyInSubclass obj = new SecKeyInSubclass(); 1740 checkEntity(SecKeyInSubclassEntity.class, obj); 1741 1742 checkMetadata(SecKeyInSubclassEntity.class.getName(), new String [][] { 1743 {"priKey", "java.lang.String"}, 1744 {"secKey1", "java.lang.String"}, 1745 }, 1746 0 , null); 1747 1748 checkMetadata(SecKeyInSubclass.class.getName(), new String [][] { 1749 {"secKey2", String .class.getName()}, 1750 }, 1751 -1 , 1752 SecKeyInSubclassEntity.class.getName()); 1753 1754 checkSecKey 1755 (obj, SecKeyInSubclassEntity.class, "secKey1", obj.secKey1, 1756 String .class); 1757 checkSecKey 1758 (obj, SecKeyInSubclassEntity.class, "secKey2", obj.secKey2, 1759 String .class); 1760 1761 close(); 1762 } 1763 1764 @Entity 1765 static class SecKeyInSubclassEntity implements MyEntity { 1766 1767 @PrimaryKey 1768 String priKey = "1"; 1769 1770 @SecondaryKey(relate=ONE_TO_ONE) 1771 String secKey1; 1772 1773 public Object getPriKeyObject() { 1774 return priKey; 1775 } 1776 1777 public void validate(Object other) { 1778 SecKeyInSubclassEntity o = (SecKeyInSubclassEntity) other; 1779 TestCase.assertEquals(priKey, o.priKey); 1780 TestCase.assertEquals(secKey1, o.secKey1); 1781 } 1782 } 1783 1784 @Persistent 1785 static class SecKeyInSubclass extends SecKeyInSubclassEntity { 1786 1787 @SecondaryKey(relate=ONE_TO_ONE) 1788 String secKey2 = "2"; 1789 1790 public void validate(Object other) { 1791 super.validate(other); 1792 SecKeyInSubclass o = (SecKeyInSubclass) other; 1793 TestCase.assertEquals(secKey2, o.secKey2); 1794 } 1795 } 1796 1797 private static void checkSameIfNonNull(Object o1, Object o2) { 1798 if (o1 != null && o2 != null) { 1799 assertSame(o1, o2); 1800 } 1801 } 1802 1803 private void checkEntity(Class entityCls, MyEntity entity) 1804 throws DatabaseException { 1805 1806 Object priKey = entity.getPriKeyObject(); 1807 Class keyCls = priKey.getClass(); 1808 DatabaseEntry keyEntry2 = new DatabaseEntry(); 1809 DatabaseEntry dataEntry2 = new DatabaseEntry(); 1810 1811 1812 PersistEntityBinding entityBinding = 1813 new PersistEntityBinding(catalog, entityCls.getName(), false); 1814 entityBinding.objectToData(entity, dataEntry); 1815 entityBinding.objectToKey(entity, keyEntry); 1816 Object entity2 = entityBinding.entryToObject(keyEntry, dataEntry); 1817 entity.validate(entity2); 1818 1819 1820 PersistKeyBinding keyBinding = 1821 new PersistKeyBinding(catalog, keyCls.getName(), false); 1822 Object priKey2 = keyBinding.entryToObject(keyEntry); 1823 assertEquals(priKey, priKey2); 1824 keyBinding.objectToEntry(priKey2, keyEntry2); 1825 assertEquals(keyEntry, keyEntry2); 1826 1827 1828 PersistEntityBinding rawEntityBinding = 1829 new PersistEntityBinding(catalog, entityCls.getName(), true); 1830 RawObject rawEntity = 1831 (RawObject) rawEntityBinding.entryToObject(keyEntry, dataEntry); 1832 rawEntityBinding.objectToKey(rawEntity, keyEntry2); 1833 rawEntityBinding.objectToData(rawEntity, dataEntry2); 1834 entity2 = entityBinding.entryToObject(keyEntry2, dataEntry2); 1835 entity.validate(entity2); 1836 RawObject rawEntity2 = 1837 (RawObject) rawEntityBinding.entryToObject(keyEntry2, dataEntry2); 1838 assertEquals(rawEntity, rawEntity2); 1839 assertEquals(dataEntry, dataEntry2); 1840 assertEquals(keyEntry, keyEntry2); 1841 1842 1843 entity2 = catalog.convertRawObject(rawEntity, null); 1844 entity.validate(entity2); 1845 1846 1847 PersistKeyBinding rawKeyBinding = 1848 new PersistKeyBinding(catalog, keyCls.getName(), true); 1849 Object rawKey = rawKeyBinding.entryToObject(keyEntry); 1850 rawKeyBinding.objectToEntry(rawKey, keyEntry2); 1851 priKey2 = keyBinding.entryToObject(keyEntry2); 1852 assertEquals(priKey, priKey2); 1853 assertEquals(keyEntry, keyEntry2); 1854 } 1855 1856 private void checkSecKey(MyEntity entity, 1857 String keyName, 1858 Object keyValue, 1859 Class keyCls) 1860 throws DatabaseException { 1861 1862 checkSecKey(entity, entity.getClass(), keyName, keyValue, keyCls); 1863 } 1864 1865 private void checkSecKey(MyEntity entity, 1866 Class entityCls, 1867 String keyName, 1868 Object keyValue, 1869 Class keyCls) 1870 throws DatabaseException { 1871 1872 1873 EntityMetadata entityMeta = 1874 model.getEntityMetadata(entityCls.getName()); 1875 assertNotNull(entityMeta); 1876 1877 1878 SecondaryKeyMetadata secKeyMeta = 1879 entityMeta.getSecondaryKeys().get(keyName); 1880 assertNotNull(secKeyMeta); 1881 1882 1883 SecondaryKeyCreator keyCreator = new PersistKeyCreator 1884 (catalog, entityMeta, keyCls.getName(), secKeyMeta); 1885 1886 1887 PersistEntityBinding entityBinding = 1888 new PersistEntityBinding(catalog, entityCls.getName(), false); 1889 entityBinding.objectToData(entity, dataEntry); 1890 entityBinding.objectToKey(entity, keyEntry); 1891 1892 1893 DatabaseEntry secKeyEntry = new DatabaseEntry(); 1894 boolean isKeyPresent = keyCreator.createSecondaryKey 1895 (null, keyEntry, dataEntry, secKeyEntry); 1896 assertEquals(keyValue != null, isKeyPresent); 1897 1898 1899 PersistKeyBinding keyBinding = 1900 new PersistKeyBinding(catalog, keyCls.getName(), false); 1901 if (isKeyPresent) { 1902 Object keyValue2 = keyBinding.entryToObject(secKeyEntry); 1903 assertEquals(keyValue, keyValue2); 1904 DatabaseEntry secKeyEntry2 = new DatabaseEntry(); 1905 keyBinding.objectToEntry(keyValue2, secKeyEntry2); 1906 assertEquals(secKeyEntry, secKeyEntry2); 1907 } 1908 } 1909 1910 private void checkSecMultiKey(MyEntity entity, 1911 String keyName, 1912 Set keyValues, 1913 Class keyCls) 1914 throws DatabaseException { 1915 1916 1917 Class entityCls = entity.getClass(); 1918 EntityMetadata entityMeta = 1919 model.getEntityMetadata(entityCls.getName()); 1920 assertNotNull(entityMeta); 1921 1922 1923 SecondaryKeyMetadata secKeyMeta = 1924 entityMeta.getSecondaryKeys().get(keyName); 1925 assertNotNull(secKeyMeta); 1926 1927 1928 SecondaryMultiKeyCreator keyCreator = new PersistKeyCreator 1929 (catalog, entityMeta, keyCls.getName(), secKeyMeta); 1930 1931 1932 PersistEntityBinding entityBinding = 1933 new PersistEntityBinding(catalog, entityCls.getName(), false); 1934 entityBinding.objectToData(entity, dataEntry); 1935 entityBinding.objectToKey(entity, keyEntry); 1936 1937 1938 Set <DatabaseEntry> results = new HashSet <DatabaseEntry>(); 1939 keyCreator.createSecondaryKeys 1940 (null, keyEntry, dataEntry, results); 1941 assertEquals(keyValues.size(), results.size()); 1942 1943 1944 PersistKeyBinding keyBinding = 1945 new PersistKeyBinding(catalog, keyCls.getName(), false); 1946 Set keyValues2 = new HashSet (); 1947 for (DatabaseEntry secKeyEntry : results) { 1948 Object keyValue2 = keyBinding.entryToObject(secKeyEntry); 1949 keyValues2.add(keyValue2); 1950 } 1951 assertEquals(keyValues, keyValues2); 1952 } 1953 1954 private void nullifySecKey(MyEntity entity, 1955 String keyName, 1956 Object keyValue, 1957 Class keyCls) 1958 throws DatabaseException { 1959 1960 1961 Class entityCls = entity.getClass(); 1962 EntityMetadata entityMeta = 1963 model.getEntityMetadata(entityCls.getName()); 1964 assertNotNull(entityMeta); 1965 1966 1967 SecondaryKeyMetadata secKeyMeta = 1968 entityMeta.getSecondaryKeys().get(keyName); 1969 assertNotNull(secKeyMeta); 1970 1971 1972 ForeignMultiKeyNullifier keyNullifier = new PersistKeyCreator 1973 (catalog, entityMeta, keyCls.getName(), secKeyMeta); 1974 1975 1976 PersistEntityBinding entityBinding = 1977 new PersistEntityBinding(catalog, entityCls.getName(), false); 1978 entityBinding.objectToData(entity, dataEntry); 1979 entityBinding.objectToKey(entity, keyEntry); 1980 1981 1982 PersistKeyBinding keyBinding = 1983 new PersistKeyBinding(catalog, keyCls.getName(), false); 1984 DatabaseEntry secKeyEntry = new DatabaseEntry(); 1985 if (keyValue != null) { 1986 keyBinding.objectToEntry(keyValue, secKeyEntry); 1987 } 1988 1989 1990 boolean isKeyPresent = keyNullifier.nullifyForeignKey 1991 (null, keyEntry, dataEntry, secKeyEntry); 1992 assertEquals(keyValue != null, isKeyPresent); 1993 1994 1995 Object entity2 = entityBinding.entryToObject(keyEntry, dataEntry); 1996 setFieldToNull(entity, keyName); 1997 entity.validate(entity2); 1998 1999 2000 checkSecKey(entity, keyName, null, keyCls); 2001 } 2002 2003 private void nullifySecMultiKey(MyEntity entity, 2004 String keyName, 2005 Object keyValue, 2006 Class keyCls) 2007 throws DatabaseException { 2008 2009 2010 Class entityCls = entity.getClass(); 2011 EntityMetadata entityMeta = 2012 model.getEntityMetadata(entityCls.getName()); 2013 assertNotNull(entityMeta); 2014 2015 2016 SecondaryKeyMetadata secKeyMeta = 2017 entityMeta.getSecondaryKeys().get(keyName); 2018 assertNotNull(secKeyMeta); 2019 2020 2021 ForeignMultiKeyNullifier keyNullifier = new PersistKeyCreator 2022 (catalog, entityMeta, keyCls.getName(), secKeyMeta); 2023 2024 2025 PersistEntityBinding entityBinding = 2026 new PersistEntityBinding(catalog, entityCls.getName(), false); 2027 entityBinding.objectToData(entity, dataEntry); 2028 entityBinding.objectToKey(entity, keyEntry); 2029 2030 2031 PersistKeyBinding keyBinding = 2032 new PersistKeyBinding(catalog, keyCls.getName(), false); 2033 DatabaseEntry secKeyEntry = new DatabaseEntry(); 2034 2035 2036 while (true) { 2037 Object fieldObj = getField(entity, keyName); 2038 fieldObj = nullifyFirstElement(fieldObj, keyBinding, secKeyEntry); 2039 if (fieldObj == null) { 2040 break; 2041 } 2042 setField(entity, keyName, fieldObj); 2043 2044 2045 boolean isKeyPresent = keyNullifier.nullifyForeignKey 2046 (null, keyEntry, dataEntry, secKeyEntry); 2047 assertEquals(keyValue != null, isKeyPresent); 2048 2049 2050 Object entity2 = entityBinding.entryToObject(keyEntry, dataEntry); 2051 entity.validate(entity2); 2052 2053 2054 Set keyValues; 2055 if (fieldObj instanceof Set ) { 2056 keyValues = (Set ) fieldObj; 2057 } else if (fieldObj instanceof Object []) { 2058 keyValues = toSet((Object []) fieldObj); 2059 } else if (fieldObj instanceof int[]) { 2060 keyValues = toSet((int[]) fieldObj); 2061 } else { 2062 throw new IllegalStateException (fieldObj.getClass().getName()); 2063 } 2064 checkSecMultiKey(entity, keyName, keyValues, keyCls); 2065 } 2066 } 2067 2068 2074 private Object nullifyFirstElement(Object obj, 2075 EntryBinding keyBinding, 2076 DatabaseEntry keyEntry) { 2077 if (obj instanceof Collection ) { 2078 Iterator i = ((Collection ) obj).iterator(); 2079 if (i.hasNext()) { 2080 Object elem = i.next(); 2081 i.remove(); 2082 keyBinding.objectToEntry(elem, keyEntry); 2083 return obj; 2084 } else { 2085 return null; 2086 } 2087 } else if (obj instanceof Object []) { 2088 Object [] a1 = (Object []) obj; 2089 if (a1.length > 0) { 2090 Object [] a2 = (Object []) Array.newInstance 2091 (obj.getClass().getComponentType(), a1.length - 1); 2092 System.arraycopy(a1, 1, a2, 0, a2.length); 2093 keyBinding.objectToEntry(a1[0], keyEntry); 2094 return a2; 2095 } else { 2096 return null; 2097 } 2098 } else if (obj instanceof int[]) { 2099 int[] a1 = (int[]) obj; 2100 if (a1.length > 0) { 2101 int[] a2 = new int[a1.length - 1]; 2102 System.arraycopy(a1, 1, a2, 0, a2.length); 2103 keyBinding.objectToEntry(a1[0], keyEntry); 2104 return a2; 2105 } else { 2106 return null; 2107 } 2108 } else { 2109 throw new IllegalStateException (obj.getClass().getName()); 2110 } 2111 } 2112 2113 private void checkMetadata(String clsName, 2114 String [][] nameTypePairs, 2115 int priKeyIndex, 2116 String superClsName) 2117 throws DatabaseException { 2118 2119 2120 checkMetadata 2121 (catalog, model, clsName, nameTypePairs, priKeyIndex, 2122 superClsName); 2123 2124 2127 PersistCatalog storedCatalog = new PersistCatalog 2128 (null, env, STORE_PREFIX, "catalog", null, null, null, 2129 false , null ); 2130 EntityModel storedModel = storedCatalog.getResolvedModel(); 2131 2132 2133 checkMetadata 2134 (storedCatalog, storedModel, clsName, nameTypePairs, priKeyIndex, 2135 superClsName); 2136 2137 storedCatalog.close(); 2138 } 2139 2140 private void checkMetadata(PersistCatalog checkCatalog, 2141 EntityModel checkModel, 2142 String clsName, 2143 String [][] nameTypePairs, 2144 int priKeyIndex, 2145 String superClsName) 2146 throws DatabaseException { 2147 2148 ClassMetadata classMeta = checkModel.getClassMetadata(clsName); 2149 assertNotNull(clsName, classMeta); 2150 2151 PrimaryKeyMetadata priKeyMeta = classMeta.getPrimaryKey(); 2152 if (priKeyIndex >= 0) { 2153 assertNotNull(priKeyMeta); 2154 String fieldName = nameTypePairs[priKeyIndex][0]; 2155 String fieldType = nameTypePairs[priKeyIndex][1]; 2156 assertEquals(priKeyMeta.getName(), fieldName); 2157 assertEquals(priKeyMeta.getClassName(), fieldType); 2158 assertEquals(priKeyMeta.getDeclaringClassName(), clsName); 2159 assertNull(priKeyMeta.getSequenceName()); 2160 } else { 2161 assertNull(priKeyMeta); 2162 } 2163 2164 RawType type = checkCatalog.getFormat(clsName); 2165 assertNotNull(type); 2166 assertEquals(clsName, type.getClassName()); 2167 assertEquals(0, type.getVersion()); 2168 assertTrue(!type.isSimple()); 2169 assertTrue(!type.isPrimitive()); 2170 assertTrue(!type.isEnum()); 2171 assertNull(type.getEnumConstants()); 2172 assertTrue(!type.isArray()); 2173 assertEquals(0, type.getDimensions()); 2174 assertNull(type.getComponentType()); 2175 RawType superType = type.getSuperType(); 2176 if (superClsName != null) { 2177 assertNotNull(superType); 2178 assertEquals(superClsName, superType.getClassName()); 2179 } else { 2180 assertNull(superType); 2181 } 2182 2183 Map <String ,RawField> fields = type.getFields(); 2184 assertNotNull(fields); 2185 2186 int nFields = nameTypePairs.length; 2187 assertEquals(nFields, fields.size()); 2188 2189 for (String [] pair : nameTypePairs) { 2190 String fieldName = pair[0]; 2191 String fieldType = pair[1]; 2192 Class fieldCls; 2193 try { 2194 fieldCls = SimpleCatalog.classForName(fieldType); 2195 } catch (ClassNotFoundException e) { 2196 fail(e.toString()); 2197 return; 2198 } 2199 RawField field = fields.get(fieldName); 2200 assertNotNull(field); 2201 assertEquals(fieldName, field.getName()); 2202 type = field.getType(); 2203 assertNotNull(type); 2204 int dim = getArrayDimensions(fieldType); 2205 while (dim > 0) { 2206 assertEquals(dim, type.getDimensions()); 2207 assertEquals(dim, getArrayDimensions(fieldType)); 2208 assertEquals(true, type.isArray()); 2209 assertEquals(fieldType, type.getClassName()); 2210 assertEquals(0, type.getVersion()); 2211 assertTrue(!type.isSimple()); 2212 assertTrue(!type.isPrimitive()); 2213 assertTrue(!type.isEnum()); 2214 assertNull(type.getEnumConstants()); 2215 fieldType = getArrayComponent(fieldType, dim); 2216 type = type.getComponentType(); 2217 assertNotNull(fieldType, type); 2218 dim -= 1; 2219 } 2220 assertEquals(fieldType, type.getClassName()); 2221 List <String > enums = getEnumConstants(fieldType); 2222 assertEquals(isSimpleType(fieldType), type.isSimple()); 2223 assertEquals(isPrimitiveType(fieldType), type.isPrimitive()); 2224 assertNull(type.getComponentType()); 2225 assertTrue(!type.isArray()); 2226 assertEquals(0, type.getDimensions()); 2227 if (enums != null) { 2228 assertTrue(type.isEnum()); 2229 assertEquals(enums, type.getEnumConstants()); 2230 assertNull(type.getSuperType()); 2231 } else { 2232 assertTrue(!type.isEnum()); 2233 assertNull(type.getEnumConstants()); 2234 } 2235 } 2236 } 2237 2238 private List <String > getEnumConstants(String clsName) { 2239 if (isPrimitiveType(clsName)) { 2240 return null; 2241 } 2242 Class cls; 2243 try { 2244 cls = Class.forName(clsName); 2245 } catch (ClassNotFoundException e) { 2246 fail(e.toString()); 2247 return null; 2248 } 2249 if (!cls.isEnum()) { 2250 return null; 2251 } 2252 List <String > enums = new ArrayList <String >(); 2253 Object [] vals = cls.getEnumConstants(); 2254 for (Object val : vals) { 2255 enums.add(val.toString()); 2256 } 2257 return enums; 2258 } 2259 2260 private String getArrayComponent(String clsName, int dim) { 2261 clsName = clsName.substring(1); 2262 if (dim > 1) { 2263 return clsName; 2264 } 2265 if (clsName.charAt(0) == 'L' && 2266 clsName.charAt(clsName.length() - 1) == ';') { 2267 return clsName.substring(1, clsName.length() - 1); 2268 } 2269 if (clsName.length() != 1) { 2270 fail(); 2271 } 2272 switch (clsName.charAt(0)) { 2273 case 'Z': return "boolean"; 2274 case 'B': return "byte"; 2275 case 'C': return "char"; 2276 case 'D': return "double"; 2277 case 'F': return "float"; 2278 case 'I': return "int"; 2279 case 'J': return "long"; 2280 case 'S': return "short"; 2281 default: fail(); 2282 } 2283 return null; 2284 } 2285 2286 private static int getArrayDimensions(String clsName) { 2287 int i = 0; 2288 while (clsName.charAt(i) == '[') { 2289 i += 1; 2290 } 2291 return i; 2292 } 2293 2294 private static boolean isSimpleType(String clsName) { 2295 return isPrimitiveType(clsName) || 2296 clsName.equals("java.lang.Boolean") || 2297 clsName.equals("java.lang.Character") || 2298 clsName.equals("java.lang.Byte") || 2299 clsName.equals("java.lang.Short") || 2300 clsName.equals("java.lang.Integer") || 2301 clsName.equals("java.lang.Long") || 2302 clsName.equals("java.lang.Float") || 2303 clsName.equals("java.lang.Double") || 2304 clsName.equals("java.lang.String") || 2305 clsName.equals("java.math.BigInteger") || 2306 clsName.equals("java.util.Date"); 2308 } 2309 2310 private static boolean isPrimitiveType(String clsName) { 2311 return clsName.equals("boolean") || 2312 clsName.equals("char") || 2313 clsName.equals("byte") || 2314 clsName.equals("short") || 2315 clsName.equals("int") || 2316 clsName.equals("long") || 2317 clsName.equals("float") || 2318 clsName.equals("double"); 2319 } 2320 2321 interface MyEntity { 2322 Object getPriKeyObject(); 2323 void validate(Object other); 2324 } 2325 2326 private static boolean nullOrEqual(Object o1, Object o2) { 2327 return (o1 != null) ? o1.equals(o2) : (o2 == null); 2328 } 2329 2330 private static String arrayToString(Object [] array) { 2331 StringBuffer buf = new StringBuffer (); 2332 buf.append('['); 2333 for (Object o : array) { 2334 if (o instanceof Object []) { 2335 buf.append(arrayToString((Object []) o)); 2336 } else { 2337 buf.append(o); 2338 } 2339 buf.append(','); 2340 } 2341 buf.append(']'); 2342 return buf.toString(); 2343 } 2344 2345 private void setFieldToNull(Object obj, String fieldName) { 2346 try { 2347 Field field = obj.getClass().getDeclaredField(fieldName); 2348 field.setAccessible(true); 2349 field.set(obj, null); 2350 } catch (NoSuchFieldException e) { 2351 fail(e.toString()); 2352 } catch (IllegalAccessException e) { 2353 fail(e.toString()); 2354 } 2355 } 2356 2357 private void setField(Object obj, String fieldName, Object fieldValue) { 2358 try { 2359 Field field = obj.getClass().getDeclaredField(fieldName); 2360 field.setAccessible(true); 2361 field.set(obj, fieldValue); 2362 } catch (NoSuchFieldException e) { 2363 throw new IllegalStateException (e.toString()); 2364 } catch (IllegalAccessException e) { 2365 throw new IllegalStateException (e.toString()); 2366 } 2367 } 2368 2369 private Object getField(Object obj, String fieldName) { 2370 try { 2371 Field field = obj.getClass().getDeclaredField(fieldName); 2372 field.setAccessible(true); 2373 return field.get(obj); 2374 } catch (NoSuchFieldException e) { 2375 throw new IllegalStateException (e.toString()); 2376 } catch (IllegalAccessException e) { 2377 throw new IllegalStateException (e.toString()); 2378 } 2379 } 2380} 2381 | Popular Tags |