[OLINGO-545] TecSvc: Support of cyclic expands and filtering on arbitrary

level
This commit is contained in:
Christian Holzer 2015-04-06 08:25:00 +02:00
parent 583c4bd078
commit 518a3a418e
6 changed files with 320 additions and 82 deletions

View File

@ -19,6 +19,7 @@
package org.apache.olingo.fit.tecsvc.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import java.net.URI;
@ -291,6 +292,161 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
assertEquals(4, entities.size());
}
@Test
public void testCyclicExpand() {
// Expand entity in the following order
// 1 => 2 => 1
// Entity with Key (PropertyInt16=1, PrroperyString='1') holds references to (PropertyInt16=1, PropertyString='1')
// and (PropertyInt16=1, PropertyString='2')
// Entity with Key (PropertyInt16=1, PropertyString='2') holds references to (PropertyInt16=1, PropertyString='1')
// Define filters to select explicit the entities at any level => Circle
final ODataClient client = getClient();
final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
options.put(QueryOption.EXPAND, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
+ "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
+ "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY + "))");
options.put(QueryOption.FILTER, "PropertyString eq '2'");
final Map<String, Object> keys = new HashMap<String, Object>();
keys.put(PROPERTY_INT16, 1);
keys.put(PROPERTY_STRING, "1");
final URI uri = client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(ES_TWO_KEY_NAV)
.appendKeySegment(keys)
.expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options)
.build();
final ODataRetrieveResponse<ODataEntity> response = client.getRetrieveRequestFactory()
.getEntityRequest(uri)
.execute();
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
assertNotNull(response.getBody().getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY));
assertEquals(1, response.getBody().getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities()
.size());
final ODataEntity entitySecondLevel = response.getBody().getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities()
.get(0);
assertEquals(1, entitySecondLevel.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals("2", entitySecondLevel.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
assertNotNull(entitySecondLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY));
assertEquals(1, entitySecondLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities()
.size());
final ODataEntity entityThirdLevel = entitySecondLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities()
.get(0);
assertEquals(1, entityThirdLevel.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals("1", entityThirdLevel.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
assertNotNull(entityThirdLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY));
assertEquals(2, entityThirdLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities()
.size());
final List<ODataEntity> fourthLevelEntites = entityThirdLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities();
assertEquals(1, fourthLevelEntites.get(0).getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals("1", fourthLevelEntites.get(0).getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
assertEquals(1, fourthLevelEntites.get(1).getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals("2", fourthLevelEntites.get(1).getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
}
@Test
public void testSystemQueryOptionOnThirdLevel() {
final ODataClient client = getClient();
final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
options.put(QueryOption.EXPAND, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
+ "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
+ "($expand=" + NAV_PROPERTY_ET_TWO_KEY_NAV_MANY
+ ";$filter=PropertyString eq '1'))");
options.put(QueryOption.FILTER, "PropertyString eq '2'");
final Map<String, Object> keys = new HashMap<String, Object>();
keys.put(PROPERTY_INT16, 1);
keys.put(PROPERTY_STRING, "1");
final URI uri = client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(ES_TWO_KEY_NAV)
.appendKeySegment(keys)
.expandWithOptions(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options)
.build();
final ODataRetrieveResponse<ODataEntity> response = client.getRetrieveRequestFactory()
.getEntityRequest(uri)
.execute();
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
assertNotNull(response.getBody().getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY));
assertEquals(1, response.getBody().getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities()
.size());
final ODataEntity entitySecondLevel = response.getBody().getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities()
.get(0);
assertEquals(1, entitySecondLevel.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals("2", entitySecondLevel.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
assertNotNull(entitySecondLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY));
assertEquals(1, entitySecondLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities()
.size());
final ODataEntity entityThirdLevel = entitySecondLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities()
.get(0);
assertEquals(1, entityThirdLevel.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals("1", entityThirdLevel.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
assertNotNull(entityThirdLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY));
assertEquals(1, entityThirdLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities()
.size());
final List<ODataEntity> fourthLevelEntites = entityThirdLevel.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY)
.asInlineEntitySet()
.getEntitySet()
.getEntities();
assertEquals(1, fourthLevelEntites.get(0).getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals("1", fourthLevelEntites.get(0).getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
}
private ODataRetrieveResponse<ODataEntitySet> buildRequest(final String entitySet, final String navigationProperty,
final Map<QueryOption, Object> expandOptions) {
return buildRequest(entitySet, navigationProperty, expandOptions, null);

View File

@ -125,7 +125,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
// Create a shallow copy of each entity. So the expanded navigation properties can be modified for serialization,
// without affecting the data stored in the database.
final ExpandSystemQueryOptionHandler expandHandler = new ExpandSystemQueryOptionHandler();
final EntitySet entitySetSerialization = expandHandler.copyEntitySetShallowRekursive(entitySet);
final EntitySet entitySetSerialization = expandHandler.transformEntitySetGraphToTree(entitySet,
edmEntitySet,
expand);
expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand);
// Serialize
@ -186,7 +188,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
final SelectOption select = uriInfo.getSelectOption();
final ExpandSystemQueryOptionHandler expandHandler = new ExpandSystemQueryOptionHandler();
final Entity entitySerialization = expandHandler.copyEntityShallowRekursive(entity);
final Entity entitySerialization = expandHandler.transformEntityGraphToTree(entity, edmEntitySet, expand);
expandHandler.applyExpandQueryOptions(entitySerialization, edmEntitySet, expand);
response.setContent(serializer.entity(

View File

@ -18,15 +18,18 @@
*/
package org.apache.olingo.server.tecsvc.processor.queryoptions;
import java.util.IdentityHashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.data.EntityImpl;
import org.apache.olingo.commons.core.data.EntitySetImpl;
@ -47,8 +50,6 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.options.SkipHandle
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.TopHandler;
public class ExpandSystemQueryOptionHandler {
private IdentityHashMap<Entity, Entity> copiedEntities = new IdentityHashMap<Entity, Entity>();
private IdentityHashMap<EntitySet, EntitySet> copiedEntitySets = new IdentityHashMap<EntitySet, EntitySet>();
public void applyExpandQueryOptions(final EntitySet entitySet, final EdmEntitySet edmEntitySet,
final ExpandOption expandOption) throws ODataApplicationException {
@ -70,20 +71,26 @@ public class ExpandSystemQueryOptionHandler {
applyExpandOptionToEntity(entity, edmEntitySet, expandOption);
}
private void applyExpandOptionToEntity(final Entity entity, final EdmEntitySet edmEntitySet,
private void applyExpandOptionToEntity(final Entity entity, final EdmBindingTarget edmBindingTarget,
final ExpandOption expandOption) throws ODataApplicationException {
final EdmEntityType entityType = edmEntitySet.getEntityType();
final EdmEntityType entityType = edmBindingTarget.getEntityType();
for (ExpandItem item : expandOption.getExpandItems()) {
final List<UriResource> uriResourceParts = item.getResourcePath().getUriResourceParts();
if (uriResourceParts.size() == 1 && uriResourceParts.get(0) instanceof UriResourceNavigation) {
final String navPropertyName = ((UriResourceNavigation) uriResourceParts.get(0)).getProperty().getName();
final EdmEntitySet targetEdmEntitySet = (EdmEntitySet) edmEntitySet.getRelatedBindingTarget(navPropertyName);
final EdmBindingTarget targetEdmEntitySet = edmBindingTarget.getRelatedBindingTarget(navPropertyName);
final Link link = entity.getNavigationLink(navPropertyName);
if (link != null && entityType.getNavigationProperty(navPropertyName).isCollection()) {
applyOptionsToEntityCollection(link.getInlineEntitySet(), targetEdmEntitySet, item.getFilterOption(),
item.getOrderByOption(), item.getCountOption(), item.getSkipOption(), item.getTopOption());
applyOptionsToEntityCollection(link.getInlineEntitySet(),
targetEdmEntitySet,
item.getFilterOption(),
item.getOrderByOption(),
item.getCountOption(),
item.getSkipOption(),
item.getTopOption(),
item.getExpandOption());
}
} else {
throw new ODataApplicationException("Not supported resource part in expand system query option",
@ -92,77 +99,150 @@ public class ExpandSystemQueryOptionHandler {
}
}
private void applyOptionsToEntityCollection(final EntitySet entitySet, final EdmEntitySet edmEntitySet,
private void applyOptionsToEntityCollection(final EntitySet entitySet, final EdmBindingTarget edmBindingTarget,
final FilterOption filterOption, final OrderByOption orderByOption, final CountOption countOption,
final SkipOption skipOption, final TopOption topOption) throws ODataApplicationException {
final SkipOption skipOption, final TopOption topOption, final ExpandOption expandOption)
throws ODataApplicationException {
FilterHandler.applyFilterSystemQuery(filterOption, entitySet, edmEntitySet);
OrderByHandler.applyOrderByOption(orderByOption, entitySet, edmEntitySet);
FilterHandler.applyFilterSystemQuery(filterOption, entitySet, edmBindingTarget);
OrderByHandler.applyOrderByOption(orderByOption, entitySet, edmBindingTarget);
// TODO Add CountHandler
SkipHandler.applySkipSystemQueryHandler(skipOption, entitySet);
TopHandler.applyTopSystemQueryOption(topOption, entitySet);
// Apply nested expand system query options to remaining entities
if(expandOption != null) {
for(final Entity entity : entitySet.getEntities()) {
applyExpandOptionToEntity(entity, edmBindingTarget, expandOption);
}
}
}
public EntitySet copyEntitySetShallowRekursive(final EntitySet entitySet) {
if (!copiedEntitySets.containsKey(entitySet)) {
final EntitySet copiedEntitySet = new EntitySetImpl();
copiedEntitySet.setCount(entitySet.getCount());
copiedEntitySet.setDeltaLink(entitySet.getDeltaLink());
copiedEntitySet.setNext(entitySet.getNext());
public EntitySet transformEntitySetGraphToTree(final EntitySet entitySet, final EdmBindingTarget edmBindingTarget,
final ExpandOption expand) throws ODataApplicationException {
copiedEntitySets.put(entitySet, copiedEntitySet);
copiedEntitySets.put(copiedEntitySet, copiedEntitySet);
final EntitySet newEntitySet = newEntitySet(entitySet);
for (Entity entity : entitySet.getEntities()) {
copiedEntitySet.getEntities().add(copyEntityShallowRekursive(entity));
}
return copiedEntitySet;
}
return copiedEntitySets.get(entitySet);
for(final Entity entity : entitySet.getEntities()) {
newEntitySet.getEntities().add(transformEntityGraphToTree(entity, edmBindingTarget, expand));
}
public Entity copyEntityShallowRekursive(final Entity entity) {
if (!copiedEntities.containsKey(entity)) {
final Entity copiedEntity = new EntityImpl();
copiedEntity.getProperties().addAll(entity.getProperties());
copiedEntity.getAnnotations().addAll(entity.getAnnotations());
copiedEntity.getAssociationLinks().addAll(entity.getAssociationLinks());
copiedEntity.setEditLink(entity.getEditLink());
copiedEntity.setId(entity.getId());
copiedEntity.setMediaContentSource(entity.getMediaContentSource());
copiedEntity.setMediaContentType(entity.getMediaContentType());
copiedEntity.setMediaETag(entity.getMediaETag());
copiedEntity.getOperations().addAll(entity.getOperations());
copiedEntity.setSelfLink(entity.getSelfLink());
copiedEntity.setType(entity.getType());
copiedEntity.getNavigationBindings().addAll(entity.getNavigationBindings());
return newEntitySet;
}
copiedEntities.put(entity, copiedEntity);
copiedEntities.put(copiedEntity, copiedEntity);
public Entity transformEntityGraphToTree(final Entity entity, EdmBindingTarget edmEntitySet,
final ExpandOption expand) throws ODataApplicationException {
// The system query options change the amount and sequence of inline entities (feeds)
// So we have to make a shallow copy of all navigation link lists
// Make sure, that each entity is only copied once.
// Otherwise an infinite loop can occur caused by cyclic navigation relationships.
final Entity newEntity = newEntity(entity);
if (hasExpandItems(expand)) {
final boolean expandAll = expandAll(expand);
final Set<String> expanded = expandAll ? null : getExpandedPropertyNames(expand.getExpandItems());
final EdmEntityType edmType = edmEntitySet.getEntityType();
for (final Link link : entity.getNavigationLinks()) {
final String propertyName = link.getTitle();
if (expandAll || expanded.contains(propertyName)) {
final EdmNavigationProperty edmNavigationProperty = edmType.getNavigationProperty(propertyName);
final EdmBindingTarget edmBindingTarget = edmEntitySet.getRelatedBindingTarget(propertyName);
final Link newLink = newLink(link);
newEntity.getNavigationLinks().add(newLink);
final ExpandOption innerExpandOption = getInnerExpandOption(expand, propertyName);
if(edmNavigationProperty.isCollection()) {
newLink.setInlineEntitySet(transformEntitySetGraphToTree(link.getInlineEntitySet(),
edmBindingTarget,
innerExpandOption));
} else {
newLink.setInlineEntity(transformEntityGraphToTree(link.getInlineEntity(),
edmBindingTarget,
innerExpandOption));
}
}
}
}
return newEntity;
}
public EntitySet newEntitySet(final EntitySet entitySet) {
final EntitySet newEntitySet = new EntitySetImpl();
newEntitySet.setCount(entitySet.getCount());
newEntitySet.setDeltaLink(entitySet.getDeltaLink());
newEntitySet.setNext(entitySet.getNext());
return newEntitySet;
}
private Entity newEntity(final Entity entity) {
final Entity newEntity = new EntityImpl();
newEntity.getProperties().addAll(entity.getProperties());
newEntity.getAnnotations().addAll(entity.getAnnotations());
newEntity.getAssociationLinks().addAll(entity.getAssociationLinks());
newEntity.setEditLink(entity.getEditLink());
newEntity.setId(entity.getId());
newEntity.setMediaContentSource(entity.getMediaContentSource());
newEntity.setMediaContentType(entity.getMediaContentType());
newEntity.setMediaETag(entity.getMediaETag());
newEntity.getOperations().addAll(entity.getOperations());
newEntity.setSelfLink(entity.getSelfLink());
newEntity.setType(entity.getType());
newEntity.getNavigationBindings().addAll(entity.getNavigationBindings());
return newEntity;
}
private Link newLink(Link link) {
final Link newLink = new LinkImpl();
newLink.setMediaETag(link.getMediaETag());
newLink.setTitle(link.getTitle());
newLink.setType(link.getType());
newLink.setRel(link.getRel());
final EntitySet inlineEntitySet = link.getInlineEntitySet();
if (inlineEntitySet != null) {
newLink.setInlineEntitySet(copyEntitySetShallowRekursive(inlineEntitySet));
} else if (link.getInlineEntity() != null) {
newLink.setInlineEntity(copyEntityShallowRekursive(link.getInlineEntity()));
}
copiedEntity.getNavigationLinks().add(newLink);
return newLink;
}
return copiedEntity;
private boolean hasExpandItems(ExpandOption expand) {
return expand != null && expand.getExpandItems() != null && !expand.getExpandItems().isEmpty();
}
return copiedEntities.get(entity);
private boolean expandAll(ExpandOption expand) {
for (final ExpandItem item : expand.getExpandItems()) {
if (item.isStar()) {
return true;
}
}
return false;
}
private Set<String> getExpandedPropertyNames(List<ExpandItem> expandItems) throws ODataApplicationException {
Set<String> expanded = new HashSet<String>();
for (final ExpandItem item : expandItems) {
final List<UriResource> resourceParts = item.getResourcePath().getUriResourceParts();
if (resourceParts.size() == 1) {
final UriResource resource = resourceParts.get(0);
if (resource instanceof UriResourceNavigation) {
expanded.add(((UriResourceNavigation) resource).getProperty().getName());
}
} else {
throw new ODataApplicationException("Expand is not supported within complex properties.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
}
}
return expanded;
}
private ExpandOption getInnerExpandOption(final ExpandOption expand, final String propertyName) {
for(final ExpandItem item : expand.getExpandItems()) {
final UriResource resource = item.getResourcePath().getUriResourceParts().get(0);
if(resource instanceof UriResourceNavigation
&& propertyName.equals(((UriResourceNavigation) resource).getProperty().getName())) {
return item.getExpandOption();
}
}
return null;
}
}

View File

@ -23,8 +23,8 @@ import java.util.Locale;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmType;
@ -49,11 +49,11 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operati
public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand> {
final private Entity entity;
final private EdmEntitySet edmEntitySet;
final private EdmBindingTarget bindingTarget;
public ExpressionVisitorImpl(Entity entity, EdmEntitySet edmEntitySet) {
public ExpressionVisitorImpl(Entity entity, EdmBindingTarget bindingTarget) {
this.entity = entity;
this.edmEntitySet = edmEntitySet;
this.bindingTarget = bindingTarget;
}
@Override
@ -183,7 +183,7 @@ public class ExpressionVisitorImpl implements ExpressionVisitor<VisitorOperand>
Property currentProperty = entity.getProperty(uriResourceParts.get(0).toString());
EdmType currentType = ((UriResourcePartTyped) uriResourceParts.get(0)).getType();
EdmProperty currentEdmProperty = edmEntitySet.getEntityType()
EdmProperty currentEdmProperty = bindingTarget.getEntityType()
.getStructuralProperty(uriResourceParts.get(0).toString());
for (int i = 1; i < uriResourceParts.size(); i++) {

View File

@ -23,7 +23,7 @@ import java.util.Locale;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.edm.primitivetype.EdmBoolean;
import org.apache.olingo.server.api.ODataApplicationException;
@ -53,8 +53,8 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand
public class FilterHandler {
public static void applyFilterSystemQuery(FilterOption filterOption, EntitySet entitySet, EdmEntitySet edmEntitySet)
throws ODataApplicationException {
public static void applyFilterSystemQuery(FilterOption filterOption, EntitySet entitySet,
EdmBindingTarget edmEntitySet) throws ODataApplicationException {
if (filterOption == null) {
return;

View File

@ -24,7 +24,7 @@ import java.util.Locale;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
@ -35,14 +35,14 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand
public class OrderByHandler {
public static void applyOrderByOption(final OrderByOption orderByOption, final EntitySet entitySet,
final EdmEntitySet edmEntitySet) throws ODataApplicationException {
final EdmBindingTarget edmBindingTarget) throws ODataApplicationException {
if (orderByOption == null) {
return;
}
try {
applyOrderByOptionInternal(orderByOption, entitySet, edmEntitySet);
applyOrderByOptionInternal(orderByOption, entitySet, edmBindingTarget);
} catch (SystemQueryOptionsRuntimeException e) {
if (e.getCause() instanceof ODataApplicationException) {
// Throw the nested exception, to send the correct HTTP status code in the HTTP response
@ -55,7 +55,7 @@ public class OrderByHandler {
}
private static void applyOrderByOptionInternal(final OrderByOption orderByOption, final EntitySet entitySet,
final EdmEntitySet edmEntitySet) throws ODataApplicationException {
final EdmBindingTarget edmBindingTarget) throws ODataApplicationException {
Collections.sort(entitySet.getEntities(), new Comparator<Entity>() {
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
@ -69,9 +69,9 @@ public class OrderByHandler {
try {
final OrderByItem item = orderByOption.getOrders().get(i);
final TypedOperand op1 =
item.getExpression().accept(new ExpressionVisitorImpl(e1, edmEntitySet)).asTypedOperand();
item.getExpression().accept(new ExpressionVisitorImpl(e1, edmBindingTarget)).asTypedOperand();
final TypedOperand op2 =
item.getExpression().accept(new ExpressionVisitorImpl(e2, edmEntitySet)).asTypedOperand();
item.getExpression().accept(new ExpressionVisitorImpl(e2, edmBindingTarget)).asTypedOperand();
if (op1.isNull() || op2.isNull()) {
if (op1.isNull() && op2.isNull()) {