You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/03/27 10:44:07 UTC
olingo-odata4 git commit: [OLINGO-603] dispatcher improvements
Repository: olingo-odata4
Updated Branches:
refs/heads/master 6421f5480 -> 4f33c704c
[OLINGO-603] dispatcher improvements
Change-Id: Ic4fbb99fbce1c23d41df36ddc090f2b7f2ec1c22
Signed-off-by: Christian Amend <ch...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/4f33c704
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/4f33c704
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/4f33c704
Branch: refs/heads/master
Commit: 4f33c704cf6b47bc969f0c981bf1f9e84d381c2f
Parents: 6421f54
Author: Klaus Straubinger <kl...@sap.com>
Authored: Fri Mar 27 10:27:35 2015 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Fri Mar 27 10:42:36 2015 +0100
----------------------------------------------------------------------
.../apache/olingo/server/core/ODataHandler.java | 289 ++++++++-----------
1 file changed, 124 insertions(+), 165 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/4f33c704/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index 6d98b5e..b01970d 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -24,7 +24,6 @@ import java.util.List;
import org.apache.olingo.commons.api.edm.EdmAction;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmFunction;
-import org.apache.olingo.commons.api.edm.EdmFunctionImport;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmReturnType;
import org.apache.olingo.commons.api.edm.EdmType;
@@ -101,8 +100,8 @@ public class ODataHandler {
odata = server;
this.serviceMetadata = serviceMetadata;
- register(new DefaultProcessor());
register(new DefaultRedirectProcessor());
+ register(new DefaultProcessor());
}
public ODataResponse process(final ODataRequest request) {
@@ -158,31 +157,23 @@ public class ODataHandler {
switch (uriInfo.getKind()) {
case metadata:
- if (method == HttpMethod.GET) {
- final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
- request, customContentTypeSupport, RepresentationType.METADATA);
- selectProcessor(MetadataProcessor.class)
- .readMetadata(request, response, uriInfo, requestedContentType);
- } else {
- throw new ODataHandlerException("HttpMethod " + method + " not allowed for metadata document",
- ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
- }
+ checkMethod(method, HttpMethod.GET);
+ final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ request, customContentTypeSupport, RepresentationType.METADATA);
+ selectProcessor(MetadataProcessor.class)
+ .readMetadata(request, response, uriInfo, requestedContentType);
break;
case service:
- if (method == HttpMethod.GET) {
- if ("".equals(request.getRawODataPath())) {
- selectProcessor(RedirectProcessor.class).redirect(request, response);
- } else {
- final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
- request, customContentTypeSupport, RepresentationType.SERVICE);
-
- selectProcessor(ServiceDocumentProcessor.class)
- .readServiceDocument(request, response, uriInfo, requestedContentType);
- }
+ checkMethod(method, HttpMethod.GET);
+ if ("".equals(request.getRawODataPath())) {
+ selectProcessor(RedirectProcessor.class)
+ .redirect(request, response);
} else {
- throw new ODataHandlerException("HttpMethod " + method + " not allowed for service document",
- ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
+ final ContentType serviceContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ request, customContentTypeSupport, RepresentationType.SERVICE);
+ selectProcessor(ServiceDocumentProcessor.class)
+ .readServiceDocument(request, response, uriInfo, serviceContentType);
}
break;
@@ -191,14 +182,9 @@ public class ODataHandler {
break;
case batch:
- if (method == HttpMethod.POST) {
- final BatchProcessor bp = selectProcessor(BatchProcessor.class);
- final BatchHandler handler = new BatchHandler(this, bp);
- handler.process(request, response, true);
- } else {
- throw new ODataHandlerException("HTTP method " + method + " is not allowed.",
- ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
- }
+ checkMethod(method, HttpMethod.POST);
+ new BatchHandler(this, selectProcessor(BatchProcessor.class))
+ .process(request, response, true);
break;
default:
@@ -237,29 +223,33 @@ public class ODataHandler {
switch (lastPathSegment.getKind()) {
case action:
+ checkMethod(request.getMethod(), HttpMethod.POST);
handleActionDispatching(request, response, (UriResourceAction) lastPathSegment);
break;
case function:
+ checkMethod(request.getMethod(), HttpMethod.GET);
handleFunctionDispatching(request, response, (UriResourceFunction) lastPathSegment);
break;
case entitySet:
case navigationProperty:
- handleEntityDispatching(request, response, (UriResourcePartTyped) lastPathSegment);
+ handleEntityDispatching(request, response,
+ ((UriResourcePartTyped) lastPathSegment).isCollection(), isMedia(lastPathSegment));
break;
case count:
+ checkMethod(request.getMethod(), HttpMethod.GET);
handleCountDispatching(request, response, lastPathSegmentIndex);
break;
case primitiveProperty:
- handlePrimitivePropertyDispatching(request, response, false,
+ handlePrimitiveDispatching(request, response,
((UriResourceProperty) lastPathSegment).isCollection());
break;
case complexProperty:
- handleComplexPropertyDispatching(request, response, false,
+ handleComplexDispatching(request, response,
((UriResourceProperty) lastPathSegment).isCollection());
break;
@@ -279,86 +269,97 @@ public class ODataHandler {
private void handleFunctionDispatching(final ODataRequest request, final ODataResponse response,
final UriResourceFunction uriResourceFunction)
- throws ODataHandlerException, SerializerException, ContentNegotiatorException,
- ODataApplicationException, DeserializerException {
- final HttpMethod method = request.getMethod();
- if (method != HttpMethod.GET) {
- throw new ODataHandlerException("HTTP method " + method + " is not allowed.",
- ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
- }
-
- EdmFunctionImport functionImport = uriResourceFunction.getFunctionImport();
- // could be null for bound functions
- if (functionImport == null) {
- throw new ODataHandlerException("Bound functions are not implemented yet",
- ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+ throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException,
+ SerializerException, DeserializerException {
+ EdmFunction function = uriResourceFunction.getFunction();
+ if (function == null) {
+ function = uriResourceFunction.getFunctionImport().getUnboundFunctions().get(0);
}
-
- List<EdmFunction> unboundFunctions = functionImport.getUnboundFunctions();
- if (unboundFunctions == null || unboundFunctions.isEmpty()) {
- throw new ODataHandlerException("No unbound function defined for function import",
+ final EdmReturnType returnType = function.getReturnType();
+ switch (returnType.getType().getKind()) {
+ case ENTITY:
+ handleEntityDispatching(request, response,
+ returnType.isCollection() && uriResourceFunction.getKeyPredicates().isEmpty(),
+ false);
+ break;
+ case PRIMITIVE:
+ handlePrimitiveDispatching(request, response, returnType.isCollection());
+ break;
+ case COMPLEX:
+ handleComplexDispatching(request, response, returnType.isCollection());
+ break;
+ default:
+ throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
}
- if(uriResourceFunction.getKeyPredicates().isEmpty()) {
- EdmReturnType returnType = unboundFunctions.get(0).getReturnType();
- handleOperationDispatching(request, response, false, returnType);
- } else {
- handleEntityDispatching(request, response, false, false, false);
- }
}
private void handleActionDispatching(final ODataRequest request, final ODataResponse response,
final UriResourceAction uriResourceAction)
- throws ODataHandlerException, SerializerException, ContentNegotiatorException,
- ODataApplicationException, DeserializerException {
-
- final HttpMethod method = request.getMethod();
- if (request.getMethod() != HttpMethod.POST) {
- throw new ODataHandlerException("HTTP method " + method + " is not allowed.",
- ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
- }
-
+ throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException,
+ SerializerException, DeserializerException {
final EdmAction action = uriResourceAction.getAction();
- if (action == null) {
- throw new ODataHandlerException("No action defined for action import.",
- ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
- }
final EdmReturnType returnType = action.getReturnType();
+ final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
+ checkContentTypeSupport(requestFormat, RepresentationType.ACTION_PARAMETERS);
+
if (returnType == null) {
- final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
- checkContentTypeSupport(requestFormat, RepresentationType.ACTION_PARAMETERS);
selectProcessor(ActionVoidProcessor.class)
.processActionVoid(request, response, uriInfo, requestFormat);
} else {
- handleOperationDispatching(request, response, true, returnType);
- }
- }
-
- private void handleOperationDispatching(final ODataRequest request, final ODataResponse response,
- final boolean isAction, final EdmReturnType edmReturnType)
- throws ODataHandlerException, SerializerException, ContentNegotiatorException,
- ODataApplicationException, DeserializerException {
+ final boolean isCollection = returnType.isCollection();
+ ContentType responseFormat = null;
+ switch (returnType.getType().getKind()) {
+ case ENTITY:
+ responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ request, customContentTypeSupport,
+ isCollection ? RepresentationType.COLLECTION_ENTITY : RepresentationType.ENTITY);
+ if (isCollection) {
+ selectProcessor(ActionEntityCollectionProcessor.class)
+ .processActionEntityCollection(request, response, uriInfo, requestFormat, responseFormat);
+ } else {
+ selectProcessor(ActionEntityProcessor.class)
+ .processActionEntity(request, response, uriInfo, requestFormat, responseFormat);
+ }
+ break;
+
+ case PRIMITIVE:
+ responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ request, customContentTypeSupport,
+ isCollection ? RepresentationType.COLLECTION_PRIMITIVE : RepresentationType.PRIMITIVE);
+ if (isCollection) {
+ selectProcessor(ActionPrimitiveCollectionProcessor.class)
+ .processActionPrimitiveCollection(request, response, uriInfo, requestFormat, responseFormat);
+ } else {
+ selectProcessor(ActionPrimitiveProcessor.class)
+ .processActionPrimitive(request, response, uriInfo, requestFormat, responseFormat);
+ }
+ break;
+
+ case COMPLEX:
+ responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ request, customContentTypeSupport,
+ isCollection ? RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX);
+ if (isCollection) {
+ selectProcessor(ActionComplexCollectionProcessor.class)
+ .processActionComplexCollection(request, response, uriInfo, requestFormat, responseFormat);
+ } else {
+ selectProcessor(ActionComplexProcessor.class)
+ .processActionComplex(request, response, uriInfo, requestFormat, responseFormat);
+ }
+ break;
- switch (edmReturnType.getType().getKind()) {
- case ENTITY:
- handleEntityDispatching(request, response, edmReturnType.isCollection(), false, isAction);
- break;
- case PRIMITIVE:
- handlePrimitivePropertyDispatching(request, response, isAction, edmReturnType.isCollection());
- break;
- case COMPLEX:
- handleComplexPropertyDispatching(request, response, isAction, edmReturnType.isCollection());
- break;
- default:
- throw new ODataHandlerException("not implemented",
- ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+ default:
+ throw new ODataHandlerException("not implemented",
+ ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+ }
}
}
private void handleReferenceDispatching(final ODataRequest request, final ODataResponse response,
final int lastPathSegmentIndex)
- throws ContentNegotiatorException, ODataApplicationException, SerializerException, ODataHandlerException,
- DeserializerException {
+ throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException,
+ SerializerException, DeserializerException {
final HttpMethod method = request.getMethod();
if (((UriResourcePartTyped) uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1)).isCollection()) {
if (method == HttpMethod.GET) {
@@ -397,8 +398,8 @@ public class ODataHandler {
private void handleValueDispatching(final ODataRequest request, final ODataResponse response,
final int lastPathSegmentIndex)
- throws ContentNegotiatorException, ODataApplicationException, SerializerException, ODataHandlerException,
- DeserializerException {
+ throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException,
+ SerializerException, DeserializerException {
final HttpMethod method = request.getMethod();
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
if (resource instanceof UriResourceProperty
@@ -449,11 +450,10 @@ public class ODataHandler {
}
}
- private void handleComplexPropertyDispatching(final ODataRequest request, final ODataResponse response,
- final boolean isAction, final boolean isCollection)
- throws ContentNegotiatorException, ODataApplicationException, SerializerException, ODataHandlerException,
- DeserializerException {
-
+ private void handleComplexDispatching(final ODataRequest request, final ODataResponse response,
+ final boolean isCollection)
+ throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException,
+ SerializerException, DeserializerException {
final HttpMethod method = request.getMethod();
final RepresentationType complexRepresentationType = isCollection ?
RepresentationType.COLLECTION_COMPLEX : RepresentationType.COMPLEX;
@@ -479,18 +479,6 @@ public class ODataHandler {
selectProcessor(ComplexProcessor.class)
.updateComplex(request, response, uriInfo, requestFormat, responseFormat);
}
- } else if (method == HttpMethod.POST && isAction) {
- final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
- checkContentTypeSupport(requestFormat, RepresentationType.ACTION_PARAMETERS);
- final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
- request, customContentTypeSupport, complexRepresentationType);
- if (isCollection) {
- selectProcessor(ActionComplexCollectionProcessor.class)
- .processActionComplexCollection(request, response, uriInfo, requestFormat, responseFormat);
- } else {
- selectProcessor(ActionComplexProcessor.class)
- .processActionComplex(request, response, uriInfo, requestFormat, responseFormat);
- }
} else if (method == HttpMethod.DELETE) {
if (isCollection) {
selectProcessor(ComplexCollectionProcessor.class)
@@ -505,11 +493,10 @@ public class ODataHandler {
}
}
- private void handlePrimitivePropertyDispatching(final ODataRequest request, final ODataResponse response,
- boolean isAction, final boolean isCollection)
- throws ContentNegotiatorException, ODataApplicationException, SerializerException, ODataHandlerException,
- DeserializerException {
-
+ private void handlePrimitiveDispatching(final ODataRequest request, final ODataResponse response,
+ final boolean isCollection)
+ throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException,
+ SerializerException, DeserializerException {
final HttpMethod method = request.getMethod();
final RepresentationType representationType = isCollection ?
RepresentationType.COLLECTION_PRIMITIVE : RepresentationType.PRIMITIVE;
@@ -543,18 +530,6 @@ public class ODataHandler {
selectProcessor(PrimitiveProcessor.class)
.deletePrimitive(request, response, uriInfo);
}
- } else if (method == HttpMethod.POST && isAction) {
- final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
- checkContentTypeSupport(requestFormat, RepresentationType.ACTION_PARAMETERS);
- final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
- request, customContentTypeSupport, representationType);
- if (isCollection) {
- selectProcessor(ActionPrimitiveCollectionProcessor.class)
- .processActionPrimitiveCollection(request, response, uriInfo, requestFormat, responseFormat);
- } else {
- selectProcessor(ActionPrimitiveProcessor.class)
- .processActionPrimitive(request, response, uriInfo, requestFormat, responseFormat);
- }
} else {
throw new ODataHandlerException("HTTP method " + method + " is not allowed.",
ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
@@ -563,8 +538,7 @@ public class ODataHandler {
private void handleCountDispatching(final ODataRequest request, final ODataResponse response,
final int lastPathSegmentIndex)
- throws ODataApplicationException, SerializerException, ODataHandlerException {
-
+ throws ODataHandlerException, ODataApplicationException, SerializerException {
final HttpMethod method = request.getMethod();
if (method == HttpMethod.GET) {
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
@@ -590,42 +564,25 @@ public class ODataHandler {
}
private void handleEntityDispatching(final ODataRequest request, final ODataResponse response,
- final UriResourcePartTyped uriResourcePart)
- throws ContentNegotiatorException, ODataApplicationException, SerializerException, ODataHandlerException,
- DeserializerException {
- handleEntityDispatching(request, response, uriResourcePart.isCollection(), isMedia(uriResourcePart), false);
- }
-
- private void handleEntityDispatching(final ODataRequest request, final ODataResponse response,
- final boolean isCollection, final boolean isMedia, boolean isAction)
- throws ContentNegotiatorException, ODataApplicationException, SerializerException, ODataHandlerException,
- DeserializerException {
-
+ final boolean isCollection, final boolean isMedia)
+ throws ODataHandlerException, ContentNegotiatorException, ODataApplicationException,
+ SerializerException, DeserializerException {
final HttpMethod method = request.getMethod();
if (isCollection) {
if (method == HttpMethod.GET) {
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
-
selectProcessor(EntityCollectionProcessor.class)
.readEntityCollection(request, response, uriInfo, requestedContentType);
} else if (method == HttpMethod.POST) {
final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
+ final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ request, customContentTypeSupport, RepresentationType.ENTITY);
if (isMedia) {
- final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
- request, customContentTypeSupport, RepresentationType.ENTITY);
selectProcessor(MediaEntityProcessor.class)
.createMediaEntity(request, response, uriInfo, requestFormat, responseFormat);
- } else if (isAction) {
- checkContentTypeSupport(requestFormat, RepresentationType.ACTION_PARAMETERS);
- final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
- request, customContentTypeSupport, RepresentationType.COLLECTION_ENTITY);
- selectProcessor(ActionEntityCollectionProcessor.class)
- .processActionEntityCollection(request, response, uriInfo, requestFormat, responseFormat);
} else {
checkContentTypeSupport(requestFormat, RepresentationType.ENTITY);
- final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
- request, customContentTypeSupport, RepresentationType.ENTITY);
selectProcessor(EntityProcessor.class)
.createEntity(request, response, uriInfo, requestFormat, responseFormat);
}
@@ -637,21 +594,15 @@ public class ODataHandler {
if (method == HttpMethod.GET) {
final ContentType requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, RepresentationType.ENTITY);
-
- selectProcessor(EntityProcessor.class).readEntity(request, response, uriInfo, requestedContentType);
+ selectProcessor(EntityProcessor.class)
+ .readEntity(request, response, uriInfo, requestedContentType);
} else if (method == HttpMethod.PUT || method == HttpMethod.PATCH) {
final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
checkContentTypeSupport(requestFormat, RepresentationType.ENTITY);
final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
request, customContentTypeSupport, RepresentationType.ENTITY);
- selectProcessor(EntityProcessor.class).updateEntity(request, response, uriInfo, requestFormat, responseFormat);
- } else if (method == HttpMethod.POST && isAction) {
- final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
- checkContentTypeSupport(requestFormat, RepresentationType.ACTION_PARAMETERS);
- final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
- request, customContentTypeSupport, RepresentationType.ENTITY);
- selectProcessor(ActionEntityProcessor.class).processActionEntity(
- request, response, uriInfo, requestFormat, responseFormat);
+ selectProcessor(EntityProcessor.class)
+ .updateEntity(request, response, uriInfo, requestFormat, responseFormat);
} else if (method == HttpMethod.DELETE) {
selectProcessor(isMedia ? MediaEntityProcessor.class : EntityProcessor.class)
.deleteEntity(request, response, uriInfo);
@@ -662,6 +613,14 @@ public class ODataHandler {
}
}
+ private void checkMethod(final HttpMethod requestMethod, final HttpMethod allowedMethod)
+ throws ODataHandlerException {
+ if (requestMethod != allowedMethod) {
+ throw new ODataHandlerException("HTTP method " + requestMethod + " is not allowed.",
+ ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, requestMethod.toString());
+ }
+ }
+
private void checkContentTypeSupport(ContentType requestFormat, RepresentationType representationType)
throws ODataHandlerException, ContentNegotiatorException {
if (!ContentNegotiator.isSupported(requestFormat, customContentTypeSupport, representationType)) {