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();

Reply via email to