[OLINGO-438] Added count support for entity set

This commit is contained in:
Michael Bolz 2014-10-01 10:15:25 +02:00
parent ad3fbfb4cb
commit aac77f05ae
6 changed files with 112 additions and 2 deletions

View File

@ -29,11 +29,19 @@ import org.apache.olingo.server.api.uri.UriInfo;
public interface EntityCollectionProcessor extends Processor {
/**
* Reads entities data from persistency and puts serialized content and status into the response.
* Reads entities data from persistence and puts serialized content and status into the response.
* @param request - OData request object containing raw HTTP information
* @param response - OData response object for collecting response data
* @param uriInfo - information of a parsed OData URI
* @param requestedContentType - requested content type after content negotiation
*/
void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestedContentType);
/**
* Count entities from persistence and puts serialized content and status into the response.
* @param request - OData request object containing raw http information.
* @param response - OData response object for collecting response data
* @param uriInfo - information of a parsed OData uri
*/
void countCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo);
}

View File

@ -227,6 +227,15 @@ public class ODataHandler {
}
}
break;
case count:
if (request.getMethod().equals(HttpMethod.GET)) {
EntityCollectionProcessor cp = selectProcessor(EntityCollectionProcessor.class);
cp.countCollection(request, response, uriInfo);
} else {
throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
}
break;
default:
throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);

View File

@ -521,6 +521,7 @@ public class UriValidator {
UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
switch (secondLastPathSegment.getKind()) {
case entitySet:
case navigationProperty:
idx = RowIndexForUriType.entitySetCount;
break;
case complexProperty:

View File

@ -230,5 +230,10 @@ public class ContentNegotiatorTest {
final ContentType requestedContentType) {
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
}
@Override
public void countCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo) {
response.setHeader(HttpHeader.CONTENT_TYPE, ContentType.TEXT_PLAIN.toContentTypeString());
}
}
}

View File

@ -43,8 +43,10 @@ import org.apache.olingo.server.api.uri.UriResource;
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.SelectOption;
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
import org.apache.olingo.server.tecsvc.data.DataProvider;
import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Locale;
@ -134,9 +136,54 @@ public class TechnicalProcessor implements EntityCollectionProcessor, EntityProc
}
}
@Override
public void countCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo) {
try {
EntitySet entitySet = null;
final UriInfoResource uriResource = uriInfo.asUriInfoResource();
final List<UriResource> resourceParts = uriResource.getUriResourceParts();
if(isCount(resourceParts)) {
int pos = resourceParts.size() - 2;
if(pos >= 0) {
final UriResourceEntitySet ur =
(UriResourceEntitySet) uriResource.getUriResourceParts().get(pos);
entitySet = readEntitySetInternal(ur.getEntitySet(), true);
}
}
if (entitySet == null) {
response.setStatusCode(HttpStatusCode.NOT_FOUND.getStatusCode());
} else {
Integer count = entitySet.getCount();
response.setContent(new ByteArrayInputStream(count.toString().getBytes()));
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, "text/plain");
}
} catch (final DataProvider.DataProviderException e) {
response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
}
}
private boolean isCount(List<UriResource> resourceParts) {
if(resourceParts.isEmpty()) {
return false;
}
UriResource part = resourceParts.get(resourceParts.size() - 1);
return SystemQueryOptionKind.COUNT.toString().equals(part.toString());
}
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet) throws DataProvider.DataProviderException {
return readEntitySetInternal(edmEntitySet, false);
}
private EntitySet readEntitySetInternal(final EdmEntitySet edmEntitySet,
boolean withCount) throws DataProvider.DataProviderException {
EntitySet entitySet = dataProvider.readAll(edmEntitySet);
// TODO: set count and next link
// TODO: set count (correctly) and next link
if(withCount && entitySet.getCount() == null) {
entitySet.setCount(entitySet.getEntities().size());
}
//
return entitySet;
}

View File

@ -35,11 +35,14 @@ import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
import org.apache.olingo.server.api.processor.MetadataProcessor;
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
public class ODataHandlerTest {
@ -238,4 +241,41 @@ public class ODataHandlerTest {
assertEquals(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), response.getStatusCode());
}
@Test
public void testCount() throws Exception {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.GET);
request.setRawODataPath("ESAllPrim/$count");
EntityCollectionProcessor processor = mock(EntityCollectionProcessor.class);
handler.register(processor);
ODataResponse response = handler.process(request);
assertNotNull(response);
Mockito.verify(processor).countCollection(
Mockito.eq(request),
Mockito.any(ODataResponse.class),
Mockito.any(UriInfo.class));
}
@Test
public void testCountWithNavigation() throws Exception {
ODataRequest request = new ODataRequest();
request.setMethod(HttpMethod.GET);
request.setRawODataPath("ESAllPrim/NavPropertyETTwoPrimMany/$count");
EntityCollectionProcessor processor = mock(EntityCollectionProcessor.class);
handler.register(processor);
ODataResponse response = handler.process(request);
assertNotNull(response);
Mockito.verify(processor).countCollection(
Mockito.eq(request),
Mockito.any(ODataResponse.class),
Mockito.any(UriInfo.class));
}
}