mirror of
https://github.com/apache/olingo-odata4.git
synced 2025-03-06 00:29:05 +00:00
[OLINGO-545] Expand supports the system query options $top, $skip, $filter, $orderby, $select
This commit is contained in:
parent
b98275153a
commit
4f15c7c724
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.fit.tecsvc.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.olingo.client.api.EdmEnabledODataClient;
|
||||
import org.apache.olingo.client.api.ODataClient;
|
||||
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
|
||||
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
|
||||
import org.apache.olingo.client.api.uri.QueryOption;
|
||||
import org.apache.olingo.client.core.ODataClientFactory;
|
||||
import org.apache.olingo.commons.api.domain.ODataEntity;
|
||||
import org.apache.olingo.commons.api.domain.ODataEntitySet;
|
||||
import org.apache.olingo.commons.api.format.ODataFormat;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.fit.AbstractBaseTestITCase;
|
||||
import org.apache.olingo.fit.tecsvc.TecSvcConst;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
|
||||
|
||||
private static final String ES_KEY_NAV = "ESKeyNav";
|
||||
private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
|
||||
private static final String NAV_PROPERTY_ET_KEY_NAV_MANY = "NavPropertyETKeyNavMany";
|
||||
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany";
|
||||
private static final String SERVICE_URI = TecSvcConst.BASE_URI;
|
||||
private static final String PROPERTY_INT16 = "PropertyInt16";
|
||||
private static final String PROPERTY_STRING = "PropertyString";
|
||||
|
||||
@Test
|
||||
public void testFilter() {
|
||||
final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
|
||||
options.put(QueryOption.FILTER, "PropertyString eq '2'");
|
||||
|
||||
final ODataRetrieveResponse<ODataEntitySet> response =
|
||||
buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
|
||||
final List<ODataEntity> entities = response.getBody().getEntities();
|
||||
assertEquals(4, entities.size());
|
||||
|
||||
for (final ODataEntity entity : entities) {
|
||||
final Object propInt16 = entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue();
|
||||
final Object propString = entity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
|
||||
final ODataEntitySet inlineEntitySet =
|
||||
entity.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
|
||||
|
||||
if (propInt16.equals(1) && propString.equals("1")) {
|
||||
assertEquals(1, inlineEntitySet.getEntities().size());
|
||||
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
|
||||
|
||||
assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertEquals("2", inlineEntity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
|
||||
} else if (propInt16.equals(1) && propString.equals("2")) {
|
||||
assertEquals(0, inlineEntitySet.getEntities().size());
|
||||
} else if (propInt16.equals(2) && propString.equals("1")) {
|
||||
assertEquals(1, inlineEntitySet.getEntities().size());
|
||||
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
|
||||
|
||||
assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertEquals("2", inlineEntity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
|
||||
} else if (propInt16.equals(3) && propString.equals("1")) {
|
||||
assertEquals(0, inlineEntitySet.getEntities().size());
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrderBy() {
|
||||
final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
|
||||
options.put(QueryOption.ORDERBY, "PropertyString desc");
|
||||
|
||||
final ODataRetrieveResponse<ODataEntitySet> response =
|
||||
buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
|
||||
final List<ODataEntity> entities = response.getBody().getEntities();
|
||||
assertEquals(4, entities.size());
|
||||
|
||||
for (final ODataEntity entity : entities) {
|
||||
final Object propInt16 = entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue();
|
||||
final Object propString = entity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
|
||||
final ODataEntitySet inlineEntitySet =
|
||||
entity.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
|
||||
|
||||
if (propInt16.equals(1) && propString.equals("1")) {
|
||||
assertEquals(2, inlineEntitySet.getEntities().size());
|
||||
final ODataEntity inlineEntity1 = inlineEntitySet.getEntities().get(0);
|
||||
final ODataEntity inlineEntity2 = inlineEntitySet.getEntities().get(1);
|
||||
|
||||
assertEquals(1, inlineEntity1.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertEquals("2", inlineEntity1.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
|
||||
|
||||
assertEquals(1, inlineEntity2.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertEquals("1", inlineEntity2.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkip() {
|
||||
final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
|
||||
options.put(QueryOption.SKIP, "1");
|
||||
|
||||
final ODataRetrieveResponse<ODataEntitySet> response =
|
||||
buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY, options);
|
||||
final List<ODataEntity> entities = response.getBody().getEntities();
|
||||
assertEquals(3, entities.size());
|
||||
|
||||
for (final ODataEntity entity : entities) {
|
||||
final Object propInt16 = entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue();
|
||||
final ODataEntitySet inlineEntitySet =
|
||||
entity.getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
|
||||
|
||||
if (propInt16.equals(1)) {
|
||||
assertEquals(1, inlineEntitySet.getEntities().size());
|
||||
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
|
||||
|
||||
assertEquals(2, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
} else if (propInt16.equals(2)) {
|
||||
assertEquals(1, inlineEntitySet.getEntities().size());
|
||||
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
|
||||
|
||||
assertEquals(3, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
} else if (propInt16.equals(3)) {
|
||||
assertEquals(0, inlineEntitySet.getEntities().size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTop() {
|
||||
final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
|
||||
options.put(QueryOption.TOP, "1");
|
||||
|
||||
final ODataRetrieveResponse<ODataEntitySet> response =
|
||||
buildRequest(ES_KEY_NAV, NAV_PROPERTY_ET_KEY_NAV_MANY, options);
|
||||
final List<ODataEntity> entities = response.getBody().getEntities();
|
||||
assertEquals(3, entities.size());
|
||||
|
||||
for (final ODataEntity entity : entities) {
|
||||
final Object propInt16 = entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue();
|
||||
final ODataEntitySet inlineEntitySet =
|
||||
entity.getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
|
||||
|
||||
if (propInt16.equals(1)) {
|
||||
assertEquals(1, inlineEntitySet.getEntities().size());
|
||||
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
|
||||
|
||||
assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
} else if (propInt16.equals(2)) {
|
||||
assertEquals(1, inlineEntitySet.getEntities().size());
|
||||
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
|
||||
|
||||
assertEquals(2, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
} else if (propInt16.equals(3)) {
|
||||
assertEquals(0, inlineEntitySet.getEntities().size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCombinedSystemQueryOptions() {
|
||||
final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
|
||||
options.put(QueryOption.SELECT, "PropertyInt16,PropertyString");
|
||||
options.put(QueryOption.FILTER, "PropertyInt16 eq 1");
|
||||
options.put(QueryOption.SKIP, "1");
|
||||
|
||||
final ODataRetrieveResponse<ODataEntitySet> response =
|
||||
buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
|
||||
final List<ODataEntity> entities = response.getBody().getEntities();
|
||||
assertEquals(4, entities.size());
|
||||
|
||||
for (final ODataEntity entity : entities) {
|
||||
final Object propInt16 = entity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue();
|
||||
final Object propString = entity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
|
||||
final ODataEntitySet inlineEntitySet =
|
||||
entity.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
|
||||
|
||||
if (propInt16.equals(1) && propString.equals("1")) {
|
||||
assertEquals(1, inlineEntitySet.getEntities().size());
|
||||
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
|
||||
|
||||
assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
|
||||
assertEquals("2", inlineEntity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
|
||||
} else if (propInt16.equals(1) && propString.equals("2")) {
|
||||
assertEquals(0, inlineEntitySet.getEntities().size());
|
||||
} else if (propInt16.equals(2) && propString.equals("1")) {
|
||||
assertEquals(0, inlineEntitySet.getEntities().size());
|
||||
} else if (propInt16.equals(3) && propString.equals("1")) {
|
||||
assertEquals(0, inlineEntitySet.getEntities().size());
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testURIEscaping() {
|
||||
final Map<QueryOption, Object> options = new HashMap<QueryOption, Object>();
|
||||
options.put(QueryOption.FILTER, "PropertyInt16 eq 1"
|
||||
+ " and PropertyComp/PropertyComp/PropertyDuration eq duration'PT1S' and length(PropertyString) gt 4");
|
||||
final ODataRetrieveResponse<ODataEntitySet> response =
|
||||
buildRequest(ES_TWO_KEY_NAV, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, options);
|
||||
final List<ODataEntity> entities = response.getBody().getEntities();
|
||||
|
||||
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
|
||||
assertEquals(4, entities.size());
|
||||
}
|
||||
|
||||
private ODataRetrieveResponse<ODataEntitySet> buildRequest(final String entitySet, final String navigationProperty,
|
||||
final Map<QueryOption, Object> expandOptions) {
|
||||
return buildRequest(entitySet, navigationProperty, expandOptions, null);
|
||||
}
|
||||
|
||||
private ODataRetrieveResponse<ODataEntitySet> buildRequest(final String entitySet, final String navigationProperty,
|
||||
final Map<QueryOption, Object> expandOptions, final String cookie) {
|
||||
final ODataClient client = getClient();
|
||||
final URI uri = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(entitySet)
|
||||
.expandWithOptions(navigationProperty, expandOptions)
|
||||
.build();
|
||||
|
||||
final ODataEntitySetRequest<ODataEntitySet> request = client.getRetrieveRequestFactory().getEntitySetRequest(uri);
|
||||
|
||||
if (cookie != null) {
|
||||
request.addCustomHeader(HttpHeader.COOKIE, cookie);
|
||||
}
|
||||
|
||||
return request.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ODataClient getClient() {
|
||||
EdmEnabledODataClient odata = ODataClientFactory.getEdmEnabledClient(SERVICE_URI);
|
||||
odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON);
|
||||
return odata;
|
||||
}
|
||||
}
|
@ -664,9 +664,9 @@ public class DataCreator {
|
||||
|
||||
// NavPropertyETTwoKeyNavMany
|
||||
setLinks(entitySet.getEntities().get(0), "NavPropertyETTwoKeyNavMany",
|
||||
esKeyNavTargets.get(0), esKeyNavTargets.get(1));
|
||||
setLinks(entitySet.getEntities().get(1), "NavPropertyETTwoKeyNavMany", esKeyNavTargets.get(0));
|
||||
setLinks(entitySet.getEntities().get(2), "NavPropertyETTwoKeyNavMany", esKeyNavTargets.get(1));
|
||||
esTwoKeyNavTargets.get(0), esTwoKeyNavTargets.get(1));
|
||||
setLinks(entitySet.getEntities().get(1), "NavPropertyETTwoKeyNavMany", esTwoKeyNavTargets.get(0));
|
||||
setLinks(entitySet.getEntities().get(2), "NavPropertyETTwoKeyNavMany", esTwoKeyNavTargets.get(1));
|
||||
}
|
||||
|
||||
protected static Property createPrimitive(final String name, final Object value) {
|
||||
|
@ -55,6 +55,7 @@ import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.ExpandSystemQueryOptionHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.CountHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.FilterHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.OrderByHandler;
|
||||
@ -104,12 +105,21 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||
entitySet,
|
||||
edmEntitySet,
|
||||
request.getRawRequestUri());
|
||||
|
||||
|
||||
// Apply expand system query option
|
||||
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
|
||||
ODataSerializer serializer = odata.createSerializer(format);
|
||||
final ExpandOption expand = uriInfo.getExpandOption();
|
||||
final SelectOption select = uriInfo.getSelectOption();
|
||||
response.setContent(serializer.entityCollection(edmEntityType, entitySet,
|
||||
|
||||
// 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);
|
||||
expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand);
|
||||
|
||||
// Serialize
|
||||
response.setContent(serializer.entityCollection(edmEntityType, entitySetSerialization,
|
||||
EntityCollectionSerializerOptions.with()
|
||||
.contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
|
||||
getContextUrl(edmEntitySet, edmEntityType, false, expand, select))
|
||||
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.olingo.server.tecsvc.processor.queryoptions;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
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.data.Link;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.commons.core.data.EntityImpl;
|
||||
import org.apache.olingo.commons.core.data.EntitySetImpl;
|
||||
import org.apache.olingo.commons.core.data.LinkImpl;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||
import org.apache.olingo.server.api.uri.queryoption.CountOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
|
||||
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.FilterOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.SkipOption;
|
||||
import org.apache.olingo.server.api.uri.queryoption.TopOption;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.FilterHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.OrderByHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.SkipHandler;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.TopHandler;
|
||||
|
||||
public class ExpandSystemQueryOptionHandler {
|
||||
private HashMap<Entity, Entity> copiedEntities = new HashMap<Entity, Entity>();
|
||||
private HashMap<EntitySet, EntitySet> copiedEntitySets = new HashMap<EntitySet, EntitySet>();
|
||||
|
||||
public void applyExpandQueryOptions(final EntitySet entitySet, final EdmEntitySet edmEntitySet,
|
||||
final ExpandOption expandOption) throws ODataApplicationException {
|
||||
final EdmEntityType entityType = edmEntitySet.getEntityType();
|
||||
if (expandOption == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
for (final Entity entity : entitySet.getEntities()) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new ODataApplicationException("Not supported resource part in expand system query option",
|
||||
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void applyOptionsToEntityCollection(final EntitySet entitySet, final EdmEntitySet edmEntitySet,
|
||||
final FilterOption filterOption, final OrderByOption orderByOption, final CountOption countOption,
|
||||
final SkipOption skipOption, final TopOption topOption) throws ODataApplicationException {
|
||||
|
||||
FilterHandler.applyFilterSystemQuery(filterOption, entitySet, edmEntitySet);
|
||||
OrderByHandler.applyOrderByOption(orderByOption, entitySet, edmEntitySet);
|
||||
SkipHandler.applySkipSystemQueryHandler(skipOption, entitySet);
|
||||
TopHandler.applyTopSystemQueryOption(topOption, entitySet);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return copiedEntitySets.get(entitySet);
|
||||
}
|
||||
|
||||
private 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.
|
||||
|
||||
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()));
|
||||
}
|
||||
copiedEntity.getNavigationLinks().add(newLink);
|
||||
}
|
||||
|
||||
return copiedEntity;
|
||||
}
|
||||
return copiedEntities.get(entity);
|
||||
}
|
||||
}
|
@ -140,7 +140,7 @@ public class ComplexTypeProvider {
|
||||
.setProperties(Arrays.asList(PropertyProvider.propertyInt16))
|
||||
.setNavigationProperties((Arrays.asList(
|
||||
PropertyProvider.collectionNavPropertyETTwoKeyNavOne_ETTwoKeyNav,
|
||||
PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav,
|
||||
PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav_WithPartnerERKeyNavOne,
|
||||
new NavigationProperty()
|
||||
.setName("NavPropertyETMediaOne")
|
||||
.setType(EntityTypeProvider.nameETMedia),
|
||||
@ -154,7 +154,7 @@ public class ComplexTypeProvider {
|
||||
.setName("CTBasePrimCompNav")
|
||||
.setBaseType(nameCTPrimComp)
|
||||
.setNavigationProperties(Arrays.asList(
|
||||
PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav,
|
||||
PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav_WithPartnerERKeyNavOne,
|
||||
PropertyProvider.collectionNavPropertyETTwoKeyNavOne_ETTwoKeyNav,
|
||||
PropertyProvider.navPropertyETKeyNavOne_ETKeyNav,
|
||||
PropertyProvider.collectionNavPropertyETKeyNavMany_ETKeyNav));
|
||||
|
@ -315,7 +315,7 @@ public class EntityTypeProvider {
|
||||
.setNavigationProperties(
|
||||
Arrays.asList(
|
||||
PropertyProvider.navPropertyETTwoKeyNavOne_ETTwoKeyNav_NotNullable,
|
||||
PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav,
|
||||
PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav_WithPartnerERKeyNavOne,
|
||||
PropertyProvider.navPropertyETKeyNavOne_ETKeyNav,
|
||||
PropertyProvider.collectionNavPropertyETKeyNavMany_ETKeyNav,
|
||||
PropertyProvider.navPropertyETMediaOne_ETMedia,
|
||||
|
@ -632,12 +632,18 @@ public class PropertyProvider {
|
||||
.setType(EntityTypeProvider.nameETMedia)
|
||||
.setCollection(true);
|
||||
|
||||
public static final NavigationProperty collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav_WithPartnerERKeyNavOne
|
||||
= new NavigationProperty()
|
||||
.setName("NavPropertyETTwoKeyNavMany")
|
||||
.setType(EntityTypeProvider.nameETTwoKeyNav)
|
||||
.setCollection(true)
|
||||
.setPartner("NavPropertyETKeyNavOne");
|
||||
|
||||
public static final NavigationProperty collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav = new NavigationProperty()
|
||||
.setName("NavPropertyETTwoKeyNavMany")
|
||||
.setType(EntityTypeProvider.nameETTwoKeyNav)
|
||||
.setCollection(true)
|
||||
.setPartner("NavPropertyETKeyNavOne");
|
||||
|
||||
.setName("NavPropertyETTwoKeyNavMany")
|
||||
.setType(EntityTypeProvider.nameETTwoKeyNav)
|
||||
.setCollection(true);
|
||||
|
||||
public static final NavigationProperty collectionNavPropertyETTwoKeyNavOne_ETTwoKeyNav = new NavigationProperty()
|
||||
.setName("NavPropertyETTwoKeyNavOne")
|
||||
.setType(EntityTypeProvider.nameETTwoKeyNav);
|
||||
|
Loading…
x
Reference in New Issue
Block a user