Repository: olingo-odata2 Updated Branches: refs/heads/master e6cdbf1f7 -> 8b40fff59
[OLINGO-1020] Fixed 0..1 multiplicity for JPA-ext Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/8b40fff5 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/8b40fff5 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/8b40fff5 Branch: refs/heads/master Commit: 8b40fff59763818af86a249828784927b8ff8cd2 Parents: e6cdbf1 Author: mibo <[email protected]> Authored: Wed Sep 7 23:51:04 2016 +0200 Committer: mibo <[email protected]> Committed: Wed Sep 7 23:51:52 2016 +0200 ---------------------------------------------------------------------- .../core/access/model/JPAEdmNameBuilder.java | 3 +- .../core/model/JPAEdmAssociationEnd.java | 83 ++++++++++--- .../core/model/JPAEdmAssociationEndTest.java | 121 +++++++++++++------ .../core/model/JPAEdmPropertyTest.java | 8 +- 4 files changed, 157 insertions(+), 58 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8b40fff5/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPAEdmNameBuilder.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPAEdmNameBuilder.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPAEdmNameBuilder.java index a5984f1..bde7c2f 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPAEdmNameBuilder.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/access/model/JPAEdmNameBuilder.java @@ -510,7 +510,8 @@ public class JPAEdmNameBuilder { navProp.setFromRole(association.getEnd2().getRole()); } } else { - if (association.getEnd2().getMultiplicity().equals(EdmMultiplicity.ONE)) { + if (association.getEnd2().getMultiplicity().equals(EdmMultiplicity.ONE) + || association.getEnd2().getMultiplicity().equals(EdmMultiplicity.ZERO_TO_ONE)) { navProp.setToRole(association.getEnd2().getRole()); navProp.setFromRole(association.getEnd1().getRole()); } else { http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8b40fff5/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationEnd.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationEnd.java b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationEnd.java index 87d409c..98d3745 100644 --- a/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationEnd.java +++ b/odata2-jpa-processor/jpa-core/src/main/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationEnd.java @@ -18,16 +18,8 @@ ******************************************************************************/ package org.apache.olingo.odata2.jpa.processor.core.model; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Array; -import java.util.List; - -import javax.persistence.ManyToMany; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.metamodel.Attribute.PersistentAttributeType; - import org.apache.olingo.odata2.api.edm.EdmMultiplicity; +import org.apache.olingo.odata2.api.edm.FullQualifiedName; import org.apache.olingo.odata2.api.edm.provider.AssociationEnd; import org.apache.olingo.odata2.jpa.processor.api.access.JPAEdmBuilder; import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException; @@ -36,6 +28,15 @@ import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmEntityTypeView; import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmPropertyView; import org.apache.olingo.odata2.jpa.processor.core.access.model.JPAEdmNameBuilder; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.metamodel.Attribute.PersistentAttributeType; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Array; +import java.util.List; + public class JPAEdmAssociationEnd extends JPAEdmBaseViewImpl implements JPAEdmAssociationEndView { private JPAEdmEntityTypeView entityTypeView = null; @@ -130,6 +131,12 @@ public class JPAEdmAssociationEnd extends JPAEdmBaseViewImpl implements JPAEdmAs case MANY_TO_ONE: currentAssociationEnd1.setMultiplicity(EdmMultiplicity.MANY); currentAssociationEnd2.setMultiplicity(EdmMultiplicity.ONE); + if (annotatedElement != null) { + ManyToOne reln = annotatedElement.getAnnotation(ManyToOne.class); + if (reln != null && reln.optional()) { + currentAssociationEnd2.setMultiplicity(EdmMultiplicity.ZERO_TO_ONE); + } + } break; case ONE_TO_ONE: currentAssociationEnd1.setMultiplicity(EdmMultiplicity.ONE); @@ -138,6 +145,9 @@ public class JPAEdmAssociationEnd extends JPAEdmBaseViewImpl implements JPAEdmAs OneToOne reln = annotatedElement.getAnnotation(OneToOne.class); if (reln != null) { mappedBy = reln.mappedBy(); + if(reln.optional()) { + currentAssociationEnd2.setMultiplicity(EdmMultiplicity.ZERO_TO_ONE); + } } } break; @@ -149,17 +159,56 @@ public class JPAEdmAssociationEnd extends JPAEdmBaseViewImpl implements JPAEdmAs @Override public boolean compare(final AssociationEnd end1, final AssociationEnd end2) { - if ((end1.getType().equals(currentAssociationEnd1.getType()) - && end2.getType().equals(currentAssociationEnd2.getType()) - && end1.getMultiplicity().equals(currentAssociationEnd1.getMultiplicity()) && end2.getMultiplicity().equals( - currentAssociationEnd2.getMultiplicity())) - || (end1.getType().equals(currentAssociationEnd2.getType()) - && end2.getType().equals(currentAssociationEnd1.getType()) - && end1.getMultiplicity().equals(currentAssociationEnd2.getMultiplicity()) && end2.getMultiplicity() - .equals(currentAssociationEnd1.getMultiplicity()))) { + FullQualifiedName end1Type = end1.getType(); + FullQualifiedName currentAssociationEnd1Type = currentAssociationEnd1.getType(); + FullQualifiedName end2Type = end2.getType(); + FullQualifiedName currentAssociationEnd2Type = currentAssociationEnd2.getType(); + + boolean end1eqCurEnd1 = end1.getMultiplicity().equals(currentAssociationEnd1.getMultiplicity()); + boolean end2eqCurEnd2 = end2.getMultiplicity().equals(currentAssociationEnd2.getMultiplicity()); + if(end1Type.equals(currentAssociationEnd1Type) && end2Type.equals(currentAssociationEnd2Type) + && end1eqCurEnd1 && end2eqCurEnd2) { return true; } + boolean end1EqCurEnd2 = end1.getMultiplicity().equals(currentAssociationEnd2.getMultiplicity()); + boolean end2EqCurEnd1 = end2.getMultiplicity().equals(currentAssociationEnd1.getMultiplicity()); + if(end1Type.equals(currentAssociationEnd2Type) && end2Type.equals(currentAssociationEnd1Type) + && end1EqCurEnd2 && end2EqCurEnd1) { + return true; + } + + boolean end1IsZeroToOne = end1.getMultiplicity() == EdmMultiplicity.ZERO_TO_ONE; + boolean end1IsOne = end1.getMultiplicity() == EdmMultiplicity.ONE; + boolean end2IsZeroToOne = end2.getMultiplicity() == EdmMultiplicity.ZERO_TO_ONE; + boolean end2IsOne = end2.getMultiplicity() == EdmMultiplicity.ONE; + + if (end1Type.equals(currentAssociationEnd1Type) && end2Type.equals(currentAssociationEnd2Type)) { + if ((end1IsZeroToOne && currentAssociationEnd1.getMultiplicity() == EdmMultiplicity.ONE + || end1IsOne && currentAssociationEnd1.getMultiplicity() == EdmMultiplicity.ZERO_TO_ONE) + && end2eqCurEnd2) { + return true; + } + if ((end2IsZeroToOne && currentAssociationEnd2.getMultiplicity() == EdmMultiplicity.ONE + || end2IsOne && currentAssociationEnd2.getMultiplicity() == EdmMultiplicity.ZERO_TO_ONE) + && end1eqCurEnd1) { + return true; + } + } + + if (end2Type.equals(currentAssociationEnd1Type) && end1Type.equals(currentAssociationEnd2Type)) { + if ((end1IsZeroToOne && currentAssociationEnd2.getMultiplicity() == EdmMultiplicity.ONE + || end1IsOne && currentAssociationEnd2.getMultiplicity() == EdmMultiplicity.ZERO_TO_ONE) + && end2EqCurEnd1) { + return true; + } + if ((end2IsZeroToOne && currentAssociationEnd1.getMultiplicity() == EdmMultiplicity.ONE + || end2IsOne && currentAssociationEnd1.getMultiplicity() == EdmMultiplicity.ZERO_TO_ONE) + && end1EqCurEnd2) { + return true; + } + } + return false; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8b40fff5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationEndTest.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationEndTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationEndTest.java index a066972..5e5e28a 100644 --- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationEndTest.java +++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmAssociationEndTest.java @@ -46,15 +46,12 @@ public class JPAEdmAssociationEndTest extends JPAEdmTestModelView { private final static int VARIANT2 = 2; private final static int VARIANT3 = 3; - private static int variant; - private static final String PUNIT_NAME = "salesorderprocessing"; private static JPAEdmAssociationEnd objJPAEdmAssociationEnd = null; - private static JPAEdmAssociationEndTest objJPAEdmAssociationEndTest = null; @BeforeClass public static void setup() { - objJPAEdmAssociationEndTest = new JPAEdmAssociationEndTest(); + InnerMock objJPAEdmAssociationEndTest = new InnerMock(Attribute.PersistentAttributeType.MANY_TO_MANY); objJPAEdmAssociationEnd = new JPAEdmAssociationEnd(objJPAEdmAssociationEndTest, objJPAEdmAssociationEndTest); try { objJPAEdmAssociationEnd.getBuilder().build(); @@ -104,7 +101,48 @@ public class JPAEdmAssociationEndTest extends JPAEdmTestModelView { assertEquals(new FullQualifiedName("salesorderprocessing", "SOID"), objJPAEdmAssociationEnd.getEdmAssociationEnd1() .getType()); assertTrue(objJPAEdmAssociationEnd.isConsistent()); + } + + @Test + public void testBuildAssociationEndManyToOne() throws Exception { + InnerMock mockFirst = new InnerMock(Attribute.PersistentAttributeType.ONE_TO_MANY); + InnerMock mockSecond = new InnerMock(Attribute.PersistentAttributeType.MANY_TO_ONE); + JPAEdmAssociationEnd associationEnd = new JPAEdmAssociationEnd(mockFirst, mockSecond); + associationEnd.getBuilder().build(); + assertEquals(EdmMultiplicity.MANY, associationEnd.getEdmAssociationEnd1().getMultiplicity()); + assertEquals(EdmMultiplicity.ONE, associationEnd.getEdmAssociationEnd2().getMultiplicity()); + assertEquals("SOID", associationEnd.getEdmAssociationEnd1().getType().getName()); + assertEquals(new FullQualifiedName("salesorderprocessing", "SOID"), associationEnd.getEdmAssociationEnd1() + .getType()); + assertTrue(associationEnd.isConsistent()); + } + + @Test + public void testBuildAssociationEndOneToMany() throws Exception { + InnerMock mockFirst = new InnerMock(Attribute.PersistentAttributeType.MANY_TO_ONE); + InnerMock mockSecond = new InnerMock(Attribute.PersistentAttributeType.ONE_TO_MANY); + JPAEdmAssociationEnd associationEnd = new JPAEdmAssociationEnd(mockFirst, mockSecond); + associationEnd.getBuilder().build(); + assertEquals(EdmMultiplicity.ONE, associationEnd.getEdmAssociationEnd1().getMultiplicity()); + assertEquals(EdmMultiplicity.MANY, associationEnd.getEdmAssociationEnd2().getMultiplicity()); + assertEquals("SOID", associationEnd.getEdmAssociationEnd1().getType().getName()); + assertEquals(new FullQualifiedName("salesorderprocessing", "SOID"), associationEnd.getEdmAssociationEnd1() + .getType()); + assertTrue(associationEnd.isConsistent()); + } + @Test + public void testBuildAssociationEndOneToOne() throws Exception { + InnerMock mockFirst = new InnerMock(Attribute.PersistentAttributeType.ONE_TO_ONE); + InnerMock mockSecond = new InnerMock(Attribute.PersistentAttributeType.ONE_TO_ONE); + JPAEdmAssociationEnd associationEnd = new JPAEdmAssociationEnd(mockFirst, mockSecond); + associationEnd.getBuilder().build(); + assertEquals(EdmMultiplicity.ONE, associationEnd.getEdmAssociationEnd1().getMultiplicity()); + assertEquals(EdmMultiplicity.ONE, associationEnd.getEdmAssociationEnd2().getMultiplicity()); + assertEquals("SOID", associationEnd.getEdmAssociationEnd1().getType().getName()); + assertEquals(new FullQualifiedName("salesorderprocessing", "SOID"), associationEnd.getEdmAssociationEnd1() + .getType()); + assertTrue(associationEnd.isConsistent()); } private AssociationEnd getAssociationEnd(final String typeName, final int variant) { @@ -127,51 +165,56 @@ public class JPAEdmAssociationEndTest extends JPAEdmTestModelView { return fullQualifiedName; } - private Attribute<?, ?> getJPAAttributeLocal() { - AttributeMock<Object, String> attr = new AttributeMock<Object, String>(); - return attr; - } - @Override - public Attribute<?, ?> getJPAAttribute() { - return getJPAAttributeLocal(); - } + private static class InnerMock extends JPAEdmTestModelView { - @Override - public String getpUnitName() { - return PUNIT_NAME; - } + private final AttributeMock<Object, String> mock; - @Override - public EntityType getEdmEntityType() { - EntityType entityType = new EntityType(); - entityType.setName(SimpleTypeA.NAME); - return entityType; - } - - // The inner class which gives us an replica of the jpa attribute - @SuppressWarnings("hiding") - public class AttributeMock<Object, String> extends JPAAttributeMock<Object, String> { + public InnerMock(Attribute.PersistentAttributeType variant) { + this.mock = new AttributeMock<Object, String>(variant); + } - @SuppressWarnings("unchecked") @Override - public Class<String> getJavaType() { - return (Class<String>) SimpleType.SimpleTypeA.clazz; + public Attribute<?, ?> getJPAAttribute() { + return getJPAAttributeLocal(); } @Override - public PersistentAttributeType getPersistentAttributeType() { - if (variant == VARIANT1) { - return PersistentAttributeType.ONE_TO_MANY; - } else if (variant == VARIANT2) { - return PersistentAttributeType.ONE_TO_ONE; - } else if (variant == VARIANT3) { - return PersistentAttributeType.MANY_TO_ONE; - } else { - return PersistentAttributeType.MANY_TO_MANY; - } + public String getpUnitName() { + return PUNIT_NAME; + } + @Override + public EntityType getEdmEntityType() { + EntityType entityType = new EntityType(); + entityType.setName(SimpleTypeA.NAME); + return entityType; + } + private Attribute<?, ?> getJPAAttributeLocal() { + return mock; } + } + // The inner class which gives us an replica of the jpa attribute + @SuppressWarnings("hiding") + private static class AttributeMock<Object, String> extends JPAAttributeMock<Object, String> { + + final private PersistentAttributeType variant; + + public AttributeMock(PersistentAttributeType variant) { + this.variant = variant; + } + + @SuppressWarnings("unchecked") + @Override + public Class<String> getJavaType() { + return (Class<String>) SimpleType.SimpleTypeA.clazz; + } + + @Override + public PersistentAttributeType getPersistentAttributeType() { + return variant; + } + } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8b40fff5/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmPropertyTest.java ---------------------------------------------------------------------- diff --git a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmPropertyTest.java b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmPropertyTest.java index 965ca70..73a6345 100644 --- a/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmPropertyTest.java +++ b/odata2-jpa-processor/jpa-core/src/test/java/org/apache/olingo/odata2/jpa/processor/core/model/JPAEdmPropertyTest.java @@ -31,6 +31,7 @@ import java.util.Set; import javax.persistence.Column; import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import javax.persistence.metamodel.Attribute; import javax.persistence.metamodel.Attribute.PersistentAttributeType; import javax.persistence.metamodel.EmbeddableType; @@ -563,7 +564,12 @@ public class JPAEdmPropertyTest extends JPAEdmTestModelView { @Override public <T extends Annotation> T getAnnotation(final Class<T> annotationClass) { - if (annotationClass.equals(JoinColumn.class)) { + if(annotationClass.equals(ManyToOne.class)) { + ManyToOne manyToOne = EasyMock.createMock(ManyToOne.class); + EasyMock.expect(manyToOne.optional()).andReturn(true).anyTimes(); + return (T) manyToOne; + + } else if (annotationClass.equals(JoinColumn.class)) { JoinColumn joinColumn = EasyMock.createMock(JoinColumn.class); EasyMock.expect(joinColumn.insertable()).andReturn(true).anyTimes();
