[OLINGO-62] Referntial Constraint support at edm

This commit is contained in:
Christian Amend 2014-02-07 16:14:03 +01:00
parent b14e278ab4
commit 3e0798675a
29 changed files with 125 additions and 29 deletions

View File

@ -33,7 +33,7 @@ public class EdmException extends RuntimeException {
super(msg);
}
public EdmException(String string, Exception e) {
public EdmException(final String string, final Exception e) {
super(string, e);
}

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm;
/**
* EdmMappable can be applied to CSDL elements to associate additional information.
*/

View File

@ -29,4 +29,11 @@ public interface EdmNavigationProperty extends EdmElement {
*/
Boolean isNullable();
/**
* @return the partner navigation property
*/
EdmNavigationProperty getPartner();
String getReferencingPropertyName(String referencedPropertyName);
}

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm;
/**
* A CSDL parameter element
*/

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm;
/**
* A CSDL Property element
* <p>EdmProperty defines a simple type or a complex type.

View File

@ -21,7 +21,6 @@ package org.apache.olingo.odata4.commons.api.edm;
import java.io.InputStream;
import java.util.List;
/**
* This interface gives access to the metadata of a service,
* the calculated Data Service Version and an info list of all entity sets, singletons, and function imports

View File

@ -51,7 +51,7 @@ public interface EdmStructuralType extends EdmType {
* @return {@link EdmStructuralType}
*/
EdmStructuralType getBaseType();
/**
* Checks if this type is convertable to parameter {@link targetType}
*

View File

@ -36,6 +36,4 @@ public interface EdmType extends EdmNamed {
*/
EdmTypeKind getKind();
}

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm.provider;
public class ActionImport extends OperationImport {
private FullQualifiedName action;

View File

@ -20,7 +20,6 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import java.util.List;
public class Annotation {
private FullQualifiedName term;
// Target should be a target path

View File

@ -20,7 +20,6 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import java.util.List;
public abstract class BindingTarget {
protected String name;

View File

@ -20,7 +20,6 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import java.util.List;
public class ComplexType extends StructuralType {
@Override

View File

@ -20,7 +20,6 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import java.util.List;
public class EntityContainer {
private String name;

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm.provider;
public class EntityContainerInfo {
private FullQualifiedName containerName;
private FullQualifiedName extendsContainer;

View File

@ -20,7 +20,6 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import java.util.List;
public class EntitySet extends BindingTarget {
private boolean includeInServiceDocument;

View File

@ -20,7 +20,6 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import java.util.List;
public class EntityType extends StructuralType {
private List<PropertyRef> key;

View File

@ -20,13 +20,14 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import org.apache.olingo.odata4.commons.api.edm.EdmMember;
public class EnumMember implements EdmMember{
public class EnumMember implements EdmMember {
private String name;
private String value;
// Annotations?
@Override
public String getName() {
return name;
}
@ -36,6 +37,7 @@ public class EnumMember implements EdmMember{
return this;
}
@Override
public String getValue() {
return value;
}

View File

@ -20,7 +20,6 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import java.util.List;
public class EnumType {
private String name;

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm.provider;
public class FunctionImport extends OperationImport {
private FullQualifiedName function;

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm.provider;
public class Parameter {
private String name;

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm.provider;
public class Property {
private String name;
@ -26,7 +25,7 @@ public class Property {
private FullQualifiedName type;
private boolean collection;
//TODO: Mimetype and mapping what here
// TODO: Mimetype and mapping what here
private String mimeType;
private Mapping mapping;

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm.provider;
public class ReturnType {
private FullQualifiedName type;

View File

@ -20,7 +20,6 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import java.util.List;
public class Singleton extends BindingTarget {
@Override

View File

@ -20,7 +20,6 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import java.util.List;
public abstract class StructuralType {
protected String name;

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm.provider;
public class Target {
private String targetName;

View File

@ -20,12 +20,11 @@ package org.apache.olingo.odata4.commons.api.edm.provider;
import java.util.List;
public class Term {
private String name;
private FullQualifiedName type;
private FullQualifiedName baseTerm;
//TODO: AppliesTo is a list of csdl elements => should we put this list inside an enum?
// TODO: AppliesTo is a list of csdl elements => should we put this list inside an enum?
private String appliesTo;
private boolean isCollection;

View File

@ -18,7 +18,6 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.api.edm.provider;
public class TypeDefinition {
private String name;

View File

@ -18,16 +18,22 @@
******************************************************************************/
package org.apache.olingo.odata4.commons.core.edm.provider;
import java.util.List;
import org.apache.olingo.odata4.commons.api.edm.EdmElement;
import org.apache.olingo.odata4.commons.api.edm.EdmEntityType;
import org.apache.olingo.odata4.commons.api.edm.EdmException;
import org.apache.olingo.odata4.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.odata4.commons.api.edm.EdmStructuralType;
import org.apache.olingo.odata4.commons.api.edm.EdmType;
import org.apache.olingo.odata4.commons.api.edm.provider.NavigationProperty;
import org.apache.olingo.odata4.commons.api.edm.provider.ReferentialConstraint;
public class EdmNavigationPropertyImpl extends EdmElementImpl implements EdmNavigationProperty {
private final NavigationProperty navigationProperty;
private EdmEntityType typeImpl;
private EdmNavigationProperty partnerNavigationProperty;
public EdmNavigationPropertyImpl(final EdmProviderImpl edm, final NavigationProperty navigationProperty) {
super(edm, navigationProperty.getName());
@ -55,4 +61,38 @@ public class EdmNavigationPropertyImpl extends EdmElementImpl implements EdmNavi
return navigationProperty.getNullable();
}
@Override
public EdmNavigationProperty getPartner() {
if (partnerNavigationProperty == null) {
String partner = navigationProperty.getPartner();
if (partner != null) {
EdmStructuralType type = (EdmStructuralType) getType();
EdmElement property = null;
String[] split = partner.split("/");
for (String element : split) {
property = type.getProperty(element);
if (property == null) {
throw new EdmException("Cannot find property with name: " + element + " at type " + type.getName());
}
type = (EdmStructuralType) property.getType();
}
partnerNavigationProperty = (EdmNavigationProperty) property;
}
}
return partnerNavigationProperty;
}
@Override
public String getReferencingPropertyName(final String referencedPropertyName) {
List<ReferentialConstraint> referentialConstraints = navigationProperty.getReferentialConstraints();
if (referentialConstraints != null) {
for (ReferentialConstraint constraint : referentialConstraints) {
if (constraint.getReferencedProperty().equals(referencedPropertyName)) {
return constraint.getProperty();
}
}
}
return null;
}
}

View File

@ -20,11 +20,15 @@ package org.apache.olingo.odata4.commons.core.edm.provider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.olingo.odata4.commons.api.edm.EdmException;
import org.apache.olingo.odata4.commons.api.edm.EdmNavigationProperty;
@ -35,6 +39,7 @@ import org.apache.olingo.odata4.commons.api.edm.provider.EntityType;
import org.apache.olingo.odata4.commons.api.edm.provider.FullQualifiedName;
import org.apache.olingo.odata4.commons.api.edm.provider.NavigationProperty;
import org.apache.olingo.odata4.commons.api.edm.provider.PropertyRef;
import org.apache.olingo.odata4.commons.api.edm.provider.ReferentialConstraint;
import org.junit.Test;
public class EdmNavigationPropertyImplTest {
@ -57,12 +62,78 @@ public class EdmNavigationPropertyImplTest {
assertEquals(EdmTypeKind.ENTITY, type.getKind());
assertEquals("ns", type.getNamespace());
assertEquals("entity", type.getName());
assertNull(property.getReferencingPropertyName("referencedPropertyName"));
assertNull(property.getPartner());
// Test caching
EdmType cachedType = property.getType();
assertTrue(type == cachedType);
}
@Test
public void navigationPropertyWithReferntialConstraint() throws Exception {
EdmProvider provider = mock(EdmProvider.class);
EdmProviderImpl edm = new EdmProviderImpl(provider);
final FullQualifiedName entityTypeName = new FullQualifiedName("ns", "entity");
EntityType entityTypeProvider = new EntityType();
entityTypeProvider.setKey(Collections.<PropertyRef> emptyList());
when(provider.getEntityType(entityTypeName)).thenReturn(entityTypeProvider);
NavigationProperty propertyProvider = new NavigationProperty();
propertyProvider.setType(entityTypeName);
propertyProvider.setNullable(false);
List<ReferentialConstraint> referentialConstraints = new ArrayList<ReferentialConstraint>();
referentialConstraints.add(new ReferentialConstraint().setProperty("property").setReferencedProperty(
"referencedProperty"));
propertyProvider.setReferentialConstraints(referentialConstraints);
EdmNavigationProperty property = new EdmNavigationPropertyImpl(edm, propertyProvider);
assertEquals("property", property.getReferencingPropertyName("referencedProperty"));
assertNull(property.getReferencingPropertyName("wrong"));
}
@Test
public void navigationPropertyWithPartner() throws Exception {
EdmProvider provider = mock(EdmProvider.class);
EdmProviderImpl edm = new EdmProviderImpl(provider);
final FullQualifiedName entityTypeName = new FullQualifiedName("ns", "entity");
EntityType entityTypeProvider = new EntityType();
entityTypeProvider.setKey(Collections.<PropertyRef> emptyList());
List<NavigationProperty> navigationProperties = new ArrayList<NavigationProperty>();
navigationProperties.add(new NavigationProperty().setName("partnerName").setType(entityTypeName));
entityTypeProvider.setNavigationProperties(navigationProperties);
when(provider.getEntityType(entityTypeName)).thenReturn(entityTypeProvider);
NavigationProperty propertyProvider = new NavigationProperty();
propertyProvider.setType(entityTypeName);
propertyProvider.setNullable(false);
propertyProvider.setPartner("partnerName");
EdmNavigationProperty property = new EdmNavigationPropertyImpl(edm, propertyProvider);
EdmNavigationProperty partner = property.getPartner();
assertNotNull(partner);
// Caching
assertTrue(partner == property.getPartner());
}
@Test(expected = EdmException.class)
public void navigationPropertyWithNonexistentPartner() throws Exception {
EdmProvider provider = mock(EdmProvider.class);
EdmProviderImpl edm = new EdmProviderImpl(provider);
final FullQualifiedName entityTypeName = new FullQualifiedName("ns", "entity");
EntityType entityTypeProvider = new EntityType();
entityTypeProvider.setKey(Collections.<PropertyRef> emptyList());
List<NavigationProperty> navigationProperties = new ArrayList<NavigationProperty>();
navigationProperties.add(new NavigationProperty().setName("partnerName").setType(entityTypeName));
entityTypeProvider.setNavigationProperties(navigationProperties);
when(provider.getEntityType(entityTypeName)).thenReturn(entityTypeProvider);
NavigationProperty propertyProvider = new NavigationProperty();
propertyProvider.setType(entityTypeName);
propertyProvider.setNullable(false);
propertyProvider.setPartner("wrong");
EdmNavigationProperty property = new EdmNavigationPropertyImpl(edm, propertyProvider);
property.getPartner();
}
@Test(expected = EdmException.class)
public void navigationPropertyWithNonExistentType() throws Exception {
EdmProviderImpl edm = mock(EdmProviderImpl.class);