[OLINGO-545] Single valued navigation properties can be null

This commit is contained in:
Christian Holzer 2015-03-11 17:21:21 +01:00
parent f6fa1eeca7
commit 4768048fba
2 changed files with 81 additions and 3 deletions

View File

@ -36,6 +36,7 @@ import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.commons.api.domain.ODataEntity;
import org.apache.olingo.commons.api.domain.ODataLink;
import org.apache.olingo.commons.api.domain.ODataObjectFactory;
import org.apache.olingo.commons.api.domain.ODataProperty;
import org.apache.olingo.commons.api.domain.ODataValue;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
@ -261,6 +262,53 @@ public class BindingITCase extends AbstractBaseTestITCase {
}
}
@Test
public void testUpdateSingleNavigationPropertyWithNull() {
final ODataClient client = getClient();
final URI entityURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(1).build();
final ODataObjectFactory of = client.getObjectFactory();
// Request to single (non collection) navigation property
ODataEntity entity = of.newEntity(ET_KEY_NAV);
final ODataProperty navPropery = of.newComplexProperty(NAV_PROPERTY_ET_KEY_NAV_ONE, null);
entity.getProperties().add(navPropery);
ODataEntityUpdateResponse<ODataEntity> updateResponse =
client.getCUDRequestFactory().getEntityUpdateRequest(entityURI, UpdateType.PATCH, entity).execute();
assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), updateResponse.getStatusCode());
final ODataEntityRequest<ODataEntity> getRequest =
client.getRetrieveRequestFactory().getEntityRequest(
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(1).expand(
NAV_PROPERTY_ET_KEY_NAV_ONE).build());
getRequest.addCustomHeader(HttpHeader.COOKIE, updateResponse.getHeader(HttpHeader.SET_COOKIE).iterator().next());
final ODataRetrieveResponse<ODataEntity> getResponse = getRequest.execute();
ODataProperty property = getResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE);
assertEquals(null, property.getPrimitiveValue());
}
@Test
public void testUpdateCollectionNavigationPropertyWithNull() {
final ODataClient client = getClient();
final URI entityURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(1).build();
final ODataObjectFactory of = client.getObjectFactory();
// Request to single (non collection) navigation property
ODataEntity entity = of.newEntity(ET_KEY_NAV);
final ODataProperty navPropery = of.newComplexProperty(NAV_PROPERTY_ET_KEY_NAV_MANY, null);
entity.getProperties().add(navPropery);
try {
client.getCUDRequestFactory().getEntityUpdateRequest(entityURI, UpdateType.PATCH, entity).execute();
fail();
} catch(ODataClientErrorException e) {
assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), e.getStatusLine().getStatusCode());
}
}
@Override
protected ODataClient getClient() {
ODataClient odata = ODataClientFactory.getClient();

View File

@ -236,6 +236,8 @@ public class DataProvider {
// Deep insert (only if not an update)
if (isInsert) {
handleDeepInsert(rawBaseUri, edmEntitySet, entity, changedEntity);
} else {
handleDeleteSingleNavigationProperties(edmEntitySet, entity, changedEntity);
}
final boolean navigationBindingsAvailable = !changedEntity.getNavigationBindings().isEmpty();
@ -244,6 +246,28 @@ public class DataProvider {
}
}
private void handleDeleteSingleNavigationProperties(EdmEntitySet edmEntitySet, Entity entity, Entity changedEntity)
throws DataProviderException {
final EdmEntityType entityType = edmEntitySet.getEntityType();
final List<String> navigationPropertyNames = entityType.getNavigationPropertyNames();
for (final String navPropertyName : navigationPropertyNames) {
final Link navigationLink = changedEntity.getNavigationLink(navPropertyName);
final EdmNavigationProperty navigationProperty = entityType.getNavigationProperty(navPropertyName);
if (!navigationProperty.isCollection() && navigationLink != null && navigationLink.getInlineEntity() == null) {
// Check if partner is available
if (navigationProperty.getPartner() != null && entity.getNavigationLink(navPropertyName) != null) {
Entity partnerEntity = entity.getNavigationLink(navPropertyName).getInlineEntity();
removeLink(navigationProperty.getPartner(), partnerEntity);
}
// Remove link
removeLink(navigationProperty, entity);
}
}
}
private void applyNavigationBinding(final String rawBaseUri, final EdmEntitySet edmEntitySet,
final Entity entity, final List<Link> navigationBindings) throws DataProviderException {
@ -303,15 +327,21 @@ public class DataProvider {
for (final Entity inlineEntity : entities) {
createLink(navigationProperty, entity, inlineEntity);
}
} else {
final Entity inlineEntity =
createInlineEntity(rawBaseUri, target, navigationLink.getInlineEntity());
} else if (!navigationProperty.isCollection() && navigationLink.getInlineEntity() != null) {
final Entity inlineEntity = createInlineEntity(rawBaseUri, target, navigationLink.getInlineEntity());
createLink(navigationProperty, entity, inlineEntity);
}
}
}
}
private void removeLink(EdmNavigationProperty navigationProperty, Entity entity) {
final Link link = entity.getNavigationLink(navigationProperty.getName());
if(link != null) {
entity.getNavigationLinks().remove(link);
}
}
private List<Entity> createInlineEntities(final String rawBaseUri, final EdmEntitySet targetEntitySet,
final EntitySet changedEntitySet) throws DataProviderException {
List<Entity> entities = new ArrayList<Entity>();