From 91c2f6a45104f13559c429ef902a42f2de8d7550 Mon Sep 17 00:00:00 2001 From: Klaus Straubinger Date: Thu, 28 May 2015 16:44:24 +0200 Subject: [PATCH] [OLINGO-675] inheritance of action processors removed Signed-off-by: Christian Amend --- .../ActionComplexCollectionProcessor.java | 2 +- .../api/processor/ActionComplexProcessor.java | 2 +- .../ActionEntityCollectionProcessor.java | 2 +- .../api/processor/ActionEntityProcessor.java | 2 +- .../ActionPrimitiveCollectionProcessor.java | 2 +- .../processor/ActionPrimitiveProcessor.java | 2 +- .../server/tecsvc/TechnicalServlet.java | 4 +- .../processor/TechnicalActionProcessor.java | 315 ++++++++++++++++++ .../processor/TechnicalEntityProcessor.java | 159 ++------- .../TechnicalPrimitiveComplexProcessor.java | 154 +-------- 10 files changed, 355 insertions(+), 289 deletions(-) create mode 100644 lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionComplexCollectionProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionComplexCollectionProcessor.java index 80b10ffd1..88003c98c 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionComplexCollectionProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionComplexCollectionProcessor.java @@ -29,7 +29,7 @@ import org.apache.olingo.server.api.uri.UriInfo; /** * Processor interface for handling an action request with a return type of ComplexCollection. */ -public interface ActionComplexCollectionProcessor extends ComplexCollectionProcessor { +public interface ActionComplexCollectionProcessor extends Processor { /** * Process an action which has as return type a complex-type collection. * @param request OData request object containing raw HTTP information diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionComplexProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionComplexProcessor.java index 20f32669c..6c25059a8 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionComplexProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionComplexProcessor.java @@ -29,7 +29,7 @@ import org.apache.olingo.server.api.uri.UriInfo; /** * Processor interface for handling an action request with a return type of Complex. */ -public interface ActionComplexProcessor extends ComplexProcessor { +public interface ActionComplexProcessor extends Processor { /** * Process an action which has as return type a complex type. * @param request OData request object containing raw HTTP information diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionEntityCollectionProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionEntityCollectionProcessor.java index f51f5a82a..1e5a122e2 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionEntityCollectionProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionEntityCollectionProcessor.java @@ -29,7 +29,7 @@ import org.apache.olingo.server.api.uri.UriInfo; /** * Processor interface for handling an action request with a return type of Entity Collection. */ -public interface ActionEntityCollectionProcessor extends EntityCollectionProcessor { +public interface ActionEntityCollectionProcessor extends Processor { /** * Process an action which has as return type a collection of entities. * @param request OData request object containing raw HTTP information diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionEntityProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionEntityProcessor.java index 236dffe08..117c2caa0 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionEntityProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionEntityProcessor.java @@ -29,7 +29,7 @@ import org.apache.olingo.server.api.uri.UriInfo; /** * Processor interface for handling an action request with a return type of Entity. */ -public interface ActionEntityProcessor extends EntityProcessor { +public interface ActionEntityProcessor extends Processor { /** * Process an action which has as return type an entity. * @param request OData request object containing raw HTTP information diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionPrimitiveCollectionProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionPrimitiveCollectionProcessor.java index 01e2c54ea..35ef6c949 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionPrimitiveCollectionProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionPrimitiveCollectionProcessor.java @@ -29,7 +29,7 @@ import org.apache.olingo.server.api.uri.UriInfo; /** * Processor interface for handling an action request with a return type of Primitive Collection. */ -public interface ActionPrimitiveCollectionProcessor extends PrimitiveCollectionProcessor { +public interface ActionPrimitiveCollectionProcessor extends Processor { /** * Process an action which has as return type a primitive-type collection. * @param request OData request object containing raw HTTP information diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionPrimitiveProcessor.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionPrimitiveProcessor.java index df0fdf960..40f3f4e32 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionPrimitiveProcessor.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/processor/ActionPrimitiveProcessor.java @@ -29,7 +29,7 @@ import org.apache.olingo.server.api.uri.UriInfo; /** * Processor interface for handling an action request with a return type of Primitive. */ -public interface ActionPrimitiveProcessor extends PrimitiveProcessor { +public interface ActionPrimitiveProcessor extends Processor { /** * Process an action which has as return type a primitive-type. * @param request OData request object containing raw HTTP information diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java index 0412c8057..a96f585b6 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java @@ -35,6 +35,7 @@ import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.edmx.EdmxReference; import org.apache.olingo.server.api.edmx.EdmxReferenceInclude; import org.apache.olingo.server.tecsvc.data.DataProvider; +import org.apache.olingo.server.tecsvc.processor.TechnicalActionProcessor; import org.apache.olingo.server.tecsvc.processor.TechnicalBatchProcessor; import org.apache.olingo.server.tecsvc.processor.TechnicalEntityProcessor; import org.apache.olingo.server.tecsvc.processor.TechnicalPrimitiveComplexProcessor; @@ -68,10 +69,11 @@ public class TechnicalServlet extends HttpServlet { ODataHttpHandler handler = odata.createHandler(serviceMetadata); handler.register(new TechnicalEntityProcessor(dataProvider, serviceMetadata)); handler.register(new TechnicalPrimitiveComplexProcessor(dataProvider, serviceMetadata)); + handler.register(new TechnicalActionProcessor(dataProvider, serviceMetadata)); handler.register(new TechnicalBatchProcessor(dataProvider)); handler.register(new ETagSupport()); handler.process(request, response); - } catch (RuntimeException e) { + } catch (final RuntimeException e) { LOG.error("Server Error", e); throw new ServletException(e); } diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java new file mode 100644 index 000000000..d0187339c --- /dev/null +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java @@ -0,0 +1,315 @@ +/* + * 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; + +import java.util.Locale; + +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.ContextURL.Builder; +import org.apache.olingo.commons.api.data.ContextURL.Suffix; +import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.edm.EdmAction; +import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.format.ContentType; +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.server.api.ODataApplicationException; +import org.apache.olingo.server.api.ODataRequest; +import org.apache.olingo.server.api.ODataResponse; +import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.deserializer.DeserializerException; +import org.apache.olingo.server.api.deserializer.DeserializerResult; +import org.apache.olingo.server.api.processor.ActionComplexCollectionProcessor; +import org.apache.olingo.server.api.processor.ActionComplexProcessor; +import org.apache.olingo.server.api.processor.ActionEntityCollectionProcessor; +import org.apache.olingo.server.api.processor.ActionEntityProcessor; +import org.apache.olingo.server.api.processor.ActionPrimitiveCollectionProcessor; +import org.apache.olingo.server.api.processor.ActionPrimitiveProcessor; +import org.apache.olingo.server.api.processor.ActionVoidProcessor; +import org.apache.olingo.server.api.serializer.ComplexSerializerOptions; +import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; +import org.apache.olingo.server.api.serializer.EntitySerializerOptions; +import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions; +import org.apache.olingo.server.api.serializer.SerializerException; +import org.apache.olingo.server.api.serializer.SerializerResult; +import org.apache.olingo.server.api.uri.UriInfo; +import org.apache.olingo.server.api.uri.UriResourceAction; +import org.apache.olingo.server.tecsvc.data.DataProvider; +import org.apache.olingo.server.tecsvc.data.EntityActionResult; + +/** + * Technical Processor for entity-related functionality. + */ +public class TechnicalActionProcessor extends TechnicalProcessor + implements ActionEntityCollectionProcessor, ActionEntityProcessor, + ActionPrimitiveCollectionProcessor, ActionPrimitiveProcessor, + ActionComplexCollectionProcessor, ActionComplexProcessor, + ActionVoidProcessor { + + public TechnicalActionProcessor(final DataProvider dataProvider, final ServiceMetadata serviceMetadata) { + super(dataProvider, serviceMetadata); + } + + @Override + public void processActionEntityCollection(final ODataRequest request, final ODataResponse response, + final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + blockBoundActions(uriInfo); + final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) + .getAction(); + + DeserializerResult deserializerResult = + odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) + .actionParameters(request.getBody(), action); + + EntityCollection collection = + dataProvider.processActionEntityCollection(action.getName(), deserializerResult.getActionParameters()); + + // Collections must never be null. + // Not nullable return types must not contain a null value. + if (collection == null + || collection.getEntities().contains(null) && !action.getReturnType().isNullable()) { + throw new ODataApplicationException("The action could not be executed.", + HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); + } + final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); + final EdmEntityType type = (EdmEntityType) action.getReturnType().getType(); + final ODataFormat format = ODataFormat.fromContentType(responseFormat); + EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions.with() + .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : getContextUrl(edmEntitySet, type, false)) + .build(); + response.setContent(odata.createSerializer(format) + .entityCollection(serviceMetadata, type, collection, options).getContent()); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } + + @Override + public void processActionEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, + final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + blockBoundActions(uriInfo); + final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) + .getAction(); + final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); + final EdmEntityType type = (EdmEntityType) action.getReturnType().getType(); + + final DeserializerResult deserializerResult = + odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) + .actionParameters(request.getBody(), action); + + final EntityActionResult entityResult = + dataProvider.processActionEntity(action.getName(), deserializerResult.getActionParameters()); + if (entityResult == null || entityResult.getEntity() == null) { + if (action.getReturnType().isNullable()) { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } else { + // Not nullable return type so we have to give back a 500 + throw new ODataApplicationException("The action could not be executed.", + HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); + } + } else { + final ODataFormat format = ODataFormat.fromContentType(responseFormat); + response.setContent(odata.createSerializer(format).entity( + serviceMetadata, + type, + entityResult.getEntity(), + EntitySerializerOptions.with() + .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : getContextUrl(edmEntitySet, type, true)) + .build()) + .getContent()); + response.setStatusCode((entityResult.isCreated() ? HttpStatusCode.CREATED : HttpStatusCode.OK) + .getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + if (entityResult.getEntity().getETag() != null) { + response.setHeader(HttpHeader.ETAG, entityResult.getEntity().getETag()); + } + } + } + + @Override + public void processActionPrimitiveCollection(final ODataRequest request, ODataResponse response, + final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + blockBoundActions(uriInfo); + final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) + .getAction(); + DeserializerResult deserializerResult = + odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) + .actionParameters(request.getBody(), action); + + Property property = + dataProvider.processActionPrimitiveCollection(action.getName(), deserializerResult.getActionParameters()); + + if (property == null || property.isNull()) { + // Collection Propertys must never be null + throw new ODataApplicationException("The action could not be executed.", + HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); + } else if (property.asCollection().contains(null) && !action.getReturnType().isNullable()) { + // Not nullable return type but array contains a null value + throw new ODataApplicationException("The action could not be executed.", + HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); + } + EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType(); + ContextURL contextURL = ContextURL.with().type(type).asCollection().build(); + PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build(); + + SerializerResult result = + odata.createSerializer(ODataFormat.fromContentType(responseFormat)) + .primitiveCollection(type, property, options); + + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setContent(result.getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } + + @Override + public void processActionPrimitive(final ODataRequest request, ODataResponse response, + final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + blockBoundActions(uriInfo); + final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) + .getAction(); + DeserializerResult deserializerResult = + odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) + .actionParameters(request.getBody(), action); + + Property property = dataProvider.processActionPrimitive(action.getName(), deserializerResult.getActionParameters()); + EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType(); + if (property == null || property.isNull()) { + if (action.getReturnType().isNullable()) { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } else { + // Not nullable return type so we have to give back an Internal Server Error + throw new ODataApplicationException("The action could not be executed.", + HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); + } + } else { + ContextURL contextURL = ContextURL.with().type(type).build(); + PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build(); + + SerializerResult result = odata.createSerializer(ODataFormat.fromContentType(responseFormat)).primitive(type, + property, options); + + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setContent(result.getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } + } + + @Override + public void processActionComplexCollection(final ODataRequest request, ODataResponse response, + final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + blockBoundActions(uriInfo); + final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) + .getAction(); + DeserializerResult deserializerResult = + odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) + .actionParameters(request.getBody(), action); + + Property property = + dataProvider.processActionComplexCollection(action.getName(), deserializerResult.getActionParameters()); + + if (property == null || property.isNull()) { + // Collection Propertys must never be null + throw new ODataApplicationException("The action could not be executed.", + HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); + } else if (property.asCollection().contains(null) && !action.getReturnType().isNullable()) { + // Not nullable return type but array contains a null value + throw new ODataApplicationException("The action could not be executed.", + HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); + } + EdmComplexType type = (EdmComplexType) action.getReturnType().getType(); + ContextURL contextURL = ContextURL.with().type(type).asCollection().build(); + ComplexSerializerOptions options = ComplexSerializerOptions.with().contextURL(contextURL).build(); + + SerializerResult result = + odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complexCollection(serviceMetadata, type, + property, options); + + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setContent(result.getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } + + @Override + public void processActionComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, + final ContentType requestFormat, final ContentType responseFormat) + throws ODataApplicationException, DeserializerException, SerializerException { + blockBoundActions(uriInfo); + final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) + .getAction(); + DeserializerResult deserializerResult = + odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) + .actionParameters(request.getBody(), action); + + Property property = dataProvider.processActionComplex(action.getName(), deserializerResult.getActionParameters()); + EdmComplexType type = (EdmComplexType) action.getReturnType().getType(); + if (property == null || property.isNull()) { + if (action.getReturnType().isNullable()) { + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } else { + // Not nullable return type so we have to give back an Internal Server Error + throw new ODataApplicationException("The action could not be executed.", + HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); + } + } else { + ContextURL contextURL = ContextURL.with().type(type).build(); + ComplexSerializerOptions options = ComplexSerializerOptions.with().contextURL(contextURL).build(); + + SerializerResult result = + odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complex(serviceMetadata, type, property, + options); + + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setContent(result.getContent()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + } + } + + @Override + public void processActionVoid(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, + final ContentType requestFormat) throws ODataApplicationException, DeserializerException { + final UriResourceAction resource = + ((UriResourceAction) uriInfo.getUriResourceParts().get(uriInfo.getUriResourceParts().size() - 1)); + final EdmAction action = resource.getAction(); + if (action.getParameterNames().size() - (action.isBound() ? 1 : 0) > 0) { + checkRequestFormat(requestFormat); + odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) + .actionParameters(request.getBody(), action); + } + response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); + } + + private ContextURL getContextUrl(final EdmEntitySet entitySet, final EdmEntityType entityType, + final boolean isSingleEntity) throws SerializerException { + Builder builder = ContextURL.with(); + builder = entitySet == null ? + isSingleEntity ? builder.type(entityType) : builder.asCollection().type(entityType) : + builder.entitySet(entitySet); + builder = builder.suffix(isSingleEntity && entitySet != null ? Suffix.ENTITY : null); + return builder.build(); + } +} diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java index 489055b26..dd3138896 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java @@ -26,7 +26,6 @@ import org.apache.olingo.commons.api.data.ContextURL.Builder; import org.apache.olingo.commons.api.data.ContextURL.Suffix; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntityCollection; -import org.apache.olingo.commons.api.edm.EdmAction; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.format.ContentType; @@ -42,9 +41,6 @@ import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.deserializer.DeserializerException; import org.apache.olingo.server.api.deserializer.DeserializerResult; import org.apache.olingo.server.api.deserializer.ODataDeserializer; -import org.apache.olingo.server.api.processor.ActionEntityCollectionProcessor; -import org.apache.olingo.server.api.processor.ActionEntityProcessor; -import org.apache.olingo.server.api.processor.ActionVoidProcessor; import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor; import org.apache.olingo.server.api.processor.EntityCollectionProcessor; import org.apache.olingo.server.api.processor.EntityProcessor; @@ -53,12 +49,10 @@ import org.apache.olingo.server.api.processor.ReferenceCollectionProcessor; import org.apache.olingo.server.api.processor.ReferenceProcessor; import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; import org.apache.olingo.server.api.serializer.EntitySerializerOptions; -import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.api.uri.UriInfo; import org.apache.olingo.server.api.uri.UriResource; -import org.apache.olingo.server.api.uri.UriResourceAction; import org.apache.olingo.server.api.uri.UriResourceEntitySet; import org.apache.olingo.server.api.uri.UriResourceFunction; import org.apache.olingo.server.api.uri.UriResourceValue; @@ -66,7 +60,6 @@ import org.apache.olingo.server.api.uri.queryoption.CountOption; 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.data.EntityActionResult; import org.apache.olingo.server.tecsvc.data.RequestValidator; import org.apache.olingo.server.tecsvc.processor.queryoptions.ExpandSystemQueryOptionHandler; import org.apache.olingo.server.tecsvc.processor.queryoptions.options.CountHandler; @@ -80,9 +73,8 @@ import org.apache.olingo.server.tecsvc.processor.queryoptions.options.TopHandler * Technical Processor for entity-related functionality. */ public class TechnicalEntityProcessor extends TechnicalProcessor - implements EntityCollectionProcessor, ActionEntityCollectionProcessor, CountEntityCollectionProcessor, - EntityProcessor, ActionEntityProcessor, MediaEntityProcessor, - ActionVoidProcessor, ReferenceCollectionProcessor, ReferenceProcessor { + implements EntityCollectionProcessor, CountEntityCollectionProcessor, EntityProcessor, MediaEntityProcessor, + ReferenceCollectionProcessor, ReferenceProcessor { public TechnicalEntityProcessor(final DataProvider dataProvider, final ServiceMetadata serviceMetadata) { super(dataProvider, serviceMetadata); @@ -93,42 +85,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor final ContentType requestedContentType) throws ODataApplicationException, SerializerException { validateOptions(uriInfo.asUriInfoResource()); - processEntityCollection(request, response, uriInfo, requestedContentType, false); - } - - @Override - public void processActionEntityCollection(final ODataRequest request, final ODataResponse response, - final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) - throws ODataApplicationException, DeserializerException, SerializerException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - - DeserializerResult deserializerResult = - odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) - .actionParameters(request.getBody(), action); - - EntityCollection collection = - dataProvider.processActionEntityCollection(action.getName(), deserializerResult.getActionParameters()); - - // Collections must never be null. - // Not nullable return types must not contain a null value. - if (collection == null - || collection.getEntities().contains(null) && !action.getReturnType().isNullable()) { - throw new ODataApplicationException("The action could not be executed.", - HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); - } - final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); - final EdmEntityType type = (EdmEntityType) action.getReturnType().getType(); - final ODataFormat format = ODataFormat.fromContentType(responseFormat); - EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions.with() - .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : - getContextUrl(edmEntitySet, type, false, null, null)) - .build(); - response.setContent(odata.createSerializer(format) - .entityCollection(serviceMetadata, type, collection, options).getContent()); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + readEntityCollection(request, response, uriInfo, requestedContentType, false); } @Override @@ -230,8 +187,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor throws ODataApplicationException, DeserializerException, SerializerException { final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo); final EdmEntityType edmEntityType = edmEntitySet.getEntityType(); - Entity entity; + Entity entity; try { entity = readEntity(uriInfo); } catch (ODataApplicationException e) { @@ -311,69 +268,6 @@ public class TechnicalEntityProcessor extends TechnicalProcessor response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); } - @Override - public void processActionEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, - final ContentType requestFormat, final ContentType responseFormat) - throws ODataApplicationException, DeserializerException, SerializerException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); - final EdmEntityType type = (EdmEntityType) action.getReturnType().getType(); - - final DeserializerResult deserializerResult = - odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) - .actionParameters(request.getBody(), action); - - final EntityActionResult entityResult = - dataProvider.processActionEntity(action.getName(), deserializerResult.getActionParameters()); - if (entityResult == null || entityResult.getEntity() == null) { - if (action.getReturnType().isNullable()) { - response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); - } else { - // Not nullable return type so we have to give back a 500 - throw new ODataApplicationException("The action could not be executed.", - HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); - } - } else { - final ODataFormat format = ODataFormat.fromContentType(responseFormat); - response.setContent(serializeEntity(entityResult.getEntity(), edmEntitySet, type, format, null, null) - .getContent()); - response.setStatusCode((entityResult.isCreated() ? HttpStatusCode.CREATED : HttpStatusCode.OK) - .getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); - if (entityResult.getEntity().getETag() != null) { - response.setHeader(HttpHeader.ETAG, entityResult.getEntity().getETag()); - } - } - } - - @Override - public void processActionVoid(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, - final ContentType requestFormat) throws ODataApplicationException, DeserializerException { - final UriResourceAction resource = - ((UriResourceAction) uriInfo.getUriResourceParts().get(uriInfo.getUriResourceParts().size() - 1)); - final EdmAction action = resource.getAction(); - if (action.getParameterNames().size() - (action.isBound() ? 1 : 0) > 0) { - checkRequestFormat(requestFormat); - odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) - .actionParameters(request.getBody(), action); - } - response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); - } - - private ContextURL getContextUrl(final EdmEntitySet entitySet, final EdmEntityType entityType, - final boolean isSingleEntity, final ExpandOption expand, final SelectOption select) throws SerializerException { - Builder builder = ContextURL.with(); - builder = entitySet == null ? - isSingleEntity ? builder.type(entityType) : builder.asCollection().type(entityType) : - builder.entitySet(entitySet); - builder = builder - .selectList(odata.createUriHelper().buildContextURLSelectList(entityType, expand, select)) - .suffix(isSingleEntity && entitySet != null ? Suffix.ENTITY : null); - return builder.build(); - } - @Override public void readReference(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType requestedContentType) throws ODataApplicationException, SerializerException { @@ -401,8 +295,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor @Override public void readReferenceCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, final ContentType requestedContentType) throws ODataApplicationException, SerializerException { - - processEntityCollection(request, response, uriInfo, requestedContentType, true); + readEntityCollection(request, response, uriInfo, requestedContentType, true); } private void readEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, @@ -440,10 +333,9 @@ public class TechnicalEntityProcessor extends TechnicalProcessor response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString()); } - private void processEntityCollection(final ODataRequest request, final ODataResponse response, + private void readEntityCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, final ContentType requestedContentType, final boolean isReference) throws ODataApplicationException, SerializerException { - final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); final EdmEntityType edmEntityType = edmEntitySet == null ? (EdmEntityType) ((UriResourceFunction) uriInfo.getUriResourceParts() @@ -451,7 +343,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor edmEntitySet.getEntityType(); EntityCollection entitySetInitial = readEntityCollection(uriInfo); - + if(entitySetInitial == null) { entitySetInitial = new EntityCollection(); } @@ -487,7 +379,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor expand); expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand); final CountOption countOption = uriInfo.getCountOption(); - + // Serialize final SerializerResult serializerResult = (isReference) ? serializeReferenceCollection(entitySetSerialization, edmEntitySet, format) : @@ -503,7 +395,6 @@ public class TechnicalEntityProcessor extends TechnicalProcessor final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType, final ODataFormat format, final ExpandOption expand, final SelectOption select, final CountOption countOption) throws SerializerException { - return odata.createSerializer(format).entityCollection( serviceMetadata, edmEntityType, @@ -515,25 +406,21 @@ public class TechnicalEntityProcessor extends TechnicalProcessor .expand(expand).select(select) .build()); } - + private SerializerResult serializeReferenceCollection(final EntityCollection entityCollection, final EdmEntitySet edmEntitySet, final ODataFormat format) throws SerializerException { - - final ContextURL contextUrl = ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build(); - final ODataSerializer serializer = odata.createSerializer(format); - - return serializer.referenceCollection(serviceMetadata, edmEntitySet, entityCollection, contextUrl); + return odata.createSerializer(format) + .referenceCollection(serviceMetadata, edmEntitySet, entityCollection, + ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build()); } - + private SerializerResult serializeReference(final Entity entity, final EdmEntitySet edmEntitySet, final ODataFormat format ) throws SerializerException { - - final ContextURL contextUrl = ContextURL.with().suffix(Suffix.REFERENCE).build(); - final ODataSerializer serializer = odata.createSerializer(format); - - return serializer.reference(serviceMetadata, edmEntitySet, entity, contextUrl); + return odata.createSerializer(format) + .reference(serviceMetadata, edmEntitySet, entity, + ContextURL.with().suffix(Suffix.REFERENCE).build()); } - + private SerializerResult serializeEntity(final Entity entity, final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType, final ODataFormat format, final ExpandOption expand, final SelectOption select) throws SerializerException { @@ -547,4 +434,16 @@ public class TechnicalEntityProcessor extends TechnicalProcessor .expand(expand).select(select) .build()); } + + private ContextURL getContextUrl(final EdmEntitySet entitySet, final EdmEntityType entityType, + final boolean isSingleEntity, final ExpandOption expand, final SelectOption select) throws SerializerException { + Builder builder = ContextURL.with(); + builder = entitySet == null ? + isSingleEntity ? builder.type(entityType) : builder.asCollection().type(entityType) : + builder.entitySet(entitySet); + builder = builder + .selectList(odata.createUriHelper().buildContextURLSelectList(entityType, expand, select)) + .suffix(isSingleEntity && entitySet != null ? Suffix.ENTITY : null); + return builder.build(); + } } diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java index 4f1a4baa0..fd9920c16 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java @@ -27,7 +27,6 @@ import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.ContextURL.Builder; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.Property; -import org.apache.olingo.commons.api.edm.EdmAction; import org.apache.olingo.commons.api.edm.EdmComplexType; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmPrimitiveType; @@ -47,11 +46,6 @@ import org.apache.olingo.server.api.ODataRequest; import org.apache.olingo.server.api.ODataResponse; import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.deserializer.DeserializerException; -import org.apache.olingo.server.api.deserializer.DeserializerResult; -import org.apache.olingo.server.api.processor.ActionComplexCollectionProcessor; -import org.apache.olingo.server.api.processor.ActionComplexProcessor; -import org.apache.olingo.server.api.processor.ActionPrimitiveCollectionProcessor; -import org.apache.olingo.server.api.processor.ActionPrimitiveProcessor; import org.apache.olingo.server.api.processor.ComplexCollectionProcessor; import org.apache.olingo.server.api.processor.ComplexProcessor; import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor; @@ -69,7 +63,6 @@ import org.apache.olingo.server.api.uri.UriHelper; import org.apache.olingo.server.api.uri.UriInfo; import org.apache.olingo.server.api.uri.UriInfoResource; import org.apache.olingo.server.api.uri.UriResource; -import org.apache.olingo.server.api.uri.UriResourceAction; import org.apache.olingo.server.api.uri.UriResourceFunction; import org.apache.olingo.server.api.uri.UriResourceKind; import org.apache.olingo.server.api.uri.UriResourceProperty; @@ -81,10 +74,8 @@ import org.apache.olingo.server.tecsvc.data.DataProvider; * Technical Processor which provides functionality related to primitive and complex types and collections thereof. */ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor - implements PrimitiveProcessor, PrimitiveValueProcessor, ActionPrimitiveProcessor, - PrimitiveCollectionProcessor, ActionPrimitiveCollectionProcessor, - ComplexProcessor, ActionComplexProcessor, - ComplexCollectionProcessor, ActionComplexCollectionProcessor { + implements PrimitiveProcessor, PrimitiveValueProcessor, PrimitiveCollectionProcessor, + ComplexProcessor, ComplexCollectionProcessor { public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider, final ServiceMetadata serviceMetadata) { @@ -110,40 +101,6 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor deleteProperty(request, response, uriInfo); } - @Override - public void processActionPrimitive(final ODataRequest request, ODataResponse response, - final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) - throws ODataApplicationException, DeserializerException, SerializerException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - DeserializerResult deserializerResult = - odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) - .actionParameters(request.getBody(), action); - - Property property = dataProvider.processActionPrimitive(action.getName(), deserializerResult.getActionParameters()); - EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType(); - if (property == null || property.isNull()) { - if (action.getReturnType().isNullable()) { - response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); - } else { - // Not nullable return type so we have to give back an Internal Server Error - throw new ODataApplicationException("The action could not be executed.", - HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); - } - } else { - ContextURL contextURL = ContextURL.with().type(type).build(); - PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build(); - - SerializerResult result = odata.createSerializer(ODataFormat.fromContentType(responseFormat)).primitive(type, - property, options); - - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setContent(result.getContent()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); - } - } - @Override public void readPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType contentType) throws ODataApplicationException, SerializerException { @@ -163,42 +120,6 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor deleteProperty(request, response, uriInfo); } - @Override - public void processActionPrimitiveCollection(final ODataRequest request, ODataResponse response, - final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) - throws ODataApplicationException, DeserializerException, SerializerException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - DeserializerResult deserializerResult = - odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) - .actionParameters(request.getBody(), action); - - Property property = - dataProvider.processActionPrimitiveCollection(action.getName(), deserializerResult.getActionParameters()); - - if (property == null || property.isNull()) { - // Collection Propertys must never be null - throw new ODataApplicationException("The action could not be executed.", - HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); - } else if (property.asCollection().contains(null) && !action.getReturnType().isNullable()) { - // Not nullable return type but array contains a null value - throw new ODataApplicationException("The action could not be executed.", - HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); - } - EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType(); - ContextURL contextURL = ContextURL.with().type(type).asCollection().build(); - PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build(); - - SerializerResult result = - odata.createSerializer(ODataFormat.fromContentType(responseFormat)) - .primitiveCollection(type, property, options); - - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setContent(result.getContent()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); - } - @Override public void readComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType contentType) throws ODataApplicationException, SerializerException { @@ -218,41 +139,6 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor deleteProperty(request, response, uriInfo); } - @Override - public void processActionComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, - final ContentType requestFormat, final ContentType responseFormat) - throws ODataApplicationException, DeserializerException, SerializerException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - DeserializerResult deserializerResult = - odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) - .actionParameters(request.getBody(), action); - - Property property = dataProvider.processActionComplex(action.getName(), deserializerResult.getActionParameters()); - EdmComplexType type = (EdmComplexType) action.getReturnType().getType(); - if (property == null || property.isNull()) { - if (action.getReturnType().isNullable()) { - response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); - } else { - // Not nullable return type so we have to give back an Internal Server Error - throw new ODataApplicationException("The action could not be executed.", - HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); - } - } else { - ContextURL contextURL = ContextURL.with().type(type).build(); - ComplexSerializerOptions options = ComplexSerializerOptions.with().contextURL(contextURL).build(); - - SerializerResult result = - odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complex(serviceMetadata, type, property, - options); - - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setContent(result.getContent()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); - } - } - @Override public void readComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType contentType) throws ODataApplicationException, SerializerException { @@ -272,42 +158,6 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor deleteProperty(request, response, uriInfo); } - @Override - public void processActionComplexCollection(final ODataRequest request, ODataResponse response, - final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) - throws ODataApplicationException, DeserializerException, SerializerException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - DeserializerResult deserializerResult = - odata.createDeserializer(ODataFormat.fromContentType(requestFormat)) - .actionParameters(request.getBody(), action); - - Property property = - dataProvider.processActionComplexCollection(action.getName(), deserializerResult.getActionParameters()); - - if (property == null || property.isNull()) { - // Collection Propertys must never be null - throw new ODataApplicationException("The action could not be executed.", - HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); - } else if (property.asCollection().contains(null) && !action.getReturnType().isNullable()) { - // Not nullable return type but array contains a null value - throw new ODataApplicationException("The action could not be executed.", - HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); - } - EdmComplexType type = (EdmComplexType) action.getReturnType().getType(); - ContextURL contextURL = ContextURL.with().type(type).asCollection().build(); - ComplexSerializerOptions options = ComplexSerializerOptions.with().contextURL(contextURL).build(); - - SerializerResult result = - odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complexCollection(serviceMetadata, type, - property, options); - - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setContent(result.getContent()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); - } - private void readProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType contentType, final RepresentationType representationType) throws ODataApplicationException, SerializerException {