[OLINGO-545] Deep Insert and Navigation Property Binding while creating and updating entities added

Signed-off-by: Michael Bolz <michael.bolz@sap.com>
This commit is contained in:
Christian Holzer 2015-02-24 09:54:03 +01:00 committed by Michael Bolz
parent 4c23cd9d8c
commit 7a4b562724
12 changed files with 906 additions and 139 deletions

View File

@ -0,0 +1,224 @@
/*
* 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 java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.communication.request.cud.UpdateType;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
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.ODataValue;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.fit.AbstractBaseTestITCase;
import org.apache.olingo.fit.tecsvc.TecSvcConst;
import org.junit.Test;
public class BindingITCase extends AbstractBaseTestITCase {
private static final String SERVICE_URI = TecSvcConst.BASE_URI;
private static final String SERVICE_NAMESPACE = "olingo.odata.test1";
private static final String ES_KEY_NAV = "ESKeyNav";
private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
private static final String ET_KEY_NAV_NAME = "ETKeyNav";
private static final FullQualifiedName ET_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_KEY_NAV_NAME);
private static final String CT_PRIM_COMP = "CTPrimComp";
private static final String CT_TWO_PRIM = "CTTwoPrim";
private static final String CT_ALL_PRIM = "CTAllPrim";
private static final String CT_NAV_FIVE_PROP = "CTNavFiveProp";
private static final String PROPERTY_INT16 = "PropertyInt16";
private static final String PROPERTY_STRING = "PropertyString";
private static final String PROPERTY_COMP = "PropertyComp";
private static final String PROPERTY_COMP_COMP = "PropertyCompComp";
private static final String PROPERTY_COMP_TWO_PRIM = "PropertyCompTwoPrim";
private static final String PROPERTY_COMP_ALL_PRIM = "PropertyCompAllPrim";
private static final String NAV_PROPERTY_ET_KEY_NAV_ONE = "NavPropertyETKeyNavOne";
private static final String NAV_PROPERTY_ET_KEY_NAV_MANY = "NavPropertyETKeyNavMany";
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany";
@Test
public void testCreateBindingSimple() throws EdmPrimitiveTypeException {
final ODataClient client = getClient();
final URI createURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build();
final ODataObjectFactory of = client.getObjectFactory();
// Create entity (EntitySet: ESKeyNav, Type: ETKeyNav)
final ODataEntity entity = of.newEntity(ET_KEY_NAV);
entity.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)));
entity.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_ALL_PRIM, of.newComplexValue(CT_ALL_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_COMP, of.newComplexValue(CT_PRIM_COMP)
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))))));
// Bind existing entities via binding synatx
final ODataLink navLinkOne =
of.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(
ES_KEY_NAV).appendKeySegment(1).build());
final ODataLink navLinkMany1 =
of.newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(
ES_KEY_NAV).appendKeySegment(2).build());
final ODataLink navLinkMany2 =
of.newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(
ES_KEY_NAV).appendKeySegment(3).build());
final HashMap<String, Object> combinedKey = new HashMap<String, Object>();
combinedKey.put(PROPERTY_INT16, 1);
combinedKey.put(PROPERTY_STRING, "1");
final ODataLink navLink2Many =
of.newEntitySetNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(combinedKey).build());
entity.addLink(navLinkOne);
entity.addLink(navLinkMany1);
entity.addLink(navLinkMany2);
entity.addLink(navLink2Many);
final ODataEntityCreateResponse<ODataEntity> createResponse =
client.getCUDRequestFactory().getEntityCreateRequest(createURI, entity).execute();
final String cookie = createResponse.getHeader(HttpHeader.SET_COOKIE).iterator().next();
final Short entityInt16Key =
createResponse.getBody().getProperty(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class);
// Check the just created entity
final URI entityGetURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(entityInt16Key).expand(
NAV_PROPERTY_ET_KEY_NAV_ONE, NAV_PROPERTY_ET_KEY_NAV_MANY, NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).build();
final ODataEntityRequest<ODataEntity> entityGetRequest =
client.getRetrieveRequestFactory().getEntityRequest(entityGetURI);
entityGetRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
final ODataRetrieveResponse<ODataEntity> entityGetResponse = entityGetRequest.execute();
// NAV_PROPERTY_ET_KEY_NAV_ONE
assertEquals(1, entityGetResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(
PROPERTY_INT16).getPrimitiveValue().toValue());
// NAV_PROPERTY_ET_KEY_NAV_MANY(0)
Iterator<ODataValue> iterator =
entityGetResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_MANY).getCollectionValue().iterator();
assertEquals(2, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
// NAV_PROPERTY_ET_KEY_NAV_MANY(1)
assertEquals(3, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
// NAV_PROPERTY_ET_TWO_KEY_NAV_MANY(0)
assertEquals(1, entityGetResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).getCollectionValue()
.iterator().next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals("1", entityGetResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).getCollectionValue()
.iterator().next().asComplex().get(PROPERTY_STRING).getPrimitiveValue().toValue());
// Check if partner navigation link has been set up
final URI etTwoKeyNavEntityURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(combinedKey).expand(
NAV_PROPERTY_ET_KEY_NAV_ONE).build();
final ODataEntityRequest<ODataEntity> etTwoKeyNavEntityRequest =
client.getRetrieveRequestFactory().getEntityRequest(etTwoKeyNavEntityURI);
etTwoKeyNavEntityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
final ODataRetrieveResponse<ODataEntity> etTwoKeyNavEntityResponse = etTwoKeyNavEntityRequest.execute();
assertEquals(entityInt16Key, etTwoKeyNavEntityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE)
.getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class));
}
@Test
public void testUpdateBinding() {
// The entity MUST NOT contain related entities as inline content. It MAY contain binding information
// for navigation properties. For single-valued navigation properties this replaces the relationship.
// For collection-valued navigation properties this adds to the relationship.
final ODataClient client = getClient();
final URI entityURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(1).build();
final ODataObjectFactory of = client.getObjectFactory();
// ESKeyNav(1).NavPropertyETKeyNavOne = ESKeyNav(2)
// ESKeyNav(1).NavPropertyETKeyNavMany = { ESKeyNav(1), ESKeyNav(2) }
// => Replace NavPropertyETKeyNavOne with ESKeyNav(3)
// => Add to NavPropertyETKeyNavOne ESKeyNav(3)
final ODataEntity entity = of.newEntity(ET_KEY_NAV);
final ODataLink navLinkOne =
of.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(3).build());
final ODataLink navLinkMany =
of.newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(3).build());
entity.addLink(navLinkOne);
entity.addLink(navLinkMany);
final ODataEntityUpdateResponse<ODataEntity> updateResponse =
client.getCUDRequestFactory().getEntityUpdateRequest(entityURI, UpdateType.PATCH, entity).execute();
final String cookie = updateResponse.getHeader(HttpHeader.SET_COOKIE).iterator().next();
// Check if update was successful
final URI entityGetURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(1).expand(
NAV_PROPERTY_ET_KEY_NAV_ONE, NAV_PROPERTY_ET_KEY_NAV_MANY).build();
final ODataEntityRequest<ODataEntity> entityRequest =
client.getRetrieveRequestFactory().getEntityRequest(entityGetURI);
entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
final ODataRetrieveResponse<ODataEntity> entityResponse = entityRequest.execute();
assertEquals(3, entityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(
PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals(3, entityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_MANY).getCollectionValue().size());
Iterator<ODataValue> iterator =
entityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_MANY).getCollectionValue().iterator();
assertEquals(1, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals(2, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
assertEquals(3, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
}
@Override
protected ODataClient getClient() {
ODataClient odata = ODataClientFactory.getV4();
odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON);
return odata;
}
}

View File

@ -0,0 +1,360 @@
/*
* 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.assertNotNull;
import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
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.domain.ODataInlineEntity;
import org.apache.olingo.commons.api.domain.ODataInlineEntitySet;
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;
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.AfterClass;
import org.junit.Test;
public class DeepInsertITCase extends AbstractBaseTestITCase {
private static final String SERVICE_URI = TecSvcConst.BASE_URI;
private static final String SERVICE_NAMESPACE = "olingo.odata.test1";
private static final String ES_KEY_NAV = "ESKeyNav";
private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
private static final String ET_KEY_NAV_NAME = "ETKeyNav";
private static final String ET_TWO_KEY_NAV_NAME = "ETTwoKeyNav";
private static final FullQualifiedName ET_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_KEY_NAV_NAME);
private static final FullQualifiedName ET_TWO_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_TWO_KEY_NAV_NAME);
private static final String CT_PRIM_COMP = "CTPrimComp";
private static final String CT_TWO_PRIM = "CTTwoPrim";
private static final String CT_ALL_PRIM = "CTAllPrim";
private static final String CT_NAV_FIVE_PROP = "CTNavFiveProp";
private static final String PROPERTY_INT16 = "PropertyInt16";
private static final String PROPERTY_STRING = "PropertyString";
private static final String PROPERTY_COMP = "PropertyComp";
private static final String PROPERTY_COMP_COMP = "PropertyCompComp";
private static final String PROPERTY_COMP_TWO_PRIM = "PropertyCompTwoPrim";
private static final String PROPERTY_COMP_ALL_PRIM = "PropertyCompAllPrim";
private static final String NAV_PROPERTY_ET_KEY_NAV_ONE = "NavPropertyETKeyNavOne";
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_ONE = "NavPropertyETTwoKeyNavOne";
private static final String NAV_PROPERTY_ET_TWO_KEY_NAV_MANY = "NavPropertyETTwoKeyNavMany";
@AfterClass
public static void tearDownAfterClass() throws Exception {}
@Test
public void testSimpleDeepInsert() throws EdmPrimitiveTypeException {
final ODataClient client = getClient();
final URI createURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build();
final ODataObjectFactory of = client.getObjectFactory();
final ODataEntity entity = client.getObjectFactory().newEntity(ET_KEY_NAV);
// Prepare entity(EntitySet: ESKeyNav, Type: ETKeyNav)
entity.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)));
entity.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_ALL_PRIM, of.newComplexValue(CT_ALL_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_COMP, of.newComplexValue(CT_PRIM_COMP)
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))))));
// Non collection navigation property
// Create related entity(EntitySet: ESTwoKeyNav, Type: ETTwoKeyNav, Nav. Property: NavPropertyETTwoKeyNavOne)
final ODataEntity inlineEntitySingle = client.getObjectFactory().newEntity(ET_TWO_KEY_NAV);
inlineEntitySingle.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 43)));
inlineEntitySingle.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("43")));
inlineEntitySingle.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431)))));
inlineEntitySingle.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 432)))
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("432")))));
// Collection navigation property
// The navigation property has a partner navigation property named "NavPropertyETKeyNavOne"
// Create related entity(EntitySet: ESTwoKeyNav, Type: NavPropertyETTwoKeyNavMany
final ODataEntity inlineEntityCol1 = client.getObjectFactory().newEntity(ET_TWO_KEY_NAV);
inlineEntityCol1.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 44)));
inlineEntityCol1.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("44")));
inlineEntityCol1.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 441)))));
inlineEntityCol1.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 442)))
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("442")))));
final ODataEntity inlineEntityCol2 = client.getObjectFactory().newEntity(ET_TWO_KEY_NAV);
inlineEntityCol2.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 45)));
inlineEntityCol2.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("45")));
inlineEntityCol2.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_PRIM_COMP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 451)))));
inlineEntityCol2.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 452)))
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("452")))));
final ODataInlineEntity newDeepInsertEntityLink =
of.newDeepInsertEntity(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE, inlineEntitySingle);
final ODataEntitySet newDeepInsertEntitySet = of.newEntitySet();
newDeepInsertEntitySet.getEntities().add(inlineEntityCol1);
newDeepInsertEntitySet.getEntities().add(inlineEntityCol2);
final ODataInlineEntitySet newDeepInsertEntitySetLink =
of.newDeepInsertEntitySet(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY, newDeepInsertEntitySet);
entity.addLink(newDeepInsertEntityLink);
entity.addLink(newDeepInsertEntitySetLink);
// Perform create request
final ODataEntityCreateResponse<ODataEntity> responseCreate = client.getCUDRequestFactory()
.getEntityCreateRequest(createURI, entity)
.execute();
assertEquals(HttpStatusCode.CREATED.getStatusCode(), responseCreate.getStatusCode());
final String cookie = responseCreate.getHeader(HttpHeader.SET_COOKIE).toString();
// Fetch ESKeyNav entity with expand of NavPropertyETTwoKeyNavOne nav. property
ODataProperty propertyInt16 = responseCreate.getBody().getProperty(PROPERTY_INT16);
final URI esKeyNavURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(
propertyInt16.getPrimitiveValue().toValue()).expand(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE,
NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).build();
final ODataEntityRequest<ODataEntity> esKeyNavRequest = client.getRetrieveRequestFactory()
.getEntityRequest(esKeyNavURI);
esKeyNavRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
final ODataRetrieveResponse<ODataEntity> esKeyNavResponse = esKeyNavRequest.execute();
// Check nav. property NavPropertyETTwoKeyNavOne
assertNotNull(esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE));
assertEquals(431, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE).getComplexValue().get(
PROPERTY_COMP).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue());
// Check nav. property NavPropertyETTwoKeyNavMany
assertNotNull(esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY));
assertEquals(2, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).getCollectionValue()
.size());
Iterator<ODataValue> twoKeyNavManyIterator =
esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).getCollectionValue().iterator();
final ODataValue firstTwoKeyNavEnity = twoKeyNavManyIterator.next(); // First entity
assertEquals(441, firstTwoKeyNavEnity.asComplex().get(PROPERTY_COMP).getValue().asComplex().get(
PROPERTY_INT16).getPrimitiveValue().toValue());
final ODataValue secondTwoKeyNavEnity = twoKeyNavManyIterator.next(); // Second entity
assertEquals(451, secondTwoKeyNavEnity.asComplex().get(PROPERTY_COMP).getValue().asComplex().get(
PROPERTY_INT16).getPrimitiveValue().toValue());
// Fetch ESTwoKeyNav entities and check if available and the partner relation have been set up
// Check ESTwoKeyNav(Created via NavPropertyETTwoKeyNavOne)
Map<String, Object> composedKey = new HashMap<String, Object>();
composedKey.put(PROPERTY_INT16, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE)
.getComplexValue().get(PROPERTY_INT16)
.getPrimitiveValue().toValue());
composedKey.put(PROPERTY_STRING, esKeyNavResponse.getBody().getProperty(NAV_PROPERTY_ET_TWO_KEY_NAV_ONE)
.getComplexValue().get(PROPERTY_STRING)
.getPrimitiveValue().toValue());
final URI esTwoKeyNavEntitySingleURI = client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(ES_TWO_KEY_NAV)
.appendKeySegment(composedKey)
.build();
final ODataEntityRequest<ODataEntity> esTwoKeyNavSingleRequest = client.getRetrieveRequestFactory()
.getEntityRequest(esTwoKeyNavEntitySingleURI);
esTwoKeyNavSingleRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
final ODataRetrieveResponse<ODataEntity> esTwoKeyNavSingleResponse = esTwoKeyNavSingleRequest.execute();
assertEquals(431, esTwoKeyNavSingleResponse.getBody().getProperty(PROPERTY_COMP).getComplexValue().get(
PROPERTY_INT16).getPrimitiveValue().toValue());
// Check ESTwoKeyNav(Created via NavPropertyETTwoKeyNavMany(0))
composedKey.clear();
composedKey.put(PROPERTY_INT16, firstTwoKeyNavEnity.asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
composedKey.put(PROPERTY_STRING, firstTwoKeyNavEnity.asComplex().get(PROPERTY_STRING).getPrimitiveValue()
.toValue());
URI esTwoKeyNavEntityManyOneURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(composedKey)
.expand(NAV_PROPERTY_ET_KEY_NAV_ONE).build();
final ODataEntityRequest<ODataEntity> esTwoKeyNavManyOneRequest =
client.getRetrieveRequestFactory().getEntityRequest(esTwoKeyNavEntityManyOneURI);
esTwoKeyNavManyOneRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
final ODataRetrieveResponse<ODataEntity> esTwoKeyNavManyOneResponse = esTwoKeyNavManyOneRequest.execute();
assertEquals(441, esTwoKeyNavManyOneResponse.getBody().getProperty(PROPERTY_COMP).getComplexValue().get(
PROPERTY_INT16).getPrimitiveValue().toValue());
assertNotNull(esTwoKeyNavManyOneResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue());
assertEquals(propertyInt16.getPrimitiveValue().toValue(), esTwoKeyNavManyOneResponse.getBody().getProperty(
NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue());
// Check ESTwoKeyNav(Created via NavPropertyETTwoKeyNavMany(1))
composedKey.clear();
composedKey.put(PROPERTY_INT16, secondTwoKeyNavEnity.asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue());
composedKey.put(PROPERTY_STRING, secondTwoKeyNavEnity.asComplex().get(PROPERTY_STRING).getPrimitiveValue()
.toValue());
URI esTwoKeyNavEntityManyTwoURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_TWO_KEY_NAV).appendKeySegment(composedKey)
.expand(NAV_PROPERTY_ET_KEY_NAV_ONE).build();
final ODataEntityRequest<ODataEntity> esTwoKeyNavManyTwoRequest =
client.getRetrieveRequestFactory().getEntityRequest(esTwoKeyNavEntityManyTwoURI);
esTwoKeyNavManyTwoRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
final ODataRetrieveResponse<ODataEntity> esTwoKeyNavManyTwoResponse = esTwoKeyNavManyTwoRequest.execute();
assertEquals(451, esTwoKeyNavManyTwoResponse.getBody().getProperty(PROPERTY_COMP).getComplexValue().get(
PROPERTY_INT16).getPrimitiveValue().toValue());
assertNotNull(esTwoKeyNavManyTwoResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue());
assertEquals(propertyInt16.getPrimitiveValue().toValue(), esTwoKeyNavManyTwoResponse.getBody().getProperty(
NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue());
}
@Test
public void testDeepInsertSameEntitySet() throws EdmPrimitiveTypeException {
final ODataClient client = getClient();
final URI createURI = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).build();
final ODataObjectFactory of = client.getObjectFactory();
final ODataEntity entity = client.getObjectFactory().newEntity(ET_KEY_NAV);
// Prepare entity(EntitySet: ESKeyNav, Type: ETKeyNav)
entity.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)));
entity.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_ALL_PRIM, of.newComplexValue(CT_ALL_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))));
entity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_COMP, of.newComplexValue(CT_PRIM_COMP)
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("42")))
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 42)))))));
// Prepare inline entity(EntitySet: ESKeyNav, Type: ETKeyNav)
final ODataEntity innerEntity = of.newEntity(ET_KEY_NAV);
innerEntity.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 43)));
innerEntity.getProperties()
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("43")));
innerEntity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431)))));
innerEntity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_ALL_PRIM, of.newComplexValue(CT_ALL_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("431")))));
innerEntity.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_TWO_PRIM, of.newComplexValue(CT_TWO_PRIM)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder().buildInt16((short) 431)))
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("431")))));
innerEntity
.getProperties()
.add(of.newComplexProperty(PROPERTY_COMP_COMP, of.newComplexValue(CT_PRIM_COMP)
.add(of.newPrimitiveProperty(PROPERTY_STRING, of.newPrimitiveValueBuilder().buildString("431")))
.add(of.newComplexProperty(PROPERTY_COMP, of.newComplexValue(CT_NAV_FIVE_PROP)
.add(of.newPrimitiveProperty(PROPERTY_INT16, of.newPrimitiveValueBuilder()
.buildInt16((short) 431)))))));
ODataInlineEntity inlineEntity = of.newDeepInsertEntity(NAV_PROPERTY_ET_KEY_NAV_ONE, innerEntity);
entity.addLink(inlineEntity);
final ODataEntityCreateResponse<ODataEntity> responseCreate =
client.getCUDRequestFactory().getEntityCreateRequest(createURI, entity).execute();
final String cookie = responseCreate.getHeader(HttpHeader.SET_COOKIE).iterator().next();
final Short esKeyNavEntityKey =
responseCreate.getBody().getProperty(PROPERTY_INT16).getPrimitiveValue().toCastValue(Short.class);
// Fetch Entity
URI fetchEntityURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(esKeyNavEntityKey)
.expand(NAV_PROPERTY_ET_KEY_NAV_ONE).build();
ODataEntityRequest<ODataEntity> entityRequest = client.getRetrieveRequestFactory().getEntityRequest(fetchEntityURI);
entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
final ODataRetrieveResponse<ODataEntity> entityResponse = entityRequest.execute();
// Check values
assertEquals(431, entityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(
PROPERTY_COMP).getComplexValue().get(PROPERTY_INT16).getPrimitiveValue().toValue());
Short innerEntityInt16Key =
entityResponse.getBody().getProperty(NAV_PROPERTY_ET_KEY_NAV_ONE).getComplexValue().get(PROPERTY_INT16)
.getPrimitiveValue().toCastValue(Short.class);
final URI innerEntityURI =
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(innerEntityInt16Key)
.build();
final ODataEntityRequest<ODataEntity> innerRequest =
client.getRetrieveRequestFactory().getEntityRequest(innerEntityURI);
innerRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
ODataRetrieveResponse<ODataEntity> innerResponse = innerRequest.execute();
assertEquals(431, innerResponse.getBody().getProperty(PROPERTY_COMP).getComplexValue().get(PROPERTY_INT16)
.getPrimitiveValue().toValue());
}
@Override
protected ODataClient getClient() {
ODataClient odata = ODataClientFactory.getV4();
odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON);
return odata;
}
}

View File

@ -137,12 +137,11 @@ public class OrderBySystemQueryITCase extends AbstractBaseTestITCase {
private ODataRetrieveResponse<ODataEntitySet> sendRequest(String entitySet, String orderByString) { private ODataRetrieveResponse<ODataEntitySet> sendRequest(String entitySet, String orderByString) {
final ODataClient client = getClient(); final ODataClient client = getClient();
String escapedFilterString = escapeFilterString(orderByString);
final URI uri = final URI uri =
client.newURIBuilder(SERVICE_URI) client.newURIBuilder(SERVICE_URI)
.appendEntitySetSegment(entitySet) .appendEntitySetSegment(entitySet)
.orderBy(escapedFilterString) .orderBy(orderByString)
.build(); .build();
ODataEntitySetRequest<ODataEntitySet> request = client.getRetrieveRequestFactory().getEntitySetRequest(uri); ODataEntitySetRequest<ODataEntitySet> request = client.getRetrieveRequestFactory().getEntitySetRequest(uri);
@ -159,10 +158,6 @@ public class OrderBySystemQueryITCase extends AbstractBaseTestITCase {
} }
} }
private String escapeFilterString(String filterString) {
return filterString.replace(" ", "%20");
}
@Override @Override
protected ODataClient getClient() { protected ODataClient getClient() {
ODataClient odata = ODataClientFactory.getV4(); ODataClient odata = ODataClientFactory.getV4();

View File

@ -29,15 +29,15 @@ import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.uri.QueryOption; import org.apache.olingo.client.api.uri.QueryOption;
import org.apache.olingo.client.core.ODataClientFactory; import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.commons.api.domain.CommonODataEntity; import org.apache.olingo.commons.api.domain.ODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataEntitySet; import org.apache.olingo.commons.api.domain.ODataEntitySet;
import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.fit.AbstractBaseTestITCase; import org.apache.olingo.fit.AbstractBaseTestITCase;
import org.apache.olingo.fit.tecsvc.TecSvcConst; import org.apache.olingo.fit.tecsvc.TecSvcConst;
import org.junit.Test; import org.junit.Test;
public class SystemQueryOptionITCas extends AbstractBaseTestITCase { public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
private static final String PROPERTY_INT16 = "PropertyInt16"; private static final String PROPERTY_INT16 = "PropertyInt16";
private static final String ES_SERVER_SIDE_PAGING = "ESServerSidePaging"; private static final String ES_SERVER_SIDE_PAGING = "ESServerSidePaging";
private static final String ES_ALL_PRIM = "ESAllPrim"; private static final String ES_ALL_PRIM = "ESAllPrim";
@ -51,7 +51,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.addQueryOption(QueryOption.COUNT, "true") .addQueryOption(QueryOption.COUNT, "true")
.build(); .build();
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
@ -67,7 +67,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.addQueryOption(QueryOption.COUNT, "true") .addQueryOption(QueryOption.COUNT, "true")
.build(); .build();
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
@ -83,14 +83,14 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.addQueryOption(QueryOption.TOP, new Integer(5).toString()) .addQueryOption(QueryOption.TOP, new Integer(5).toString())
.build(); .build();
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
assertEquals(5, response.getBody().getEntities().size()); assertEquals(5, response.getBody().getEntities().size());
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
CommonODataEntity entity = response.getBody().getEntities().get(i); ODataEntity entity = response.getBody().getEntities().get(i);
assertEquals(new Integer(i + 1).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString()); assertEquals(new Integer(i + 1).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
} }
} }
@ -103,14 +103,14 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.addQueryOption(QueryOption.SKIP, new Integer(5).toString()) .addQueryOption(QueryOption.SKIP, new Integer(5).toString())
.build(); .build();
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
assertEquals(10, response.getBody().getEntities().size()); assertEquals(10, response.getBody().getEntities().size());
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
CommonODataEntity entity = response.getBody().getEntities().get(i); ODataEntity entity = response.getBody().getEntities().get(i);
assertEquals(new Integer(i + 6).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString()); assertEquals(new Integer(i + 6).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
} }
} }
@ -124,7 +124,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.addQueryOption(QueryOption.SKIP, new Integer(503).toString()) .addQueryOption(QueryOption.SKIP, new Integer(503).toString())
.build(); .build();
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
@ -139,7 +139,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.addQueryOption(QueryOption.SKIP, new Integer(10000).toString()) .addQueryOption(QueryOption.SKIP, new Integer(10000).toString())
.build(); .build();
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
@ -158,7 +158,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.addQueryOption(QueryOption.TOP, new Integer(43).toString()) // 102, 101, ...., 59 .addQueryOption(QueryOption.TOP, new Integer(43).toString()) // 102, 101, ...., 59
.build(); .build();
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
@ -169,7 +169,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
// Check first 10 entities // Check first 10 entities
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
CommonODataEntity entity = response.getBody().getEntities().get(i); ODataEntity entity = response.getBody().getEntities().get(i);
assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString()); assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
id--; id--;
} }
@ -180,7 +180,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
assertEquals(Integer.valueOf(105), response.getBody().getCount()); assertEquals(Integer.valueOf(105), response.getBody().getCount());
assertEquals(10, response.getBody().getEntities().size()); assertEquals(10, response.getBody().getEntities().size());
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
CommonODataEntity entity = response.getBody().getEntities().get(i); ODataEntity entity = response.getBody().getEntities().get(i);
assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString()); assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
id--; id--;
} }
@ -191,7 +191,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
assertEquals(Integer.valueOf(105), response.getBody().getCount()); assertEquals(Integer.valueOf(105), response.getBody().getCount());
assertEquals(3, response.getBody().getEntities().size()); assertEquals(3, response.getBody().getEntities().size());
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
CommonODataEntity entity = response.getBody().getEntities().get(i); ODataEntity entity = response.getBody().getEntities().get(i);
assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString()); assertEquals(new Integer(id).toString(), entity.getProperty(PROPERTY_INT16).getValue().toString());
id--; id--;
} }
@ -207,7 +207,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.appendEntitySetSegment(ES_SERVER_SIDE_PAGING) .appendEntitySetSegment(ES_SERVER_SIDE_PAGING)
.build(); .build();
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
@ -234,7 +234,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.addQueryOption(QueryOption.COUNT, Boolean.TRUE.toString()) .addQueryOption(QueryOption.COUNT, Boolean.TRUE.toString())
.build(); .build();
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
@ -273,7 +273,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.build(); .build();
try { try {
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
fail(); fail();
@ -291,7 +291,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
.addQueryOption(QueryOption.TOP, new Integer(-5).toString()) .addQueryOption(QueryOption.TOP, new Integer(-5).toString())
.build(); .build();
try { try {
ODataRetrieveResponse<CommonODataEntitySet> response = client.getRetrieveRequestFactory() ODataRetrieveResponse<ODataEntitySet> response = client.getRetrieveRequestFactory()
.getEntitySetRequest(uri) .getEntitySetRequest(uri)
.execute(); .execute();
fail(); fail();
@ -301,7 +301,7 @@ public class SystemQueryOptionITCas extends AbstractBaseTestITCase {
} }
@Override @Override
protected CommonODataClient<?> getClient() { protected ODataClient getClient() {
ODataClient odata = ODataClientFactory.getV4(); ODataClient odata = ODataClientFactory.getV4();
odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON); odata.getConfiguration().setDefaultPubFormat(ODataFormat.JSON);
return odata; return odata;

View File

@ -18,8 +18,10 @@
*/ */
package org.apache.olingo.server.tecsvc.data; package org.apache.olingo.server.tecsvc.data;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -29,24 +31,39 @@ import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet; import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.data.Link; import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.domain.ODataLinkType;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmComplexType; import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmStructuredType; import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.data.EntityImpl; 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.commons.core.edm.primitivetype.EdmInt16;
import org.apache.olingo.commons.core.edm.primitivetype.EdmInt32;
import org.apache.olingo.commons.core.edm.primitivetype.EdmInt64;
import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException; import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.api.uri.UriParameter;
public class DataProvider { public class DataProvider {
protected static final String MEDIA_PROPERTY_NAME = "$value"; protected static final String MEDIA_PROPERTY_NAME = "$value";
private static final String KEY_NAME = "PropertyInt16"; // private static final String KEY_NAME = "PropertyInt16";
private Map<String, EntitySet> data; final private Map<String, EntitySet> data;
private Edm edm;
private OData odata;
public DataProvider() { public DataProvider() {
data = new DataCreator().getData(); data = new DataCreator().getData();
@ -116,35 +133,97 @@ public class DataProvider {
} }
} }
// public Entity create(final EdmEntitySet edmEntitySet) throws DataProviderException {
// final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
// List<Entity> entities = readAll(edmEntitySet).getEntities();
// Entity entity = new EntityImpl();
// final List<String> keyNames = edmEntityType.getKeyPredicateNames();
// if (keyNames.size() == 1 && keyNames.get(0).equals(KEY_NAME)) {
// entity.addProperty(DataCreator.createPrimitive(KEY_NAME, findFreeKeyValue(entities)));
// } else {
// throw new DataProviderException("Key construction not supported!");
// }
// createProperties(edmEntityType, entity.getProperties());
// entities.add(entity);
// return entity;
// }
//
// private Integer findFreeKeyValue(final List<Entity> entities) {
// Integer result = 0;
// boolean free;
// do {
// ++result;
// free = true;
// for (final Entity entity : entities) {
// if (result.equals(entity.getProperty(KEY_NAME).getValue())) {
// free = false;
// break;
// }
// }
// } while (!free);
// return result;
// }
public Entity create(final EdmEntitySet edmEntitySet) throws DataProviderException { public Entity create(final EdmEntitySet edmEntitySet) throws DataProviderException {
final EdmEntityType edmEntityType = edmEntitySet.getEntityType(); final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
List<Entity> entities = readAll(edmEntitySet).getEntities(); final EntitySet entitySet = readAll(edmEntitySet);
Entity entity = new EntityImpl(); final List<Entity> entities = entitySet.getEntities();
final List<String> keyNames = edmEntityType.getKeyPredicateNames(); final Map<String, Object> newKey = findFreeComposedKey(entities, edmEntitySet.getEntityType());
if (keyNames.size() == 1 && keyNames.get(0).equals(KEY_NAME)) { final Entity newEntity = new EntityImpl();
entity.addProperty(DataCreator.createPrimitive(KEY_NAME, findFreeKeyValue(entities)));
} else { for (final String keyName : edmEntityType.getKeyPredicateNames()) {
throw new DataProviderException("Key construction not supported!"); newEntity.addProperty(DataCreator.createPrimitive(keyName, newKey.get(keyName)));
} }
createProperties(edmEntityType, entity.getProperties());
entities.add(entity); createProperties(edmEntityType, newEntity.getProperties());
return entity; entities.add(newEntity);
return newEntity;
} }
private Integer findFreeKeyValue(final List<Entity> entities) { private Map<String, Object> findFreeComposedKey(final List<Entity> entities, final EdmEntityType entityType)
Integer result = 0; throws DataProviderException {
boolean free; // Weak key construction
do { // 3e entity: (V k keys: k ! e.ki) => e.(k1, k2, k3) ! entitySet
++result; final HashMap<String, Object> keys = new HashMap<String, Object>();
free = true; for (final String keyName : entityType.getKeyPredicateNames()) {
for (final Entity entity : entities) { final EdmType type = entityType.getProperty(keyName).getType();
if (result.equals(entity.getProperty(KEY_NAME).getValue())) { Object newValue = null;
free = false;
break; if (type instanceof EdmInt16 || type instanceof EdmInt32 || type instanceof EdmInt64) {
// Integer keys
newValue = Integer.valueOf(1);
while (!isFree(newValue, keyName, entities)) {
newValue = ((Integer) newValue) + 1;
} }
} else if (type instanceof EdmString) {
// String keys
newValue = String.valueOf(1);
int i = 0;
while (!isFree(newValue, keyName, entities)) {
newValue = String.valueOf(i);
i++;
}
} else {
throw new DataProviderException("Key type not supported");
} }
} while (!free);
return result; keys.put(keyName, newValue);
}
return keys;
}
private boolean isFree(final Object value, final String keyPropertyName, final List<Entity> entities) {
for (final Entity entity : entities) {
if (value != null && value.equals(entity.getProperty(keyPropertyName).getValue())) {
return false;
}
}
return true;
} }
private void createProperties(final EdmStructuredType type, List<Property> properties) throws DataProviderException { private void createProperties(final EdmStructuredType type, List<Property> properties) throws DataProviderException {
@ -173,10 +252,14 @@ public class DataProvider {
} }
} }
public void update(final EdmEntitySet edmEntitySet, Entity entity, final Entity changedEntity, final boolean patch) public void update(final String rawBaseUri, final EdmEntitySet edmEntitySet, Entity entity,
throws DataProviderException { final Entity changedEntity, final boolean patch,
final boolean isInsert) throws DataProviderException {
final EdmEntityType entityType = edmEntitySet.getEntityType(); final EdmEntityType entityType = edmEntitySet.getEntityType();
final List<String> keyNames = entityType.getKeyPredicateNames(); final List<String> keyNames = entityType.getKeyPredicateNames();
// Update Properties
for (final String propertyName : entityType.getPropertyNames()) { for (final String propertyName : entityType.getPropertyNames()) {
if (!keyNames.contains(propertyName)) { if (!keyNames.contains(propertyName)) {
updateProperty(entityType.getStructuralProperty(propertyName), updateProperty(entityType.getStructuralProperty(propertyName),
@ -185,8 +268,140 @@ public class DataProvider {
patch); patch);
} }
} }
// Deep insert (only if not an update)
if (isInsert) {
handleDeepInsert(rawBaseUri, edmEntitySet, entity, changedEntity);
} else if (isInsert && changedEntity.getNavigationLinks().size() != 0) {
throw new DataProviderException("Deep inserts are not allowed in update operations using PUT or PATCH requests.");
}
if (!changedEntity.getNavigationBindings().isEmpty()) { if (!changedEntity.getNavigationBindings().isEmpty()) {
throw new DataProviderException("Binding operations are not yet supported."); applyNavigationBinding(rawBaseUri, edmEntitySet, entity, changedEntity.getNavigationBindings());
}
}
private void applyNavigationBinding(final String rawBaseUri, final EdmEntitySet edmEntitySet,
final Entity entity, final List<Link> navigationBindings) throws DataProviderException {
for (final Link link : navigationBindings) {
final EdmNavigationProperty edmNavProperty = edmEntitySet.getEntityType().getNavigationProperty(link.getTitle());
final EdmEntitySet edmTargetEntitySet =
(EdmEntitySet) edmEntitySet.getRelatedBindingTarget(edmNavProperty.getName());
if (edmNavProperty.isCollection()) {
for (final String bindingLink : link.getBindingLinks()) {
final Entity destEntity = getEntityByURI(rawBaseUri, edmTargetEntitySet, bindingLink);
createLink(edmNavProperty, entity, destEntity);
}
} else {
final String bindingLink = link.getBindingLink();
final Entity destEntity = getEntityByURI(rawBaseUri, edmTargetEntitySet, bindingLink);
createLink(edmNavProperty, entity, destEntity);
}
}
}
private Entity getEntityByURI(final String rawBaseUri, final EdmEntitySet edmEntitySetTarget,
final String bindingLink) throws DataProviderException {
try {
final List<UriParameter> keys = odata.createUriHelper()
.getKeyPredicatesFromEntityLink(edm, bindingLink, rawBaseUri);
final Entity entity = read(edmEntitySetTarget, keys);
if(entity == null) {
throw new DataProviderException("Entity " + bindingLink + " not found");
}
return entity;
} catch (DeserializerException e) {
throw new DataProviderException("Invalid entity binding link", e);
}
}
private void handleDeepInsert(final String rawBaseUri, final EdmEntitySet edmEntitySet, Entity entity,
final Entity changedEntity)
throws DataProviderException {
final EdmEntityType entityType = edmEntitySet.getEntityType();
for (final String navPropertyName : entityType.getNavigationPropertyNames()) {
final Link navigationLink = changedEntity.getNavigationLink(navPropertyName);
if (navigationLink != null) {
// Deep inserts are not allowed in update operations, so we can be sure, that we do not override
// a navigation link!
final EdmNavigationProperty navigationProperty = entityType.getNavigationProperty(navPropertyName);
final EdmBindingTarget target = edmEntitySet.getRelatedBindingTarget(navPropertyName);
final EdmEntityType inlineEntityType = navigationProperty.getType();
if (navigationProperty.isCollection()) {
final List<Entity> entities =
createInlineEntities(rawBaseUri, target, inlineEntityType, navigationLink.getInlineEntitySet());
for (final Entity inlineEntity : entities) {
createLink(navigationProperty, entity, inlineEntity);
}
} else {
final Entity inlineEntity =
createInlineEntity(rawBaseUri, target, inlineEntityType, navigationLink.getInlineEntity());
createLink(navigationProperty, entity, inlineEntity);
}
}
}
}
private List<Entity> createInlineEntities(final String rawBaseUri, final EdmBindingTarget target,
final EdmEntityType type, final EntitySet changedEntitsSet) throws DataProviderException {
List<Entity> entities = new ArrayList<Entity>();
for (final Entity newEntity : changedEntitsSet.getEntities()) {
entities.add(createInlineEntity(rawBaseUri, target, type, newEntity));
}
return entities;
}
private Entity createInlineEntity(final String rawBaseUri, final EdmBindingTarget target,
final EdmEntityType type, final Entity changedEntity) throws DataProviderException {
final Entity inlineEntity = create((EdmEntitySet) target);
update(rawBaseUri, (EdmEntitySet) target, inlineEntity, changedEntity, false, true);
return inlineEntity;
}
private void createLink(final EdmNavigationProperty navigationProperty, final Entity srcEntity,
final Entity destEntity) {
setLink(navigationProperty, srcEntity, destEntity);
final EdmNavigationProperty partnerNavigationProperty = navigationProperty.getPartner();
if (partnerNavigationProperty != null) {
setLink(partnerNavigationProperty, destEntity, srcEntity);
}
}
// TODO Duplicated code in DataCreator
private void setLink(final EdmNavigationProperty navigationProperty, final Entity srcEntity,
final Entity destEntity) {
Link link = srcEntity.getNavigationLink(navigationProperty.getName());
if (link == null) {
link = new LinkImpl();
link.setTitle(navigationProperty.getName());
srcEntity.getNavigationLinks().add(link);
}
if (navigationProperty.isCollection()) {
if (link.getInlineEntitySet() == null) {
link.setType(ODataLinkType.ENTITY_SET_NAVIGATION.toString());
link.setInlineEntitySet(new EntitySetImpl());
}
link.getInlineEntitySet().getEntities().add(destEntity);
} else {
link.setType(ODataLinkType.ENTITY_NAVIGATION.toString());
link.setInlineEntity(destEntity);
} }
} }
@ -238,6 +453,14 @@ public class DataProvider {
entity.setMediaContentType(type); entity.setMediaContentType(type);
} }
public void setEdm(final Edm edm) {
this.edm = edm;
}
public void setOData(final OData odata) {
this.odata = odata;
}
public static class DataProviderException extends ODataApplicationException { public static class DataProviderException extends ODataApplicationException {
private static final long serialVersionUID = 5098059649321796156L; private static final long serialVersionUID = 5098059649321796156L;

View File

@ -53,8 +53,12 @@ import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption; import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.SelectOption; import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.tecsvc.data.DataProvider; import org.apache.olingo.server.tecsvc.data.DataProvider;
import org.apache.olingo.server.tecsvc.processor.queryoptions.SystemQueryOptions; 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;
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.ServerSidePagingHandler; import org.apache.olingo.server.tecsvc.processor.queryoptions.options.ServerSidePagingHandler;
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.SkipHandler;
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.TopHandler;
/** /**
* Technical Processor for entity-related functionality. * Technical Processor for entity-related functionality.
@ -83,8 +87,16 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
entitySet.getEntities().addAll(entitySetInitial.getEntities()); entitySet.getEntities().addAll(entitySetInitial.getEntities());
// Apply system query options // Apply system query options
SystemQueryOptions.applySystemQueryOptions(entitySet, edmEntitySet, uriInfo); FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, edmEntitySet);
ServerSidePagingHandler.applyServerSidePaging(entitySet, request.getRawRequestUri(), uriInfo); CountHandler.applyCountSystemQueryOption(uriInfo.getCountOption(), entitySet);
OrderByHandler.applyOrderByOption(uriInfo.getOrderByOption(), entitySet, edmEntitySet);
SkipHandler.applySkipSystemQueryHandler(uriInfo.getSkipOption(), entitySet);
TopHandler.applyTopSystemQueryOption(uriInfo.getTopOption(), entitySet);
ServerSidePagingHandler.applyServerSidePaging(uriInfo.getSkipTokenOption(),
entitySet,
edmEntitySet,
request.getRawRequestUri());
final ODataFormat format = ODataFormat.fromContentType(requestedContentType); final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
ODataSerializer serializer = odata.createSerializer(format); ODataSerializer serializer = odata.createSerializer(format);
@ -114,7 +126,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
public void countEntityCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo) public void countEntityCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
throws ODataApplicationException, SerializerException { throws ODataApplicationException, SerializerException {
validateOptions(uriInfo.asUriInfoResource()); validateOptions(uriInfo.asUriInfoResource());
getEdmEntitySet(uriInfo); // including checks getEdmEntitySet(uriInfo); // including checks
EntitySet entitySet = readEntityCollection(uriInfo); EntitySet entitySet = readEntityCollection(uriInfo);
if (entitySet == null) { if (entitySet == null) {
throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT); throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
@ -150,7 +162,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
@Override @Override
public void readMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, public void readMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType responseFormat) throws ODataApplicationException, SerializerException { final ContentType responseFormat) throws ODataApplicationException, SerializerException {
getEdmEntitySet(uriInfo); // including checks getEdmEntitySet(uriInfo); // including checks
final Entity entity = readEntity(uriInfo); final Entity entity = readEntity(uriInfo);
response.setContent(odata.createFixedFormatSerializer().binary(dataProvider.readMedia(entity))); response.setContent(odata.createFixedFormatSerializer().binary(dataProvider.readMedia(entity)));
response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setStatusCode(HttpStatusCode.OK.getStatusCode());
@ -167,7 +179,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
@Override @Override
public void createEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, public void createEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestFormat, final ContentType responseFormat) final ContentType requestFormat, final ContentType responseFormat)
throws ODataApplicationException, DeserializerException, SerializerException { throws ODataApplicationException, DeserializerException, SerializerException {
if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) { if (uriInfo.asUriInfoResource().getUriResourceParts().size() > 1) {
throw new ODataApplicationException("Invalid resource type.", throw new ODataApplicationException("Invalid resource type.",
HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
@ -182,10 +194,10 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()), dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
requestFormat.toContentTypeString()); requestFormat.toContentTypeString());
} else { } else {
dataProvider.update(edmEntitySet, entity, dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity,
odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
.entity(request.getBody(), edmEntityType), .entity(request.getBody(), edmEntityType),
false); false, true);
} }
final ODataFormat format = ODataFormat.fromContentType(responseFormat); final ODataFormat format = ODataFormat.fromContentType(responseFormat);
@ -204,21 +216,22 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
@Override @Override
public void updateEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, public void updateEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
final ContentType requestFormat, final ContentType responseFormat) final ContentType requestFormat, final ContentType responseFormat)
throws ODataApplicationException, DeserializerException, SerializerException { throws ODataApplicationException, DeserializerException, SerializerException {
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo); final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
Entity entity = readEntity(uriInfo); Entity entity = readEntity(uriInfo);
checkRequestFormat(requestFormat); checkRequestFormat(requestFormat);
ODataDeserializer deserializer = odata.createDeserializer(ODataFormat.fromContentType(requestFormat)); ODataDeserializer deserializer = odata.createDeserializer(ODataFormat.fromContentType(requestFormat));
final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType()); final Entity changedEntity = deserializer.entity(request.getBody(), edmEntitySet.getEntityType());
dataProvider.update(edmEntitySet, entity, changedEntity, request.getMethod() == HttpMethod.PATCH); dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, changedEntity,
request.getMethod() == HttpMethod.PATCH, false);
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
} }
@Override @Override
public void updateMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, public void updateMediaEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
final ContentType requestFormat, final ContentType responseFormat) final ContentType requestFormat, final ContentType responseFormat)
throws ODataApplicationException, DeserializerException, SerializerException { throws ODataApplicationException, DeserializerException, SerializerException {
getEdmEntitySet(uriInfo); // including checks getEdmEntitySet(uriInfo); // including checks
Entity entity = readEntity(uriInfo); Entity entity = readEntity(uriInfo);
checkRequestFormat(requestFormat); checkRequestFormat(requestFormat);
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()), dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
@ -244,7 +257,6 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
} }
private void setCount(EntitySet entitySet) { private void setCount(EntitySet entitySet) {
// TODO: set count (correctly) and next link
if (entitySet.getCount() == null) { if (entitySet.getCount() == null) {
entitySet.setCount(entitySet.getEntities().size()); entitySet.setCount(entitySet.getEntities().size());
} }

View File

@ -46,6 +46,7 @@ public abstract class TechnicalProcessor implements Processor {
protected OData odata; protected OData odata;
protected DataProvider dataProvider; protected DataProvider dataProvider;
protected ServiceMetadata serviceMetadata;
protected TechnicalProcessor(final DataProvider dataProvider) { protected TechnicalProcessor(final DataProvider dataProvider) {
this.dataProvider = dataProvider; this.dataProvider = dataProvider;
@ -54,6 +55,9 @@ public abstract class TechnicalProcessor implements Processor {
@Override @Override
public void init(final OData odata, final ServiceMetadata serviceMetadata) { public void init(final OData odata, final ServiceMetadata serviceMetadata) {
this.odata = odata; this.odata = odata;
this.serviceMetadata = serviceMetadata;
this.dataProvider.setOData(odata);
this.dataProvider.setEdm(serviceMetadata.getEdm());
} }
protected EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException { protected EdmEntitySet getEdmEntitySet(final UriInfoResource uriInfo) throws ODataApplicationException {

View File

@ -1,41 +0,0 @@
/*
* 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 org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriInfo;
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;
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.SkipHandler;
import org.apache.olingo.server.tecsvc.processor.queryoptions.options.TopHandler;
public class SystemQueryOptions {
public static void applySystemQueryOptions(final EntitySet entitySet, final EdmEntitySet edmEntitySet,
final UriInfo uriInfo) throws ODataApplicationException {
FilterHandler.applyFilterSystemQuery(uriInfo.getFilterOption(), entitySet, edmEntitySet);
CountHandler.applyCountSystemQueryOption(uriInfo.getCountOption(), entitySet);
OrderByHandler.applyOrderByOption(uriInfo.getOrderByOption(), entitySet, edmEntitySet);
SkipHandler.applySkipSystemQueryHandler(uriInfo.getSkipOption(), entitySet);
TopHandler.applyTopSystemQueryOption(uriInfo.getTopOption(), entitySet);
}
}

View File

@ -27,5 +27,4 @@ public class CountHandler {
entitySet.setCount(entitySet.getEntities().size()); entitySet.setCount(entitySet.getEntities().size());
} }
} }
} }

View File

@ -31,7 +31,6 @@ import org.apache.olingo.server.api.uri.queryoption.OrderByItem;
import org.apache.olingo.server.api.uri.queryoption.OrderByOption; import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException; import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitException;
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.ExpressionVisitorImpl; import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.ExpressionVisitorImpl;
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.FilterRuntimeException;
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand.TypedOperand; import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand.TypedOperand;
public class OrderByHandler { public class OrderByHandler {
@ -44,7 +43,7 @@ public class OrderByHandler {
try { try {
applyOrderByOptionInternal(orderByOption, entitySet, edmEntitySet); applyOrderByOptionInternal(orderByOption, entitySet, edmEntitySet);
} catch (FilterRuntimeException e) { } catch (SystemQueryOptionsRuntimeException e) {
if (e.getCause() instanceof ODataApplicationException) { if (e.getCause() instanceof ODataApplicationException) {
// Throw the nested exception, to send the correct HTTP status code in the HTTP response // Throw the nested exception, to send the correct HTTP status code in the HTTP response
throw (ODataApplicationException) e.getCause(); throw (ODataApplicationException) e.getCause();
@ -93,9 +92,9 @@ public class OrderByHandler {
result = item.isDescending() ? result * -1 : result; result = item.isDescending() ? result * -1 : result;
} catch (ODataApplicationException e) { } catch (ODataApplicationException e) {
throw new FilterRuntimeException(e); throw new SystemQueryOptionsRuntimeException(e);
} catch (ExpressionVisitException e) { } catch (ExpressionVisitException e) {
throw new FilterRuntimeException(e); throw new SystemQueryOptionsRuntimeException(e);
} }
} }
return result; return result;

View File

@ -23,22 +23,23 @@ import java.net.URISyntaxException;
import java.util.Locale; import java.util.Locale;
import org.apache.olingo.commons.api.data.EntitySet; import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.Encoder; import org.apache.olingo.commons.core.Encoder;
import org.apache.olingo.server.api.ODataApplicationException; import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.queryoption.SkipTokenOption; import org.apache.olingo.server.api.uri.queryoption.SkipTokenOption;
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind; import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
public class ServerSidePagingHandler { public class ServerSidePagingHandler {
private static final int MAX_PAGE_SIZE = 10; private static final int MAX_PAGE_SIZE = 10;
private static final String ES_SERVER_SIDE_PAGING = "ESServerSidePaging";
public static void public static void applyServerSidePaging(final SkipTokenOption skipTokenOption, final EntitySet entitySet,
applyServerSidePaging(final EntitySet entitySet, final String rawRequestUri, final UriInfo uriInfo) final EdmEntitySet edmEntitySet, final String rawRequestUri) throws ODataApplicationException {
throws ODataApplicationException {
if (shouldApplyServerSidePaging(entitySet)) { if (shouldApplyServerSidePaging(edmEntitySet)) {
final int maxPageSize = getMaxPageSize(); final int maxPageSize = getMaxPageSize();
final int page = getPage(uriInfo.getSkipTokenOption()); final int page = getPage(skipTokenOption);
final int itemsToSkip = maxPageSize * page; final int itemsToSkip = maxPageSize * page;
if (itemsToSkip <= entitySet.getEntities().size()) { if (itemsToSkip <= entitySet.getEntities().size()) {
@ -48,16 +49,15 @@ public class ServerSidePagingHandler {
// Determine if a new next Link has to be provided // Determine if a new next Link has to be provided
if (remainingItems > maxPageSize) { if (remainingItems > maxPageSize) {
entitySet.setNext(createNextLink(uriInfo, rawRequestUri, page + 1)); entitySet.setNext(createNextLink(rawRequestUri, page + 1));
} }
} else { } else {
throw new ODataApplicationException("Invalid skiptoken", HttpStatusCode.BAD_REQUEST.getStatusCode(), throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
Locale.ROOT);
} }
} }
} }
private static URI createNextLink(final UriInfo uriInfo, final String rawRequestUri, final Integer page) private static URI createNextLink(final String rawRequestUri, final Integer page)
throws ODataApplicationException { throws ODataApplicationException {
try { try {
@ -99,8 +99,8 @@ public class ServerSidePagingHandler {
} }
} }
private static boolean shouldApplyServerSidePaging(final EntitySet entitySet) { private static boolean shouldApplyServerSidePaging(final EdmEntitySet edmEntitySet) {
return true; return ES_SERVER_SIDE_PAGING.equals(edmEntitySet.getName());
} }
private static int getMaxPageSize() { private static int getMaxPageSize() {

View File

@ -16,23 +16,15 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.apache.olingo.server.tecsvc.processor.queryoptions.expression; package org.apache.olingo.server.tecsvc.processor.queryoptions.options;
import org.apache.olingo.commons.api.ODataRuntimeException; import org.apache.olingo.commons.api.ODataRuntimeException;
public class FilterRuntimeException extends ODataRuntimeException { public class SystemQueryOptionsRuntimeException extends ODataRuntimeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public FilterRuntimeException(Exception cause) { public SystemQueryOptionsRuntimeException(Exception cause) {
super(cause); super(cause);
} }
public FilterRuntimeException(String msg, Exception cause) {
super(msg, cause);
}
public FilterRuntimeException(String msg) {
super(msg);
}
} }