You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ra...@apache.org on 2015/04/20 16:28:26 UTC
[06/22] olingo-odata4 git commit: [OLINGO-545] TecSvc: Support of
cyclic expands and filtering on arbitrary level
[OLINGO-545] TecSvc: Support of cyclic expands and filtering on arbitrary
level
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/518a3a41
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/518a3a41
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/518a3a41
Branch: refs/heads/OLINGO-573
Commit: 518a3a418e9e79e2a3ce5feb61e175083812c2d8
Parents: 583c4bd
Author: Christian Holzer <c....@sap.com>
Authored: Mon Apr 6 08:25:00 2015 +0200
Committer: Christian Holzer <c....@sap.com>
Committed: Tue Apr 7 08:26:05 2015 +0200
----------------------------------------------------------------------
.../ExpandWithSystemQueryOptionsITCase.java | 160 +++++++++++++-
.../processor/TechnicalEntityProcessor.java | 6 +-
.../ExpandSystemQueryOptionHandler.java | 208 +++++++++++++------
.../expression/ExpressionVisitorImpl.java | 10 +-
.../queryoptions/options/FilterHandler.java | 6 +-
.../queryoptions/options/OrderByHandler.java | 12 +-
6 files changed, 320 insertions(+), 82 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/518a3a41/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
index 2db9535..1a6b411 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
@@ -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;
@@ -119,7 +120,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
}
}
}
-
+
@Test
public void testSkip() {
final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
@@ -290,7 +291,162 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
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);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/518a3a41/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index ed120b9..a2774e3 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -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(
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/518a3a41/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
index 3ae3b3a..ce1b774 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/ExpandSystemQueryOptionHandler.java
@@ -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());
-
- copiedEntitySets.put(entitySet, copiedEntitySet);
- copiedEntitySets.put(copiedEntitySet, copiedEntitySet);
-
- for (Entity entity : entitySet.getEntities()) {
- copiedEntitySet.getEntities().add(copyEntityShallowRekursive(entity));
- }
- return copiedEntitySet;
+ public EntitySet transformEntitySetGraphToTree(final EntitySet entitySet, final EdmBindingTarget edmBindingTarget,
+ final ExpandOption expand) throws ODataApplicationException {
+
+ final EntitySet newEntitySet = newEntitySet(entitySet);
+
+ for(final Entity entity : entitySet.getEntities()) {
+ newEntitySet.getEntities().add(transformEntityGraphToTree(entity, edmBindingTarget, expand));
}
- return copiedEntitySets.get(entitySet);
+
+ return newEntitySet;
}
+
+ public Entity transformEntityGraphToTree(final Entity entity, EdmBindingTarget edmEntitySet,
+ final ExpandOption expand) throws ODataApplicationException {
- 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());
-
- copiedEntities.put(entity, copiedEntity);
- copiedEntities.put(copiedEntity, copiedEntity);
-
- // 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 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()));
+ 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));
+ }
}
- copiedEntity.getNavigationLinks().add(newLink);
}
+
+ }
+ 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());
+
+ return newLink;
+ }
+
+ private boolean hasExpandItems(ExpandOption expand) {
+ return expand != null && expand.getExpandItems() != null && !expand.getExpandItems().isEmpty();
+ }
+
+ 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;
+ }
- return copiedEntity;
+ 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 copiedEntities.get(entity);
+
+ return null;
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/518a3a41/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/ExpressionVisitorImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/ExpressionVisitorImpl.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/ExpressionVisitorImpl.java
index 3a91f49..ab0eca3 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/ExpressionVisitorImpl.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/ExpressionVisitorImpl.java
@@ -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++) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/518a3a41/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/FilterHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/FilterHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/FilterHandler.java
index f1ba4ee..d4068a1 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/FilterHandler.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/FilterHandler.java
@@ -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;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/518a3a41/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/OrderByHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/OrderByHandler.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/OrderByHandler.java
index 71b9a81..d166c4e 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/OrderByHandler.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/OrderByHandler.java
@@ -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()) {