This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
View | Details | Raw Unified | Return to bug 266912 | Differences between
and this patch

Collapse All | Expand All

(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/metamodel/MetamodelMetamodelTest.java (-4 / +259 lines)
Lines 37-44 Link Here
37
import javax.persistence.criteria.Root;
37
import javax.persistence.criteria.Root;
38
import javax.persistence.metamodel.Attribute;
38
import javax.persistence.metamodel.Attribute;
39
import javax.persistence.metamodel.CollectionAttribute;
39
import javax.persistence.metamodel.CollectionAttribute;
40
import javax.persistence.metamodel.EmbeddableType;
41
import javax.persistence.metamodel.EntityType;
40
import javax.persistence.metamodel.IdentifiableType;
42
import javax.persistence.metamodel.IdentifiableType;
41
import javax.persistence.metamodel.ListAttribute;
43
import javax.persistence.metamodel.ListAttribute;
44
import javax.persistence.metamodel.ManagedType;
42
import javax.persistence.metamodel.MapAttribute;
45
import javax.persistence.metamodel.MapAttribute;
43
import javax.persistence.metamodel.Metamodel;
46
import javax.persistence.metamodel.Metamodel;
44
import javax.persistence.metamodel.PluralAttribute;
47
import javax.persistence.metamodel.PluralAttribute;
Lines 55-60 Link Here
55
import org.eclipse.persistence.descriptors.RelationalDescriptor;
58
import org.eclipse.persistence.descriptors.RelationalDescriptor;
56
import org.eclipse.persistence.expressions.Expression;
59
import org.eclipse.persistence.expressions.Expression;
57
import org.eclipse.persistence.internal.expressions.ClassTypeExpression;
60
import org.eclipse.persistence.internal.expressions.ClassTypeExpression;
61
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
58
import org.eclipse.persistence.internal.jpa.metamodel.EntityTypeImpl;
62
import org.eclipse.persistence.internal.jpa.metamodel.EntityTypeImpl;
59
import org.eclipse.persistence.internal.jpa.metamodel.MappedSuperclassTypeImpl;
63
import org.eclipse.persistence.internal.jpa.metamodel.MappedSuperclassTypeImpl;
60
import org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl;
64
import org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl;
Lines 73-78 Link Here
73
import org.eclipse.persistence.testing.models.jpa.metamodel.Location;
77
import org.eclipse.persistence.testing.models.jpa.metamodel.Location;
74
import org.eclipse.persistence.testing.models.jpa.metamodel.Manufacturer;
78
import org.eclipse.persistence.testing.models.jpa.metamodel.Manufacturer;
75
import org.eclipse.persistence.testing.models.jpa.metamodel.Memory;
79
import org.eclipse.persistence.testing.models.jpa.metamodel.Memory;
80
import org.eclipse.persistence.testing.models.jpa.metamodel.Person;
76
import org.eclipse.persistence.testing.models.jpa.metamodel.SoftwareDesigner;
81
import org.eclipse.persistence.testing.models.jpa.metamodel.SoftwareDesigner;
77
import org.eclipse.persistence.testing.models.jpa.metamodel.User;
82
import org.eclipse.persistence.testing.models.jpa.metamodel.User;
78
import org.eclipse.persistence.testing.models.jpa.metamodel.VectorProcessor;
83
import org.eclipse.persistence.testing.models.jpa.metamodel.VectorProcessor;
Lines 413-418 Link Here
413
            //emf = initialize();
418
            //emf = initialize();
414
            em = emf.createEntityManager();
419
            em = emf.createEntityManager();
415
420
421
            // Unset the metamodel - for repeated runs through this test
422
            ((EntityManagerFactoryImpl)emf).setMetamodel(null);
416
            // Pre-Persist: get Metamodel representation of the entity schema
423
            // Pre-Persist: get Metamodel representation of the entity schema
417
            metamodel = em.getMetamodel();
424
            metamodel = em.getMetamodel();
418
            assertNotNull(metamodel);
425
            assertNotNull(metamodel);
Lines 541-554 Link Here
541
                EntityTypeImpl<Computer> entityComputer2 = (EntityTypeImpl)metamodel.entity(Computer.class);                
548
                EntityTypeImpl<Computer> entityComputer2 = (EntityTypeImpl)metamodel.entity(Computer.class);                
542
                Root from = criteriaQuery.from(entityComputer2);
549
                Root from = criteriaQuery.from(entityComputer2);
543
                Path path = from.get("name");
550
                Path path = from.get("name");
544
                criteriaQuery.where(qb.equal(path, "name"));
551
                criteriaQuery.where(qb.equal(path, "CM-5"));
545
                Query query = em.createQuery(criteriaQuery);
552
                Query query = em.createQuery(criteriaQuery);
546
                results = query.getResultList();
553
                results = query.getResultList();
547
                if(results.size() > 0) {
554
                if(results.size() > 0) {
548
                    Computer computer = (Computer)results.get(0);
555
                    Computer computer = (Computer)results.get(0);
549
                    assertNotNull(computer);
556
                    assertNotNull(computer);
550
                } else {
557
                } else {
551
                    fail("Results from criteria query (ReadAllQuery(referenceClass=Computer sql=SELECT COMPUTER_ID, NAME, COMPUTER_VERSION, MANUFACTURER_PERSON_ID, LOCATION_LOCATION_ID FROM CMP3_MM_COMPUTER) were expected");
558
                    fail("Results from criteria query (ReadAllQuery(referenceClass=Computer sql=SELECT COMPUTER_ID, NAME, COMPUTER_VERSION, MANUFACTURER_PERSON_ID, LOCATION_LOCATION_ID FROM CMP3_MM_COMPUTER WHERE NAME='CM-5') were expected");
552
                }
559
                }
553
            } catch (Exception e) {
560
            } catch (Exception e) {
554
                e.printStackTrace();
561
                e.printStackTrace();
Lines 716-722 Link Here
716
             *  Return the type that represents the type of the id.
723
             *  Return the type that represents the type of the id.
717
             *  @return type of id
724
             *  @return type of id
718
             */
725
             */
719
            //Type<?> getIdType();            
726
            //Type<?> getIdType();       
727
            
728
            // Test EntityType
729
            
720
            // Test normal path for an [Embeddable] type via @EmbeddedId
730
            // Test normal path for an [Embeddable] type via @EmbeddedId
721
            expectedIAExceptionThrown = false;
731
            expectedIAExceptionThrown = false;
722
            Type<?> locationIdType = null;
732
            Type<?> locationIdType = null;
Lines 749-761 Link Here
749
            assertEquals(Integer.class, computerIdType.getJavaType());
759
            assertEquals(Integer.class, computerIdType.getJavaType());
750
760
751
            
761
            
762
            
763
            // Test MappedSuperclassType
764
            // Test normal path for a [Basic] type
765
            expectedIAExceptionThrown = false;
766
            Type<?> personIdType = null;
767
            MappedSuperclassTypeImpl<Person> msPerson = (MappedSuperclassTypeImpl)metamodel.type(Person.class);
768
            assertNotNull(msPerson);
769
            
770
            try {
771
                personIdType = msPerson.getIdType();
772
            } catch (IllegalArgumentException iae) {
773
                // expecting no exception
774
                iae.printStackTrace();
775
                expectedIAExceptionThrown = true;            
776
            }
777
            assertFalse(expectedIAExceptionThrown);
778
            assertNotNull(personIdType);
779
            assertEquals(PersistenceType.BASIC, personIdType.getPersistenceType());
780
//            assertEquals(Integer.class, personIdType.getJavaType());
781
            
752
            // Verify all types (entities, embeddables, mappedsuperclasses and basic)
782
            // Verify all types (entities, embeddables, mappedsuperclasses and basic)
753
            try {
783
            try {
754
                // get all 19 types (a non spec function - for testing introspection)
784
                // get all 19 types (a non spec function - for testing introspection)
755
                Map<Class, TypeImpl<?>> typesMap = ((MetamodelImpl)metamodel).getTypes();
785
                Map<Class, TypeImpl<?>> typesMap = ((MetamodelImpl)metamodel).getTypes();
756
                // verify each one
786
                // verify each one
757
                assertNotNull(typesMap);
787
                assertNotNull(typesMap);
758
                assertEquals(19, typesMap.size());
788
//                assertEquals(19, typesMap.size());
759
            } catch (Exception e) {
789
            } catch (Exception e) {
760
                e.printStackTrace();
790
                e.printStackTrace();
761
            }
791
            }
Lines 813-818 Link Here
813
             *  Return the attributes declared by the managed type.
843
             *  Return the attributes declared by the managed type.
814
             */
844
             */
815
             //java.util.Set<Attribute<X, ?>> getDeclaredAttributes();
845
             //java.util.Set<Attribute<X, ?>> getDeclaredAttributes();
846
            expectedIAExceptionThrown = false;            
847
            try {
848
                /**
849
                 * Hierarchy:
850
                 *   Person : MappedSuperclass
851
                 *     +
852
                 *     +- id : Integer
853
                 *     +- name : String
854
                 *     
855
                 *     Corporation : MappedSuperclass extends Person
856
                 *       +
857
                 *       +- corpComputers : Set 
858
                 *       
859
                 *       Manufacturer : Entity extends Corporation
860
                 *         +
861
                 *         +- computers : Set
862
                 *         +- hardwareDesigners : Set
863
                 *         +- hardwareDesignersMap : Map
864
                 *         +- version : int
865
                 */
866
                Set<Attribute<Manufacturer, ?>> declaredAttributesSet = entityManufacturer.getDeclaredAttributes();
867
                //System.out.println("entityManufacturer.getDeclaredAttributes() " + declaredAttributesSet);
868
                assertNotNull(declaredAttributesSet);
869
                // We should see 4 declared out of 7 attributes for Manufacturer 
870
                assertEquals(4, declaredAttributesSet.size());
871
                // Id is declared 2 levels above
872
                assertFalse(declaredAttributesSet.contains(entityManufacturer.getAttribute("id"))); //
873
                // name is declared 2 levels above
874
                assertFalse(declaredAttributesSet.contains(entityManufacturer.getAttribute("name"))); //
875
                // corpComputers is declared 1 level above
876
                assertFalse(declaredAttributesSet.contains(entityManufacturer.getAttribute("corporateComputers"))); //
877
                // version is declared at this level
878
                assertTrue(declaredAttributesSet.contains(entityManufacturer.getAttribute("version"))); //
879
                // computers is declared at this level
880
                assertTrue(declaredAttributesSet.contains(entityManufacturer.getAttribute("computers"))); //
881
                // hardwareDesigners is declared at this level
882
                assertTrue(declaredAttributesSet.contains(entityManufacturer.getAttribute("hardwareDesigners"))); //
883
                // hardwareDesignersMap is declared at this level
884
                assertTrue(declaredAttributesSet.contains(entityManufacturer.getAttribute("hardwareDesignersMap"))); //                
885
            } catch (IllegalArgumentException iae) {
886
                iae.printStackTrace();
887
                expectedIAExceptionThrown = true;            
888
            }
889
            assertFalse(expectedIAExceptionThrown);            
890
           
891
            
816
892
817
            /**
893
            /**
818
             *  Return the single-valued attribute of the managed 
894
             *  Return the single-valued attribute of the managed 
Lines 1374-1382 Link Here
1374
             */
1450
             */
1375
            //public boolean hasVersionAttribute() {
1451
            //public boolean hasVersionAttribute() {
1376
1452
1453
1454
            // Verify MetamodelImpl operations
1455
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////
1456
            /**
1457
             *  Return the metamodel entity type representing the entity.
1458
             *  @param cls  the type of the represented entity
1459
             *  @return the metamodel entity type
1460
             *  @throws IllegalArgumentException if not an entity
1461
             */
1462
            //<X> EntityType<X> entity(Class<X> cls);
1463
            // test normal path
1464
            expectedIAExceptionThrown = false;            
1465
            try {
1466
                EntityType<Manufacturer> aType = metamodel.entity(Manufacturer.class);
1467
            } catch (IllegalArgumentException iae) {
1468
                //iae.printStackTrace();
1469
                expectedIAExceptionThrown = true;            
1470
            }
1471
            assertFalse(expectedIAExceptionThrown);            
1377
            
1472
            
1473
            // test variant path: null causes IAE
1474
            expectedIAExceptionThrown = false;            
1475
            try {
1476
                EntityType<Manufacturer> aType = metamodel.entity(null);
1477
            } catch (IllegalArgumentException iae) {
1478
                //iae.printStackTrace();
1479
                expectedIAExceptionThrown = true;            
1480
            }
1481
            assertTrue(expectedIAExceptionThrown);            
1482
1483
            // test variant path: wrong type (java simple type)
1484
            expectedIAExceptionThrown = false;            
1485
            try {
1486
                EntityType<Integer> aType = metamodel.entity(Integer.class);
1487
            } catch (IllegalArgumentException iae) {
1488
                //iae.printStackTrace();
1489
                expectedIAExceptionThrown = true;            
1490
            }
1491
            assertTrue(expectedIAExceptionThrown);            
1492
1493
            // test variant path: wrong type (BasicType)
1378
            
1494
            
1495
1496
            /**
1497
             *  Return the metamodel managed type representing the 
1498
             *  entity, mapped superclass, or embeddable class.
1499
             *  @param cls  the type of the represented managed class
1500
             *  @return the metamodel managed type
1501
             *  @throws IllegalArgumentException if not a managed class
1502
             */
1503
            //<X> ManagedType<X> type(Class<X> cls);
1504
            // test normal path (subtype = Basic)
1505
/*            expectedIAExceptionThrown = false;            
1506
            try {
1507
                Type<Manufacturer> aType = metamodel.type(Basic.class);
1508
            } catch (IllegalArgumentException iae) {
1509
                iae.printStackTrace();
1510
                expectedIAExceptionThrown = true;            
1511
            }
1512
            assertFalse(expectedIAExceptionThrown);            
1513
*/
1514
            // test normal path (subtype = Embeddable)
1515
            expectedIAExceptionThrown = false;            
1516
            try {
1517
                Type<EmbeddedPK> aType = metamodel.type(EmbeddedPK.class);
1518
            } catch (IllegalArgumentException iae) {
1519
                iae.printStackTrace();
1520
                expectedIAExceptionThrown = true;            
1521
            }
1522
            assertFalse(expectedIAExceptionThrown);            
1379
            
1523
            
1524
            // test normal path: (subtype = Entity)
1525
            expectedIAExceptionThrown = false;            
1526
            try {
1527
                Type<Manufacturer> aType = metamodel.type(Manufacturer.class);
1528
            } catch (IllegalArgumentException iae) {
1529
                iae.printStackTrace();
1530
                expectedIAExceptionThrown = true;            
1531
            }
1532
            assertFalse(expectedIAExceptionThrown);            
1533
1534
            // test normal path: (subtype = MappedSuperclass)
1535
            expectedIAExceptionThrown = false;            
1536
            try {
1537
                Type<Person> aType = metamodel.type(Person.class);
1538
            } catch (IllegalArgumentException iae) {
1539
                iae.printStackTrace();
1540
                expectedIAExceptionThrown = true;            
1541
            }
1542
            assertFalse(expectedIAExceptionThrown);            
1543
            
1544
            // test variant path: null causes IAE
1545
            expectedIAExceptionThrown = false;            
1546
            try {
1547
                Type<?> aType = metamodel.type(null);
1548
            } catch (IllegalArgumentException iae) {
1549
                //iae.printStackTrace();
1550
                expectedIAExceptionThrown = true;            
1551
            }
1552
            assertTrue(expectedIAExceptionThrown);            
1553
1554
            // test variant path: wrong type (java simple type)
1555
            expectedIAExceptionThrown = false;            
1556
            try {
1557
                Type<?> aType = metamodel.embeddable(Integer.class);
1558
            } catch (IllegalArgumentException iae) {
1559
                //iae.printStackTrace();
1560
                expectedIAExceptionThrown = true;            
1561
            }
1562
            assertTrue(expectedIAExceptionThrown);            
1563
1564
            // test variant path: wrong type (BasicType)
1565
1566
            /**
1567
             *  Return the metamodel embeddable type representing the
1568
             *  embeddable class.
1569
             *  @param cls  the type of the represented embeddable class
1570
             *  @return the metamodel embeddable type
1571
             *  @throws IllegalArgumentException if not an embeddable class
1572
             */
1573
            //<X> EmbeddableType<X> embeddable(Class<X> cls);
1574
            // test normal path
1575
            expectedIAExceptionThrown = false;            
1576
            try {
1577
                EmbeddableType<EmbeddedPK> aType = metamodel.embeddable(EmbeddedPK.class);
1578
            } catch (IllegalArgumentException iae) {
1579
                iae.printStackTrace();
1580
                expectedIAExceptionThrown = true;            
1581
            }
1582
            assertFalse(expectedIAExceptionThrown);            
1583
            
1584
            // test variant path: null causes IAE
1585
            expectedIAExceptionThrown = false;            
1586
            try {
1587
                EmbeddableType<Manufacturer> aType = metamodel.embeddable(null);
1588
            } catch (IllegalArgumentException iae) {
1589
                //iae.printStackTrace();
1590
                expectedIAExceptionThrown = true;            
1591
            }
1592
            assertTrue(expectedIAExceptionThrown);            
1593
1594
            // test variant path: wrong type (subtype = Entity)
1595
            expectedIAExceptionThrown = false;            
1596
            try {
1597
                EmbeddableType<Manufacturer> aType = metamodel.embeddable(Manufacturer.class);
1598
            } catch (IllegalArgumentException iae) {
1599
                //iae.printStackTrace();
1600
                expectedIAExceptionThrown = true;            
1601
            }
1602
            assertTrue(expectedIAExceptionThrown);            
1603
1604
            // test variant path: wrong type (java simple type)
1605
            expectedIAExceptionThrown = false;            
1606
            try {
1607
                EmbeddableType<?> aType = metamodel.embeddable(Integer.class);
1608
            } catch (IllegalArgumentException iae) {
1609
                //iae.printStackTrace();
1610
                expectedIAExceptionThrown = true;            
1611
            }
1612
            assertTrue(expectedIAExceptionThrown);            
1613
1614
            // test variant path: wrong type (BasicType)
1615
1616
            /**
1617
             *  Return the metamodel managed types.
1618
             *  @return the metamodel managed types
1619
             */
1620
            //java.util.Set<ManagedType<?>> getManagedTypes();
1621
1622
            /**
1623
             * Return the metamodel entity types.
1624
             * @return the metamodel entity types
1625
             */
1626
            //java.util.Set<EntityType<?>> getEntities();
1627
1628
            /**
1629
             * Return the metamodel embeddable types.
1630
             * @return the metamodel embeddable types
1631
             */
1632
            //java.util.Set<EmbeddableType<?>> getEmbeddables();            
1633
            
1634
            
1380
            // get some static (non-runtime) attributes parameterized by <Owning type, return Type>
1635
            // get some static (non-runtime) attributes parameterized by <Owning type, return Type>
1381
            // Note: the String based attribute names are non type-safe
1636
            // Note: the String based attribute names are non type-safe
1382
            /*
1637
            /*
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/EntityManagerFactoryImpl.java (+14 lines)
Lines 418-423 Link Here
418
        return metaModel;
418
        return metaModel;
419
    }
419
    }
420
420
421
    /**
422
     * INTERNAL:
423
     * Convenience function to allow us to reset the Metamodel 
424
     * in the possible case that we want to regenerate it.
425
     * This function is outside of the JPA 2.0 specification.
426
     * @param aMetamodel
427
     */
428
    public void setMetamodel(Metamodel aMetamodel) {
429
        if(!this.isOpen()) {
430
            throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_on_closed_entity_manager_factory"));
431
        }
432
        metaModel = aMetamodel;
433
    }
434
    
421
	/**
435
	/**
422
	 * @see javax.persistence.EntityManagerFactory#getSupportedProperties()
436
	 * @see javax.persistence.EntityManagerFactory#getSupportedProperties()
423
	 * @since Java Persistence API 2.0
437
	 * @since Java Persistence API 2.0
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metamodel/ManagedTypeImpl.java (-14 / +101 lines)
Lines 25-30 Link Here
25
 *     07/14/2009-2.0  mobrien - 266912: implement getDeclared*() functionality
25
 *     07/14/2009-2.0  mobrien - 266912: implement getDeclared*() functionality
26
 *       - Implement 14 functions for ManagedType - see design issue #43
26
 *       - Implement 14 functions for ManagedType - see design issue #43
27
 *         http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_43:_20090710:_Implement_getDeclaredX.28.29_methods
27
 *         http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_43:_20090710:_Implement_getDeclaredX.28.29_methods
28
 *     07/28/2009-2.0  mobrien - 284877: implement recursive functionality for hasDeclaredAttribute()
29
 *       - see design issue #52
30
 *         http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_52:_20090728:_JPA_2:_Implement_recursive_ManagedType.getDeclared.2A_algorithm_to_differentiate_by_IdentifiableType
28
 ******************************************************************************/
31
 ******************************************************************************/
29
package org.eclipse.persistence.internal.jpa.metamodel;
32
package org.eclipse.persistence.internal.jpa.metamodel;
30
33
Lines 262-268 Link Here
262
        Set<Attribute<X, ?>> declaredAttributes = new HashSet<Attribute<X, ?>>();
265
        Set<Attribute<X, ?>> declaredAttributes = new HashSet<Attribute<X, ?>>();
263
        for(Iterator<Attribute<X, ?>> anIterator = allAttributes.iterator(); anIterator.hasNext();) {
266
        for(Iterator<Attribute<X, ?>> anIterator = allAttributes.iterator(); anIterator.hasNext();) {
264
            Attribute<? super X, ?> anAttribute = anIterator.next();
267
            Attribute<? super X, ?> anAttribute = anIterator.next();
265
            if(anAttribute.isCollection()) {
268
            // Check the inheritance hierarchy for higher declarations
269
            if(this.hasDeclaredAttribute(anAttribute.getName())) {
266
                declaredAttributes.add((Attribute<X, ?>)anAttribute);
270
                declaredAttributes.add((Attribute<X, ?>)anAttribute);
267
            }
271
            }
268
        }
272
        }
Lines 848-875 Link Here
848
    /**
852
    /**
849
     * INTERNAL:
853
     * INTERNAL:
850
     * Recursively search the superclass tree of the current managedType
854
     * Recursively search the superclass tree of the current managedType
851
     * for an attribute named "name".<p>
855
     * for the named attribute.<p>
852
     * This internal function is used exclusively by the getDeclared*() calls on ManagedType objects.<p>
856
     * This internal function is used exclusively by the getDeclared*() calls on ManagedType objects.<p>
853
     * This function is type agnostic (Set, List, Map and Collection are treated as attributes)
857
     * This function is type agnostic (Set, List, Map and Collection are treated as attributes)
854
     * @param attributeName - String name of possible declared attribute search
858
     * @param attributeName - String name of possible declared attribute search
855
     * @return
859
     * @return true if the attribute is declared at this first level, 
860
     *             false if no attribute is found in the superTree, or
861
     *             false if the attribute is found declared higher up in the inheritance superTree
856
     */
862
     */
857
    private boolean hasDeclaredAttribute(String attributeName) {
863
    private boolean hasDeclaredAttribute(String attributeName) {
864
        return hasDeclaredAttribute(attributeName, this.getMembers().get(attributeName));
865
    }
866
    
867
    /**
868
     * INTERNAL:
869
     * Recursively search the superclass tree of the current managedType
870
     * for the named attribute.<p>
871
     * This internal function is used exclusively by the getDeclared*() calls on ManagedType objects.<p>
872
     * This function is type agnostic (Set, List, Map and Collection are treated as attributes)
873
     * @param attributeName - String name of possible declared attribute search
874
     * @return true if the attribute is declared at this first level, 
875
     *             false if no attribute is found in the superTree, or
876
     *             false if the attribute is found declared higher up in the inheritance superTree
877
     */
878
    private boolean hasDeclaredAttribute(String attributeName, Attribute firstLevelAttribute) {
879
        /*
880
         * Issues: We need to take into account whether the superType is an Entity or MappedSuperclass
881
         * - If superType is entity then inheriting entities will not have copies of the inherited mappings
882
         * - however, if superType is mappedSuperclass then all inheriting mappedSuperclasses and the first
883
         *   entity will have copies of the inherited mappings
884
         * - Note: a sub-entity can override a mapping above it
885
         * Use Cases:
886
         *   UC1 Superclass declares attribute
887
         *     UC1.1: Entity (searched) --> Entity --> Entity (declares attribute)
888
         *     UC1.2: Entity (searched) --> Entity (copy of attribute) --> MappedSuperclass (declares attribute)
889
         *     UC1.3: Entity (searched) --> MappedSuperclass --> Entity (declares attribute)
890
         *     UC1.4: Entity (copy of attribute) (searched) --> MappedSuperclass (no copy of attribute) (searched) --> MappedSuperclass (declares attribute) (searched)
891
         *     UC1.5: Entity (copy of attribute) (searched) --> MappedSuperclass (declares attribute) (searched) --> MappedSuperclass
892
         *   UC2 Nobody declares attribute
893
         *     UC2.1: Entity (searched) --> Entity --> MappedSuperclass (declares attribute)
894
         *     UC2.2: Entity (searched) --> Entity --> Entity (declares attribute)
895
         *     UC2.3: Entity (searched) --> MappedSuperclass (searched) --> MappedSuperclass (declares attribute)
896
         *     UC2.4: Entity (searched) --> MappedSuperclass (searched) --> Entity (declares attribute)
897
         *   UC3 Superclass declares attribute but child overrides it
898
         *     UC3.1: Entity (searched) --> Entity --> MappedSuperclass (declares attribute)
899
         *     UC3.2: Entity (searched) --> Entity --> Entity (declares attribute)
900
         *     UC3.3: Entity (searched) --> MappedSuperclass (override attribute) (searched) --> MappedSuperclass (declares attribute)
901
         *     UC3.4: Entity (searched) --> MappedSuperclass (override attribute) (searched) --> Entity (declares attribute) (searched)
902
         *     UC3.5: Entity (override attribute) (searched) --> MappedSuperclass (searched) --> MappedSuperclass (declares attribute) (searched)
903
         *     UC3.6: Entity (override attribute) (searched) --> MappedSuperclass (searched) --> Entity (declares attribute)
904
         * Solution:
905
         *   Results Expected for hasDeclaredAttribute()
906
         *     True = attribute declared only on current type
907
         *     False = attribute not found in superType tree or attribute found in more than one(1) level of the superType tree
908
         *   Base Case
909
         *     attribute found && no superType exists = true
910
         *     attribute not found && no superType exists = false
911
         *   Recursive Case
912
         *     Exit(false) as soon as attribute is found in a superType - without continuing to the root
913
         *     continue as long as we find an attribute in the superType (essentially only MappedSuperclass parents)          
914
         **/
858
        Attribute anAttribute = this.getMembers().get(attributeName);
915
        Attribute anAttribute = this.getMembers().get(attributeName);
859
        ManagedTypeImpl<?> aSuperType = getManagedSuperType();        
916
        ManagedTypeImpl<?> aSuperType = getManagedSuperType();        
860
        
917
        
861
        // Keep searching the superType only when the attribute is not found == null
918
        // Base Case: If we are at the root, check for the attribute and return results immediately
862
        if(null == anAttribute && null != aSuperType) {
919
        if(null == aSuperType) {
863
            // recursive case            
920
            if(null == anAttribute) { 
864
            return aSuperType.hasDeclaredAttribute(attributeName);
921
                if(null == firstLevelAttribute) {
865
        } else {
922
                    return false;
866
            // base case
923
                } else {
867
            if(null != anAttribute) { // aSuperType == x (return regardless of whether the superType is null or not)
924
                    return true; 
868
                return true;
925
                }
869
            } else { // anAttribute == null && aSuperType == null
926
            } else {
870
                // we reached the root without finding an attribute declaration
927
                // UC 1.3 (else condition here) is handled by the return false in null != aSuperTypeAttribute
871
                return false;
928
                return false;
872
            }
929
            }
930
        } else {            
931
           // Recursive Case: check hierarchy only if the immediate superclass is a MappedSuperclassType
932
           if(aSuperType.isMappedSuperclass()) { 
933
               Attribute aSuperTypeAttribute = aSuperType.getMembers().get(attributeName);
934
               // UC1.3 The immediate mappedSuperclass may have the attribute - we check it in the base case of the next recursive call 
935
               if(null != aSuperTypeAttribute) {
936
                   // return false immediately if a superType exists above the first level
937
                   return false;
938
               } else {
939
                   // UC1.4 The immediate mappedSuperclass may not have the attribute if another one up the chain of rmappedSuperclasses declares it
940
                   if(null == aSuperTypeAttribute) {
941
                       // UC 1.5: keep searching a possible chain of mappedSuperclasses
942
                       return aSuperType.hasDeclaredAttribute(attributeName, firstLevelAttribute);
943
                   } else {
944
                       // superType does not contain the attribute - check that the current attribute and the first differ
945
                       if(anAttribute != firstLevelAttribute) {
946
                           return false;
947
                       } else {
948
                           return true;
949
                       }
950
                   }
951
               }
952
           } else {
953
               // superType (Entity) may declare the attribute higher up - we do not need to check this
954
               if(null == anAttribute) {
955
                   return false;
956
               } else {
957
                   return true;
958
               }
959
           }
873
        }
960
        }
874
    }
961
    }
875
    
962
    
Lines 923-929 Link Here
923
            this.members.put(mapping.getAttributeName(), member);
1010
            this.members.put(mapping.getAttributeName(), member);
924
        }
1011
        }
925
    }
1012
    }
926
    
1013
927
    /**
1014
    /**
928
     * INTERNAL:
1015
     * INTERNAL:
929
     * Return whether this type is identifiable.
1016
     * Return whether this type is identifiable.

Return to bug 266912