You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2015/06/27 11:48:28 UTC
[1/4] olingo-odata2 git commit: [OLINGO-710] FixGetCallbackGeneric
Repository: olingo-odata2
Updated Branches:
refs/heads/master 5fc3ed2a1 -> 438f7a95e
[OLINGO-710] FixGetCallbackGeneric
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/5f81a5c4
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/5f81a5c4
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/5f81a5c4
Branch: refs/heads/master
Commit: 5f81a5c4c2c79a26619528ed9587de27bf27b7e7
Parents: 5fc3ed2
Author: mibo <mi...@mirb.de>
Authored: Sun Jun 21 16:46:36 2015 +0200
Committer: mibo <mi...@mirb.de>
Committed: Sun Jun 21 16:46:36 2015 +0200
----------------------------------------------------------------------
.../annotation/processor/ref/AnnotationRefServiceFactory.java | 2 +-
.../olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java | 2 +-
.../java/org/apache/olingo/odata2/api/ODataServiceFactory.java | 2 +-
.../org/apache/olingo/odata2/core/ODataExceptionWrapperTest.java | 2 +-
.../odata2/core/rest/ODataServiceFactoryWithCallbackImpl.java | 2 +-
.../org/apache/olingo/odata2/fit/misc/ODataApplicationFactory.java | 2 +-
.../apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java | 2 +-
.../olingo/odata2/testutil/fit/DebugCallbackFactoryFlase.java | 2 +-
.../olingo/odata2/testutil/fit/DebugCallbackFactoryTrue.java | 2 +-
.../apache/olingo/odata2/testutil/fit/FitStaticServiceFactory.java | 2 +-
.../src/main/java/processor/AnnotationSampleServiceFactory.java | 2 +-
11 files changed, 11 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java b/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java
index 9130a19..a7cc61d 100644
--- a/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java
+++ b/odata2-annotation-processor/annotation-processor-ref/src/main/java/org/apache/olingo/odata2/annotation/processor/ref/AnnotationRefServiceFactory.java
@@ -77,7 +77,7 @@ public class AnnotationRefServiceFactory extends ODataServiceFactory {
@SuppressWarnings("unchecked")
@Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
return (T) (callbackInterface.isAssignableFrom(ScenarioErrorCallback.class)
? new ScenarioErrorCallback() : callbackInterface.isAssignableFrom(ODataDebugCallback.class)
? new ScenarioDebugCallback() : super.getCallback(callbackInterface));
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java
index bb982b8..5566ada 100644
--- a/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java
+++ b/odata2-jpa-processor/jpa-api/src/main/java/org/apache/olingo/odata2/jpa/processor/api/ODataJPAServiceFactory.java
@@ -159,7 +159,7 @@ public abstract class ODataJPAServiceFactory extends ODataServiceFactory {
@SuppressWarnings("unchecked")
@Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
if (setDetailErrors == true) {
if (callbackInterface.isAssignableFrom(ODataErrorCallback.class)) {
return (T) new ODataJPAErrorCallback();
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java
index 7b6f7a3..681b70d 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java
@@ -70,7 +70,7 @@ public abstract class ODataServiceFactory {
* @param callbackInterface a interface type to query for implementation
* @return a callback implementation for this interface or null
*/
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
return null;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataExceptionWrapperTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataExceptionWrapperTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataExceptionWrapperTest.java
index a2fe86c..98c6b26 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataExceptionWrapperTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataExceptionWrapperTest.java
@@ -118,7 +118,7 @@ public class ODataExceptionWrapperTest extends BaseTest {
@SuppressWarnings("unchecked")
@Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
if (callbackInterface == ODataErrorCallback.class) {
if (errorCallback == null) {
return (T) new ODataErrorHandlerCallbackImpl();
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/rest/ODataServiceFactoryWithCallbackImpl.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/rest/ODataServiceFactoryWithCallbackImpl.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/rest/ODataServiceFactoryWithCallbackImpl.java
index c210de6..0d24da4 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/rest/ODataServiceFactoryWithCallbackImpl.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/rest/ODataServiceFactoryWithCallbackImpl.java
@@ -38,7 +38,7 @@ public class ODataServiceFactoryWithCallbackImpl extends ODataServiceFactory {
@SuppressWarnings("unchecked")
@Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
T callback = null;
if (callbackInterface == ODataErrorCallback.class) {
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/misc/ODataApplicationFactory.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/misc/ODataApplicationFactory.java b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/misc/ODataApplicationFactory.java
index e28aad2..7577cc8 100644
--- a/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/misc/ODataApplicationFactory.java
+++ b/odata2-lib/odata-fit/src/test/java/org/apache/olingo/odata2/fit/misc/ODataApplicationFactory.java
@@ -33,7 +33,7 @@ public class ODataApplicationFactory extends ODataServiceFactory {
}
@Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
return new ScenarioServiceFactory().getCallback(callbackInterface);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java
index d3075da..add23f9 100644
--- a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java
+++ b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ScenarioServiceFactory.java
@@ -44,7 +44,7 @@ public class ScenarioServiceFactory extends ODataServiceFactory {
@SuppressWarnings("unchecked")
@Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
return (T) (callbackInterface.isAssignableFrom(ScenarioErrorCallback.class) ?
new ScenarioErrorCallback() : callbackInterface.isAssignableFrom(ODataDebugCallback.class) ?
new ScenarioDebugCallback() : super.getCallback(callbackInterface));
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/DebugCallbackFactoryFlase.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/DebugCallbackFactoryFlase.java b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/DebugCallbackFactoryFlase.java
index 9e7cdc6..fc71390 100644
--- a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/DebugCallbackFactoryFlase.java
+++ b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/DebugCallbackFactoryFlase.java
@@ -25,7 +25,7 @@ public class DebugCallbackFactoryFlase extends FitStaticServiceFactory {
@SuppressWarnings("unchecked")
@Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
if (callbackInterface.isAssignableFrom(FitErrorCallback.class)) {
return (T) new FitErrorCallback();
} else if (callbackInterface.isAssignableFrom(ODataDebugCallback.class)) {
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/DebugCallbackFactoryTrue.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/DebugCallbackFactoryTrue.java b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/DebugCallbackFactoryTrue.java
index 66f483d..ba7248b 100644
--- a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/DebugCallbackFactoryTrue.java
+++ b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/DebugCallbackFactoryTrue.java
@@ -25,7 +25,7 @@ public class DebugCallbackFactoryTrue extends FitStaticServiceFactory {
@SuppressWarnings("unchecked")
@Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
if (callbackInterface.isAssignableFrom(FitErrorCallback.class)) {
return (T) new FitErrorCallback();
} else if (callbackInterface.isAssignableFrom(ODataDebugCallback.class)) {
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/FitStaticServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/FitStaticServiceFactory.java b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/FitStaticServiceFactory.java
index 0a86faf..fd8a9ea 100644
--- a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/FitStaticServiceFactory.java
+++ b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/fit/FitStaticServiceFactory.java
@@ -40,7 +40,7 @@ public class FitStaticServiceFactory extends ODataServiceFactory {
@SuppressWarnings("unchecked")
@Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
if (callbackInterface.isAssignableFrom(FitErrorCallback.class)) {
return (T) new FitErrorCallback();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5f81a5c4/odata2-sample/cars-annotation-archetype/src/main/resources/archetype-resources/src/main/java/processor/AnnotationSampleServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-sample/cars-annotation-archetype/src/main/resources/archetype-resources/src/main/java/processor/AnnotationSampleServiceFactory.java b/odata2-sample/cars-annotation-archetype/src/main/resources/archetype-resources/src/main/java/processor/AnnotationSampleServiceFactory.java
index fc8ebb2..c244bf6 100644
--- a/odata2-sample/cars-annotation-archetype/src/main/resources/archetype-resources/src/main/java/processor/AnnotationSampleServiceFactory.java
+++ b/odata2-sample/cars-annotation-archetype/src/main/resources/archetype-resources/src/main/java/processor/AnnotationSampleServiceFactory.java
@@ -69,7 +69,7 @@ public class AnnotationSampleServiceFactory extends ODataServiceFactory {
@SuppressWarnings("unchecked")
@Override
- public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+ public <T extends ODataCallback> T getCallback(final Class<T> callbackInterface) {
return (T) (callbackInterface.isAssignableFrom(ScenarioErrorCallback.class)
? new ScenarioErrorCallback() : callbackInterface.isAssignableFrom(ODataDebugCallback.class)
? new ScenarioDebugCallback() : super.getCallback(callbackInterface));
[4/4] olingo-odata2 git commit: Merge branch
'OLINGO-709-InjectODataServiceFactory'
Posted by mi...@apache.org.
Merge branch 'OLINGO-709-InjectODataServiceFactory'
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/438f7a95
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/438f7a95
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/438f7a95
Branch: refs/heads/master
Commit: 438f7a95e6209aafb763d3790f260efd6067d0d7
Parents: 5f81a5c ac22319
Author: mibo <mi...@mirb.de>
Authored: Sat Jun 27 11:45:03 2015 +0200
Committer: mibo <mi...@mirb.de>
Committed: Sat Jun 27 11:45:03 2015 +0200
----------------------------------------------------------------------
.../olingo/odata2/api/ODataServiceFactory.java | 5 +
.../odata2/core/servlet/ODataServlet.java | 112 +++++++++++++------
.../olingo/odata2/core/servlet/RestUtil.java | 5 +-
.../odata2/core/servlet/ODataServletTest.java | 54 +++++----
4 files changed, 120 insertions(+), 56 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/438f7a95/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java
----------------------------------------------------------------------
[3/4] olingo-odata2 git commit: [OLINGO-709] Merged abstract with
concrete ODataServlet
Posted by mi...@apache.org.
[OLINGO-709] Merged abstract with concrete ODataServlet
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/ac223196
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/ac223196
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/ac223196
Branch: refs/heads/master
Commit: ac22319687de5c2da1f58e3667612803fd6ffd2a
Parents: f1ca1a2
Author: Michael Bolz <mi...@sap.com>
Authored: Tue Jun 23 13:39:09 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Tue Jun 23 13:39:09 2015 +0200
----------------------------------------------------------------------
.../core/servlet/AbstractODataServlet.java | 350 -------------------
.../odata2/core/servlet/ODataServlet.java | 321 ++++++++++++++++-
.../core/servlet/AbstractODataServletTest.java | 280 ---------------
.../odata2/core/servlet/ODataServletTest.java | 8 +-
4 files changed, 322 insertions(+), 637 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ac223196/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/AbstractODataServlet.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/AbstractODataServlet.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/AbstractODataServlet.java
deleted file mode 100644
index 2fc6972..0000000
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/AbstractODataServlet.java
+++ /dev/null
@@ -1,350 +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.odata2.core.servlet;
-
-import org.apache.olingo.odata2.api.ODataService;
-import org.apache.olingo.odata2.api.ODataServiceFactory;
-import org.apache.olingo.odata2.api.commons.HttpHeaders;
-import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
-import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
-import org.apache.olingo.odata2.api.exception.MessageReference;
-import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
-import org.apache.olingo.odata2.api.exception.ODataHttpException;
-import org.apache.olingo.odata2.api.exception.ODataInternalServerErrorException;
-import org.apache.olingo.odata2.api.exception.ODataMethodNotAllowedException;
-import org.apache.olingo.odata2.api.exception.ODataNotAcceptableException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.processor.ODataRequest;
-import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.core.ODataContextImpl;
-import org.apache.olingo.odata2.core.ODataRequestHandler;
-import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-
-public abstract class AbstractODataServlet extends HttpServlet {
-
- private static final String HTTP_METHOD_OPTIONS = "OPTIONS";
- private static final String HTTP_METHOD_HEAD = "HEAD";
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Get the service factory instance which is used for creation of the
- * <code>ODataService</code> which handles the processing of the request.
- *
- * @param request the http request which is processed as an OData request
- * @return an instance of an ODataServiceFactory
- */
- protected abstract ODataServiceFactory getServiceFactory(HttpServletRequest request);
-
- @Override
- protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
- // We have to create the Service Factory here because otherwise we do not have access to the error callback
- ODataServiceFactory serviceFactory = getServiceFactory(req);
- if(serviceFactory == null) {
- throw new ODataRuntimeException("Unable to get Service Factory. Check either '" +
- ODataServiceFactory.FACTORY_LABEL + "' or '" + ODataServiceFactory.FACTORY_INSTANCE_LABEL + "' config.");
- }
-
- String xHttpMethod = req.getHeader("X-HTTP-Method");
- String xHttpMethodOverride = req.getHeader("X-HTTP-Method-Override");
- if (xHttpMethod != null && xHttpMethodOverride != null) {
- if (!xHttpMethod.equalsIgnoreCase(xHttpMethodOverride)) {
- ODataExceptionWrapper wrapper = new ODataExceptionWrapper(req, serviceFactory);
- createResponse(resp, wrapper.wrapInExceptionResponse(
- new ODataBadRequestException(ODataBadRequestException.AMBIGUOUS_XMETHOD)));
- }
- }
-
- if (req.getPathInfo() != null) {
- handle(req, resp, xHttpMethod, xHttpMethodOverride, serviceFactory);
- } else {
- handleRedirect(req, resp, serviceFactory);
- }
- }
-
-
- protected void handle(final HttpServletRequest req, final HttpServletResponse resp, final String xHttpMethod,
- final String xHttpMethodOverride, ODataServiceFactory serviceFactory) throws IOException {
- String method = req.getMethod();
- if (ODataHttpMethod.GET.name().equals(method)) {
- handleRequest(req, ODataHttpMethod.GET, resp, serviceFactory);
- } else if (ODataHttpMethod.POST.name().equals(method)) {
- if (xHttpMethod == null && xHttpMethodOverride == null) {
- handleRequest(req, ODataHttpMethod.POST, resp, serviceFactory);
- } else if (xHttpMethod == null) {
- /* tunneling */
- boolean methodHandled = handleHttpTunneling(req, resp, xHttpMethodOverride, serviceFactory);
- if (!methodHandled) {
- createMethodNotAllowedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
- }
- } else {
- /* tunneling */
- boolean methodHandled = handleHttpTunneling(req, resp, xHttpMethod, serviceFactory);
- if (!methodHandled) {
- createNotImplementedResponse(req, ODataNotImplementedException.TUNNELING, resp, serviceFactory);
- }
- }
-
- } else if (ODataHttpMethod.PUT.name().equals(method)) {
- handleRequest(req, ODataHttpMethod.PUT, resp, serviceFactory);
- } else if (ODataHttpMethod.DELETE.name().equals(method)) {
- handleRequest(req, ODataHttpMethod.DELETE, resp, serviceFactory);
- } else if (ODataHttpMethod.PATCH.name().equals(method)) {
- handleRequest(req, ODataHttpMethod.PATCH, resp, serviceFactory);
- } else if (ODataHttpMethod.MERGE.name().equals(method)) {
- handleRequest(req, ODataHttpMethod.MERGE, resp, serviceFactory);
- } else if (HTTP_METHOD_HEAD.equals(method) || HTTP_METHOD_OPTIONS.equals(method)) {
- createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
- } else {
- createNotImplementedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
- }
- }
-
- private boolean handleHttpTunneling(final HttpServletRequest req, final HttpServletResponse resp,
- final String xHttpMethod, ODataServiceFactory serviceFactory) throws IOException {
- if (ODataHttpMethod.MERGE.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.MERGE, resp, serviceFactory);
- } else if (ODataHttpMethod.PATCH.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.PATCH, resp, serviceFactory);
- } else if (ODataHttpMethod.DELETE.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.DELETE, resp, serviceFactory);
- } else if (ODataHttpMethod.PUT.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.PUT, resp, serviceFactory);
- } else if (ODataHttpMethod.GET.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.GET, resp, serviceFactory);
- } else if (ODataHttpMethod.POST.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.POST, resp, serviceFactory);
- } else if (HTTP_METHOD_HEAD.equals(xHttpMethod) || HTTP_METHOD_OPTIONS.equals(xHttpMethod)) {
- createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
- } else {
- createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
- }
- return true;
- }
-
- private void
- handleRequest(final HttpServletRequest req, final ODataHttpMethod method, final HttpServletResponse resp,
- ODataServiceFactory serviceFactory)
- throws IOException {
- try {
- final String pathSplitAsString = getInitParameter(ODataServiceFactory.PATH_SPLIT_LABEL);
- int pathSplit = 0;
- if (pathSplitAsString != null) {
- pathSplit = Integer.parseInt(pathSplitAsString);
- }
- if (req.getHeader(HttpHeaders.ACCEPT) != null && req.getHeader(HttpHeaders.ACCEPT).isEmpty()) {
- createNotAcceptableResponse(req, ODataNotAcceptableException.COMMON, resp, serviceFactory);
- }
- ODataRequest odataRequest = ODataRequest.method(method)
- .contentType(RestUtil.extractRequestContentType(req.getContentType()).toContentTypeString())
- .acceptHeaders(RestUtil.extractAcceptHeaders(req.getHeader(HttpHeaders.ACCEPT)))
- .acceptableLanguages(RestUtil.extractAcceptableLanguage(req.getHeader(HttpHeaders.ACCEPT_LANGUAGE)))
- .pathInfo(RestUtil.buildODataPathInfo(req, pathSplit))
- .allQueryParameters(RestUtil.extractAllQueryParameters(req.getQueryString()))
- .requestHeaders(RestUtil.extractHeaders(req))
- .body(req.getInputStream())
- .build();
-
- ODataContextImpl context = new ODataContextImpl(odataRequest, serviceFactory);
- context.setParameter(ODataContext.HTTP_SERVLET_REQUEST_OBJECT, req);
-
- ODataService service = serviceFactory.createService(context);
- if (service == null) {
- createServiceUnavailableResponse(req, ODataInternalServerErrorException.NOSERVICE, resp, serviceFactory);
- } else {
- context.setService(service);
- service.getProcessor().setContext(context);
-
- ODataRequestHandler requestHandler = new ODataRequestHandler(serviceFactory, service, context);
- final ODataResponse odataResponse = requestHandler.handle(odataRequest);
- createResponse(resp, odataResponse);
- }
- } catch (Exception e) {
- ODataExceptionWrapper wrapper = new ODataExceptionWrapper(req, serviceFactory);
- createResponse(resp, wrapper.wrapInExceptionResponse(e));
- }
- }
-
- protected void handleRedirect(final HttpServletRequest req, final HttpServletResponse resp,
- ODataServiceFactory serviceFactory) throws IOException {
- String method = req.getMethod();
- if (ODataHttpMethod.GET.name().equals(method) ||
- ODataHttpMethod.POST.name().equals(method) ||
- ODataHttpMethod.PUT.name().equals(method) ||
- ODataHttpMethod.DELETE.name().equals(method) ||
- ODataHttpMethod.PATCH.name().equals(method) ||
- ODataHttpMethod.MERGE.name().equals(method) ||
- HTTP_METHOD_HEAD.equals(method) ||
- HTTP_METHOD_OPTIONS.equals(method)) {
- ODataResponse odataResponse = ODataResponse.status(HttpStatusCodes.TEMPORARY_REDIRECT)
- .header(HttpHeaders.LOCATION, createLocation(req))
- .build();
- createResponse(resp, odataResponse);
- } else {
- createNotImplementedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
- }
-
- }
-
- private String createLocation(final HttpServletRequest req) {
- StringBuilder location = new StringBuilder();
- String contextPath = req.getContextPath();
- if (contextPath != null) {
- location.append(contextPath);
- }
- String servletPath = req.getServletPath();
- if (servletPath != null) {
- location.append(servletPath);
- }
- location.append("/");
- return location.toString();
- }
-
- protected void createResponse(final HttpServletResponse resp, final ODataResponse response) throws IOException {
- resp.setStatus(response.getStatus().getStatusCode());
- resp.setContentType(response.getContentHeader());
- for (String headerName : response.getHeaderNames()) {
- resp.setHeader(headerName, response.getHeader(headerName));
- }
-
- Object entity = response.getEntity();
- if (entity != null) {
- ServletOutputStream out = resp.getOutputStream();
- int curByte;
- int contentLength = 0;
-
- if (entity instanceof InputStream) {
- while ((curByte = ((InputStream) entity).read()) != -1) {
- contentLength++;
- out.write((char) curByte);
- }
- ((InputStream) entity).close();
- } else if (entity instanceof String) {
- String body = (String) entity;
- final byte[] entityBytes = body.getBytes("utf-8");
- out.write(entityBytes);
- contentLength = entityBytes.length;
- }
-
- if (response.getHeader(HttpHeaders.CONTENT_LENGTH) != null) {
- // Override content length
- try {
- contentLength = Integer.parseInt(response.getHeader(HttpHeaders.CONTENT_LENGTH));
- } catch (NumberFormatException e) {
- // Ignore
- }
- }
-
- resp.setContentLength(contentLength);
- out.flush();
- out.close();
- }
- }
-
- private void createNotImplementedResponse(final HttpServletRequest req, final MessageReference messageReference,
- final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
- // RFC 2616, 5.1.1: "An origin server SHOULD return the status code [...]
- // 501 (Not Implemented) if the method is unrecognized [...] by the origin server."
- ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
- ODataResponse response =
- exceptionWrapper.wrapInExceptionResponse(new ODataNotImplementedException(messageReference));
-// resp.setStatus(HttpStatusCodes.NOT_IMPLEMENTED.getStatusCode());
- createResponse(resp, response);
- }
-
- private void createMethodNotAllowedResponse(final HttpServletRequest req, final MessageReference messageReference,
- final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
- ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
- ODataResponse response =
- exceptionWrapper.wrapInExceptionResponse(new ODataMethodNotAllowedException(messageReference));
- createResponse(resp, response);
- }
-
- private void createNotAcceptableResponse(final HttpServletRequest req, final MessageReference messageReference,
- final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
- ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
- ODataResponse response =
- exceptionWrapper.wrapInExceptionResponse(new ODataNotAcceptableException(messageReference));
- createResponse(resp, response);
- }
-
- private void createServiceUnavailableResponse(HttpServletRequest req, MessageReference messageReference,
- HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
- ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
- ODataResponse response =
- exceptionWrapper.wrapInExceptionResponse(new ODataInternalServerErrorException(messageReference));
- createResponse(resp, response);
- }
-
- /**
- * Create an instance of a ODataServiceFactory via factory class
- * from servlet init parameter ODataServiceFactory.FACTORY_LABEL
- * and ODataServiceFactory.FACTORY_CLASSLOADER_LABEL (if set).
- *
- * @see ODataServiceFactory#FACTORY_LABEL
- * @see ODataServiceFactory#FACTORY_CLASSLOADER_LABEL
- *
- * @param req http servlet request
- * @return instance of a ODataServiceFactory
- */
- protected ODataServiceFactory createODataServiceFactory(HttpServletRequest req)
- throws InstantiationException, IllegalAccessException, ClassNotFoundException {
- final String factoryClassName = getInitParameter(ODataServiceFactory.FACTORY_LABEL);
- if(factoryClassName == null) {
- return null;
- }
-
- ClassLoader cl = (ClassLoader) req.getAttribute(ODataServiceFactory.FACTORY_CLASSLOADER_LABEL);
- if (cl == null) {
- return (ODataServiceFactory) Class.forName(factoryClassName).newInstance();
- } else {
- return (ODataServiceFactory) Class.forName(factoryClassName, true, cl).newInstance();
- }
- }
-
- /**
- * Get an instance of a ODataServiceFactory from request attribute
- * ODataServiceFactory.FACTORY_INSTANCE_LABEL
- *
- * @see ODataServiceFactory#FACTORY_INSTANCE_LABEL
- *
- * @param req http servlet request
- * @return instance of a ODataServiceFactory
- */
- protected ODataServiceFactory getServiceFactoryInstance(HttpServletRequest req) {
- Object factory = req.getAttribute(ODataServiceFactory.FACTORY_INSTANCE_LABEL);
- if(factory == null) {
- return null;
- } else if(factory instanceof ODataServiceFactory) {
- return (ODataServiceFactory) factory;
- }
- throw new ODataRuntimeException("Invalid service factory instance of type " + factory.getClass());
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ac223196/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
index d3e95e8..1aaf9d8 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
@@ -18,21 +18,78 @@
******************************************************************************/
package org.apache.olingo.odata2.core.servlet;
+import org.apache.olingo.odata2.api.ODataService;
import org.apache.olingo.odata2.api.ODataServiceFactory;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
+import org.apache.olingo.odata2.api.exception.MessageReference;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.api.exception.ODataHttpException;
+import org.apache.olingo.odata2.api.exception.ODataInternalServerErrorException;
+import org.apache.olingo.odata2.api.exception.ODataMethodNotAllowedException;
+import org.apache.olingo.odata2.api.exception.ODataNotAcceptableException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataRequest;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.core.ODataContextImpl;
+import org.apache.olingo.odata2.core.ODataRequestHandler;
import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
-public final class ODataServlet extends AbstractODataServlet {
+public class ODataServlet extends HttpServlet {
+ private static final String HTTP_METHOD_OPTIONS = "OPTIONS";
+ private static final String HTTP_METHOD_HEAD = "HEAD";
+
+ /**
+ *
+ */
private static final long serialVersionUID = 1L;
+ @Override
+ protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
+ // We have to create the Service Factory here because otherwise we do not have access to the error callback
+ ODataServiceFactory serviceFactory = getServiceFactory(req);
+ if(serviceFactory == null) {
+ throw new ODataRuntimeException("Unable to get Service Factory. Check either '" +
+ ODataServiceFactory.FACTORY_LABEL + "' or '" + ODataServiceFactory.FACTORY_INSTANCE_LABEL + "' config.");
+ }
+
+ String xHttpMethod = req.getHeader("X-HTTP-Method");
+ String xHttpMethodOverride = req.getHeader("X-HTTP-Method-Override");
+ if (xHttpMethod != null && xHttpMethodOverride != null) {
+ if (!xHttpMethod.equalsIgnoreCase(xHttpMethodOverride)) {
+ ODataExceptionWrapper wrapper = new ODataExceptionWrapper(req, serviceFactory);
+ createResponse(resp, wrapper.wrapInExceptionResponse(
+ new ODataBadRequestException(ODataBadRequestException.AMBIGUOUS_XMETHOD)));
+ }
+ }
+
+ if (req.getPathInfo() != null) {
+ handle(req, resp, xHttpMethod, xHttpMethodOverride, serviceFactory);
+ } else {
+ handleRedirect(req, resp, serviceFactory);
+ }
+ }
+
/**
- * @{inherit}
+ * Get the service factory instance which is used for creation of the
+ * <code>ODataService</code> which handles the processing of the request.
+ *
+ * @param request the http request which is processed as an OData request
+ * @return an instance of an ODataServiceFactory
*/
protected ODataServiceFactory getServiceFactory(HttpServletRequest request) {
try {
- ODataServiceFactory factoryInstance = getServiceFactoryInstance(request);
+ ODataServiceFactory factoryInstance = getODataServiceFactoryInstance(request);
if(factoryInstance == null) {
return createODataServiceFactory(request);
}
@@ -42,4 +99,262 @@ public final class ODataServlet extends AbstractODataServlet {
throw new ODataRuntimeException(e);
}
}
+
+ protected void handle(final HttpServletRequest req, final HttpServletResponse resp, final String xHttpMethod,
+ final String xHttpMethodOverride, ODataServiceFactory serviceFactory) throws IOException {
+ String method = req.getMethod();
+ if (ODataHttpMethod.GET.name().equals(method)) {
+ handleRequest(req, ODataHttpMethod.GET, resp, serviceFactory);
+ } else if (ODataHttpMethod.POST.name().equals(method)) {
+ if (xHttpMethod == null && xHttpMethodOverride == null) {
+ handleRequest(req, ODataHttpMethod.POST, resp, serviceFactory);
+ } else if (xHttpMethod == null) {
+ /* tunneling */
+ boolean methodHandled = handleHttpTunneling(req, resp, xHttpMethodOverride, serviceFactory);
+ if (!methodHandled) {
+ createMethodNotAllowedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
+ }
+ } else {
+ /* tunneling */
+ boolean methodHandled = handleHttpTunneling(req, resp, xHttpMethod, serviceFactory);
+ if (!methodHandled) {
+ createNotImplementedResponse(req, ODataNotImplementedException.TUNNELING, resp, serviceFactory);
+ }
+ }
+
+ } else if (ODataHttpMethod.PUT.name().equals(method)) {
+ handleRequest(req, ODataHttpMethod.PUT, resp, serviceFactory);
+ } else if (ODataHttpMethod.DELETE.name().equals(method)) {
+ handleRequest(req, ODataHttpMethod.DELETE, resp, serviceFactory);
+ } else if (ODataHttpMethod.PATCH.name().equals(method)) {
+ handleRequest(req, ODataHttpMethod.PATCH, resp, serviceFactory);
+ } else if (ODataHttpMethod.MERGE.name().equals(method)) {
+ handleRequest(req, ODataHttpMethod.MERGE, resp, serviceFactory);
+ } else if (HTTP_METHOD_HEAD.equals(method) || HTTP_METHOD_OPTIONS.equals(method)) {
+ createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
+ } else {
+ createNotImplementedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
+ }
+ }
+
+ private boolean handleHttpTunneling(final HttpServletRequest req, final HttpServletResponse resp,
+ final String xHttpMethod, ODataServiceFactory serviceFactory) throws IOException {
+ if (ODataHttpMethod.MERGE.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.MERGE, resp, serviceFactory);
+ } else if (ODataHttpMethod.PATCH.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.PATCH, resp, serviceFactory);
+ } else if (ODataHttpMethod.DELETE.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.DELETE, resp, serviceFactory);
+ } else if (ODataHttpMethod.PUT.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.PUT, resp, serviceFactory);
+ } else if (ODataHttpMethod.GET.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.GET, resp, serviceFactory);
+ } else if (ODataHttpMethod.POST.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.POST, resp, serviceFactory);
+ } else if (HTTP_METHOD_HEAD.equals(xHttpMethod) || HTTP_METHOD_OPTIONS.equals(xHttpMethod)) {
+ createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
+ } else {
+ createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
+ }
+ return true;
+ }
+
+ private void
+ handleRequest(final HttpServletRequest req, final ODataHttpMethod method, final HttpServletResponse resp,
+ ODataServiceFactory serviceFactory)
+ throws IOException {
+ try {
+ final String pathSplitAsString = getInitParameter(ODataServiceFactory.PATH_SPLIT_LABEL);
+ int pathSplit = 0;
+ if (pathSplitAsString != null) {
+ pathSplit = Integer.parseInt(pathSplitAsString);
+ }
+ if (req.getHeader(HttpHeaders.ACCEPT) != null && req.getHeader(HttpHeaders.ACCEPT).isEmpty()) {
+ createNotAcceptableResponse(req, ODataNotAcceptableException.COMMON, resp, serviceFactory);
+ }
+ ODataRequest odataRequest = ODataRequest.method(method)
+ .contentType(RestUtil.extractRequestContentType(req.getContentType()).toContentTypeString())
+ .acceptHeaders(RestUtil.extractAcceptHeaders(req.getHeader(HttpHeaders.ACCEPT)))
+ .acceptableLanguages(RestUtil.extractAcceptableLanguage(req.getHeader(HttpHeaders.ACCEPT_LANGUAGE)))
+ .pathInfo(RestUtil.buildODataPathInfo(req, pathSplit))
+ .allQueryParameters(RestUtil.extractAllQueryParameters(req.getQueryString()))
+ .requestHeaders(RestUtil.extractHeaders(req))
+ .body(req.getInputStream())
+ .build();
+
+ ODataContextImpl context = new ODataContextImpl(odataRequest, serviceFactory);
+ context.setParameter(ODataContext.HTTP_SERVLET_REQUEST_OBJECT, req);
+
+ ODataService service = serviceFactory.createService(context);
+ if (service == null) {
+ createServiceUnavailableResponse(req, ODataInternalServerErrorException.NOSERVICE, resp, serviceFactory);
+ } else {
+ context.setService(service);
+ service.getProcessor().setContext(context);
+
+ ODataRequestHandler requestHandler = new ODataRequestHandler(serviceFactory, service, context);
+ final ODataResponse odataResponse = requestHandler.handle(odataRequest);
+ createResponse(resp, odataResponse);
+ }
+ } catch (Exception e) {
+ ODataExceptionWrapper wrapper = new ODataExceptionWrapper(req, serviceFactory);
+ createResponse(resp, wrapper.wrapInExceptionResponse(e));
+ }
+ }
+
+ protected void handleRedirect(final HttpServletRequest req, final HttpServletResponse resp,
+ ODataServiceFactory serviceFactory) throws IOException {
+ String method = req.getMethod();
+ if (ODataHttpMethod.GET.name().equals(method) ||
+ ODataHttpMethod.POST.name().equals(method) ||
+ ODataHttpMethod.PUT.name().equals(method) ||
+ ODataHttpMethod.DELETE.name().equals(method) ||
+ ODataHttpMethod.PATCH.name().equals(method) ||
+ ODataHttpMethod.MERGE.name().equals(method) ||
+ HTTP_METHOD_HEAD.equals(method) ||
+ HTTP_METHOD_OPTIONS.equals(method)) {
+ ODataResponse odataResponse = ODataResponse.status(HttpStatusCodes.TEMPORARY_REDIRECT)
+ .header(HttpHeaders.LOCATION, createLocation(req))
+ .build();
+ createResponse(resp, odataResponse);
+ } else {
+ createNotImplementedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
+ }
+
+ }
+
+ private String createLocation(final HttpServletRequest req) {
+ StringBuilder location = new StringBuilder();
+ String contextPath = req.getContextPath();
+ if (contextPath != null) {
+ location.append(contextPath);
+ }
+ String servletPath = req.getServletPath();
+ if (servletPath != null) {
+ location.append(servletPath);
+ }
+ location.append("/");
+ return location.toString();
+ }
+
+ protected void createResponse(final HttpServletResponse resp, final ODataResponse response) throws IOException {
+ resp.setStatus(response.getStatus().getStatusCode());
+ resp.setContentType(response.getContentHeader());
+ for (String headerName : response.getHeaderNames()) {
+ resp.setHeader(headerName, response.getHeader(headerName));
+ }
+
+ Object entity = response.getEntity();
+ if (entity != null) {
+ ServletOutputStream out = resp.getOutputStream();
+ int curByte;
+ int contentLength = 0;
+
+ if (entity instanceof InputStream) {
+ while ((curByte = ((InputStream) entity).read()) != -1) {
+ contentLength++;
+ out.write((char) curByte);
+ }
+ ((InputStream) entity).close();
+ } else if (entity instanceof String) {
+ String body = (String) entity;
+ final byte[] entityBytes = body.getBytes("utf-8");
+ out.write(entityBytes);
+ contentLength = entityBytes.length;
+ }
+
+ if (response.getHeader(HttpHeaders.CONTENT_LENGTH) != null) {
+ // Override content length
+ try {
+ contentLength = Integer.parseInt(response.getHeader(HttpHeaders.CONTENT_LENGTH));
+ } catch (NumberFormatException e) {
+ // Ignore
+ }
+ }
+
+ resp.setContentLength(contentLength);
+ out.flush();
+ out.close();
+ }
+ }
+
+ private void createNotImplementedResponse(final HttpServletRequest req, final MessageReference messageReference,
+ final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
+ // RFC 2616, 5.1.1: "An origin server SHOULD return the status code [...]
+ // 501 (Not Implemented) if the method is unrecognized [...] by the origin server."
+ ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
+ ODataResponse response =
+ exceptionWrapper.wrapInExceptionResponse(new ODataNotImplementedException(messageReference));
+// resp.setStatus(HttpStatusCodes.NOT_IMPLEMENTED.getStatusCode());
+ createResponse(resp, response);
+ }
+
+ private void createMethodNotAllowedResponse(final HttpServletRequest req, final MessageReference messageReference,
+ final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
+ ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
+ ODataResponse response =
+ exceptionWrapper.wrapInExceptionResponse(new ODataMethodNotAllowedException(messageReference));
+ createResponse(resp, response);
+ }
+
+ private void createNotAcceptableResponse(final HttpServletRequest req, final MessageReference messageReference,
+ final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
+ ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
+ ODataResponse response =
+ exceptionWrapper.wrapInExceptionResponse(new ODataNotAcceptableException(messageReference));
+ createResponse(resp, response);
+ }
+
+ private void createServiceUnavailableResponse(HttpServletRequest req, MessageReference messageReference,
+ HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
+ ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
+ ODataResponse response =
+ exceptionWrapper.wrapInExceptionResponse(new ODataInternalServerErrorException(messageReference));
+ createResponse(resp, response);
+ }
+
+ /**
+ * Create an instance of a ODataServiceFactory via factory class
+ * from servlet init parameter ODataServiceFactory.FACTORY_LABEL
+ * and ODataServiceFactory.FACTORY_CLASSLOADER_LABEL (if set).
+ *
+ * @see ODataServiceFactory#FACTORY_LABEL
+ * @see ODataServiceFactory#FACTORY_CLASSLOADER_LABEL
+ *
+ * @param req http servlet request
+ * @return instance of a ODataServiceFactory
+ */
+ private ODataServiceFactory createODataServiceFactory(HttpServletRequest req)
+ throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+ final String factoryClassName = getInitParameter(ODataServiceFactory.FACTORY_LABEL);
+ if(factoryClassName == null) {
+ return null;
+ }
+
+ ClassLoader cl = (ClassLoader) req.getAttribute(ODataServiceFactory.FACTORY_CLASSLOADER_LABEL);
+ if (cl == null) {
+ return (ODataServiceFactory) Class.forName(factoryClassName).newInstance();
+ } else {
+ return (ODataServiceFactory) Class.forName(factoryClassName, true, cl).newInstance();
+ }
+ }
+
+ /**
+ * Get an instance of a ODataServiceFactory from request attribute
+ * ODataServiceFactory.FACTORY_INSTANCE_LABEL
+ *
+ * @see ODataServiceFactory#FACTORY_INSTANCE_LABEL
+ *
+ * @param req http servlet request
+ * @return instance of a ODataServiceFactory
+ */
+ private ODataServiceFactory getODataServiceFactoryInstance(HttpServletRequest req) {
+ Object factory = req.getAttribute(ODataServiceFactory.FACTORY_INSTANCE_LABEL);
+ if(factory == null) {
+ return null;
+ } else if(factory instanceof ODataServiceFactory) {
+ return (ODataServiceFactory) factory;
+ }
+ throw new ODataRuntimeException("Invalid service factory instance of type " + factory.getClass());
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ac223196/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/AbstractODataServletTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/AbstractODataServletTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/AbstractODataServletTest.java
deleted file mode 100644
index de21917..0000000
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/AbstractODataServletTest.java
+++ /dev/null
@@ -1,280 +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.odata2.core.servlet;
-
-import junit.framework.Assert;
-import org.apache.olingo.odata2.api.ODataService;
-import org.apache.olingo.odata2.api.ODataServiceFactory;
-import org.apache.olingo.odata2.api.commons.HttpHeaders;
-import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.processor.ODataProcessor;
-import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.api.servicedocument.Collection;
-import org.apache.olingo.odata2.core.ODataResponseImpl;
-import org.apache.olingo.odata2.core.rest.ODataServiceFactoryImpl;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import javax.servlet.GenericServlet;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Collections;
-
-/**
- *
- */
-public class AbstractODataServletTest {
-
- private HttpServletRequest reqMock;
- private HttpServletResponse respMock;
- private ServletConfig configMock;
-
- public AbstractODataServletTest() {
- reqMock = Mockito.mock(HttpServletRequest.class);
- respMock = Mockito.mock(HttpServletResponse.class);
- configMock = Mockito.mock(ServletConfig.class);
- }
-
- private static class MyTestODataServlet extends AbstractODataServlet {
- enum ServiceFactorySource {INSTANCE, CLASSLOADER, MOCK};
-
- ODataServiceFactory viaInstance;
- ODataServiceFactory viaClassLoader;
- ODataServiceFactory viaMock;
- final ServiceFactorySource source;
-
- public MyTestODataServlet() {
- this(ServiceFactorySource.MOCK);
- }
-
- public MyTestODataServlet(ServiceFactorySource source) {
- this.source = source;
- }
-
- @Override
- protected ODataServiceFactory getServiceFactory(HttpServletRequest request) {
- viaInstance = getServiceFactoryInstance(request);
- try {
- viaClassLoader = createODataServiceFactory(request);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- viaMock = Mockito.mock(ODataServiceFactory.class);
-
- switch (source) {
- case INSTANCE: return viaInstance;
- case CLASSLOADER: return viaClassLoader;
- case MOCK: return viaMock;
- }
- return null;
- }
- }
-
- @Test
- public void handleRedirect() throws Exception {
- AbstractODataServlet servlet = new MyTestODataServlet();
- prepareServlet(servlet);
- prepareRequest(reqMock);
- servlet.service(reqMock, respMock);
-
- Mockito.verify(respMock).setStatus(HttpStatusCodes.TEMPORARY_REDIRECT.getStatusCode());
- Mockito.verify(respMock).setHeader(HttpHeaders.LOCATION, "/context-path/servlet-path/");
- }
-
- @Test
- public void handleRedirectWoServletPath() throws Exception {
- AbstractODataServlet servlet = new MyTestODataServlet();
- prepareServlet(servlet);
- prepareRequest(reqMock, "/context-path", null);
- servlet.service(reqMock, respMock);
-
- Mockito.verify(respMock).setStatus(HttpStatusCodes.TEMPORARY_REDIRECT.getStatusCode());
- Mockito.verify(respMock).setHeader(HttpHeaders.LOCATION, "/context-path/");
- }
-
- @Test
- public void handleRedirectWoContextPath() throws Exception {
- AbstractODataServlet servlet = new MyTestODataServlet();
- prepareServlet(servlet);
- prepareRequest(reqMock, null, "/servlet-path");
- servlet.service(reqMock, respMock);
-
- Mockito.verify(respMock).setStatus(HttpStatusCodes.TEMPORARY_REDIRECT.getStatusCode());
- Mockito.verify(respMock).setHeader(HttpHeaders.LOCATION, "/servlet-path/");
- }
-
- @Test
- public void handleRedirectWoPath() throws Exception {
- AbstractODataServlet servlet = new MyTestODataServlet();
- prepareServlet(servlet);
- prepareRequest(reqMock, null, null);
- servlet.service(reqMock, respMock);
-
- Mockito.verify(respMock).setStatus(HttpStatusCodes.TEMPORARY_REDIRECT.getStatusCode());
- Mockito.verify(respMock).setHeader(HttpHeaders.LOCATION, "/");
- }
-
- @Test
- public void contentLengthCalculatedString() throws Exception {
- final Method createResponse =
- AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
- createResponse.setAccessible(true);
-
- final AbstractODataServlet servlet = new MyTestODataServlet();
- final String content = "Test\r\n";
- final ODataResponse response = ODataResponseImpl.status(HttpStatusCodes.OK).entity(content).build();
- prepareResponseMockToWrite(respMock);
- prepareServlet(servlet);
-
- createResponse.invoke(servlet, respMock, response);
- Mockito.verify(respMock).setContentLength(content.getBytes("utf-8").length);
- }
-
- @Test
- public void contentLengthCalculatedStream() throws Exception {
- final Method createResponse =
- AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
- createResponse.setAccessible(true);
-
- final AbstractODataServlet servlet = new MyTestODataServlet();
- final String content = "Test\r\n";
-
- final ODataResponse response =
- ODataResponseImpl.status(HttpStatusCodes.OK).entity(new ByteArrayInputStream(content.getBytes("utf-8")))
- .build();
- prepareResponseMockToWrite(respMock);
- prepareServlet(servlet);
-
- createResponse.invoke(servlet, respMock, response);
- Mockito.verify(respMock).setContentLength(content.getBytes("utf-8").length);
- }
-
- @Test
- public void contentLengthHeader() throws Exception {
- final Method createResponse =
- AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
- createResponse.setAccessible(true);
- final AbstractODataServlet servlet = new MyTestODataServlet();
- final ODataResponse response =
- ODataResponseImpl.status(HttpStatusCodes.OK).header(HttpHeaders.CONTENT_LENGTH, "15").entity("").build();
- prepareResponseMockToWrite(respMock);
- prepareServlet(servlet);
-
- createResponse.invoke(servlet, respMock, response);
-
- Mockito.verify(respMock).setHeader(HttpHeaders.CONTENT_LENGTH, "15");
- Mockito.verify(respMock).setContentLength(15);
- }
-
- @Test
- public void contentLengthHeaderInvalid() throws Exception {
- final Method createResponse =
- AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
- createResponse.setAccessible(true);
- final AbstractODataServlet servlet = new MyTestODataServlet();
- final ODataResponse response =
- ODataResponseImpl.status(HttpStatusCodes.OK).header(HttpHeaders.CONTENT_LENGTH, "ab").entity("Test").build();
- prepareResponseMockToWrite(respMock);
- prepareServlet(servlet);
-
- createResponse.invoke(servlet, respMock, response);
-
- Mockito.verify(respMock).setHeader(HttpHeaders.CONTENT_LENGTH, "ab");
- Mockito.verify(respMock).setContentLength(4); // ||"Test"|| = 4
- }
-
- @Test
- public void serviceInstance() throws Exception {
- MyTestODataServlet servlet = new MyTestODataServlet(MyTestODataServlet.ServiceFactorySource.INSTANCE);
- prepareServlet(servlet, false);
- prepareRequest(reqMock, "", "/servlet-path");
- Mockito.when(reqMock.getPathInfo()).thenReturn("/request-path-info");
- Mockito.when(reqMock.getRequestURI()).thenReturn("http://localhost:8080/servlet-path/request-path-info");
- ODataServiceFactory factory = Mockito.mock(ODataServiceFactory.class);
- ODataService service = Mockito.mock(ODataService.class);
- Mockito.when(factory.createService(Mockito.any(ODataContext.class))).thenReturn(service);
- ODataProcessor processor = Mockito.mock(ODataProcessor.class);
- Mockito.when(service.getProcessor()).thenReturn(processor);
- Mockito.when(reqMock.getAttribute(ODataServiceFactory.FACTORY_INSTANCE_LABEL)).thenReturn(factory);
- Mockito.when(respMock.getOutputStream()).thenReturn(Mockito.mock(ServletOutputStream.class));
-
- servlet.service(reqMock, respMock);
-
- Mockito.verify(factory).createService(Mockito.any(ODataContext.class));
- Assert.assertNotNull(servlet.viaInstance);
- Assert.assertNull(servlet.viaClassLoader);
- }
-
- @Test
- public void serviceClassloader() throws Exception {
- MyTestODataServlet servlet = new MyTestODataServlet(MyTestODataServlet.ServiceFactorySource.CLASSLOADER);
- prepareServlet(servlet);
- prepareRequest(reqMock, "", "/servlet-path");
- Mockito.when(reqMock.getPathInfo()).thenReturn("/request-path-info");
- Mockito.when(reqMock.getRequestURI()).thenReturn("http://localhost:8080/servlet-path/request-path-info");
- Mockito.when(respMock.getOutputStream()).thenReturn(Mockito.mock(ServletOutputStream.class));
-
- servlet.service(reqMock, respMock);
-
- Assert.assertNull(servlet.viaInstance);
- Assert.assertNotNull(servlet.viaClassLoader);
- }
-
- private void prepareResponseMockToWrite(final HttpServletResponse response) throws IOException {
- Mockito.when(response.getOutputStream()).thenReturn(new ServletOutputStream() {
- @Override
- public void write(int b) throws IOException {}
- });
- }
-
- private void prepareRequest(final HttpServletRequest req, final String contextPath, final String servletPath) {
- Mockito.when(req.getMethod()).thenReturn("GET");
- Mockito.when(req.getContextPath()).thenReturn(contextPath);
- Mockito.when(req.getServletPath()).thenReturn(servletPath);
- Mockito.when(req.getHeaderNames()).thenReturn(Collections.emptyEnumeration());
- }
-
- private void prepareRequest(final HttpServletRequest req) {
- prepareRequest(req, "/context-path", "/servlet-path");
- }
-
- private void prepareServlet(final GenericServlet servlet) throws Exception {
- prepareServlet(servlet, true);
- }
-
- private void prepareServlet(final GenericServlet servlet, boolean withFactoryLabel) throws Exception {
- // private transient ServletConfig config;
- Field configField = GenericServlet.class.getDeclaredField("config");
- configField.setAccessible(true);
- configField.set(servlet, configMock);
-
- if(withFactoryLabel) {
- String factoryClassName = ODataServiceFactoryImpl.class.getName();
- Mockito.when(configMock.getInitParameter(ODataServiceFactory.FACTORY_LABEL)).thenReturn(factoryClassName);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ac223196/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/ODataServletTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/ODataServletTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/ODataServletTest.java
index e1ad5dc..da985e5 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/ODataServletTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/ODataServletTest.java
@@ -105,7 +105,7 @@ public class ODataServletTest {
@Test
public void contentLengthCalculatedString() throws Exception {
final Method createResponse =
- AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
+ ODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
createResponse.setAccessible(true);
final ODataServlet servlet = new ODataServlet();
@@ -121,7 +121,7 @@ public class ODataServletTest {
@Test
public void contentLengthCalculatedStream() throws Exception {
final Method createResponse =
- AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
+ ODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
createResponse.setAccessible(true);
final ODataServlet servlet = new ODataServlet();
@@ -171,7 +171,7 @@ public class ODataServletTest {
Mockito.verify(configMock).getInitParameter(ODataServiceFactory.FACTORY_LABEL);
Mockito.verify(reqMock).getAttribute(ODataServiceFactory.FACTORY_CLASSLOADER_LABEL);
- Assert.assertEquals(ODataServiceFactoryImpl.class, servlet.createODataServiceFactory(reqMock).getClass());
+ Assert.assertEquals(ODataServiceFactoryImpl.class, servlet.getServiceFactory(reqMock).getClass());
}
@@ -186,7 +186,7 @@ public class ODataServletTest {
Mockito.when(req.getMethod()).thenReturn("GET");
Mockito.when(req.getContextPath()).thenReturn(contextPath);
Mockito.when(req.getServletPath()).thenReturn(servletPath);
- Mockito.when(req.getHeaderNames()).thenReturn(Collections.emptyEnumeration());
+ Mockito.when(req.getHeaderNames()).thenReturn(Collections.enumeration(Collections.emptyList()));
}
private void prepareRequest(final HttpServletRequest req) {
[2/4] olingo-odata2 git commit: [OLINGO-709] Support injection of
ODataServiceFactory instance
Posted by mi...@apache.org.
[OLINGO-709] Support injection of ODataServiceFactory instance
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/f1ca1a20
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/f1ca1a20
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/f1ca1a20
Branch: refs/heads/master
Commit: f1ca1a20492c4a6d2e74bda0c1a21d0996a24c32
Parents: 5fc3ed2
Author: mibo <mi...@mirb.de>
Authored: Sun Jun 21 16:26:55 2015 +0200
Committer: mibo <mi...@mirb.de>
Committed: Sun Jun 21 16:57:24 2015 +0200
----------------------------------------------------------------------
.../olingo/odata2/api/ODataServiceFactory.java | 5 +
.../core/servlet/AbstractODataServlet.java | 350 +++++++++++++++++++
.../odata2/core/servlet/ODataServlet.java | 287 +--------------
.../olingo/odata2/core/servlet/RestUtil.java | 5 +-
.../core/servlet/AbstractODataServletTest.java | 280 +++++++++++++++
.../odata2/core/servlet/ODataServletTest.java | 58 +--
6 files changed, 682 insertions(+), 303 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f1ca1a20/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java
index 7b6f7a3..4b408c5 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ODataServiceFactory.java
@@ -42,6 +42,11 @@ public abstract class ODataServiceFactory {
public static final String FACTORY_CLASSLOADER_LABEL = "org.apache.olingo.odata2.service.factory.classloader";
/**
+ * Label used in web.xml to assign servlet init parameter to factory class instance.
+ */
+ public static final String FACTORY_INSTANCE_LABEL = "org.apache.olingo.odata2.service.factory.instance";
+
+ /**
* Label used in web.xml to assign servlet init parameter for a path split (service resolution).
*/
public static final String PATH_SPLIT_LABEL = "org.apache.olingo.odata2.path.split";
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f1ca1a20/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/AbstractODataServlet.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/AbstractODataServlet.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/AbstractODataServlet.java
new file mode 100644
index 0000000..2fc6972
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/AbstractODataServlet.java
@@ -0,0 +1,350 @@
+/*******************************************************************************
+ * 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.odata2.core.servlet;
+
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.ODataServiceFactory;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
+import org.apache.olingo.odata2.api.exception.MessageReference;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.api.exception.ODataHttpException;
+import org.apache.olingo.odata2.api.exception.ODataInternalServerErrorException;
+import org.apache.olingo.odata2.api.exception.ODataMethodNotAllowedException;
+import org.apache.olingo.odata2.api.exception.ODataNotAcceptableException;
+import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataRequest;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.core.ODataContextImpl;
+import org.apache.olingo.odata2.core.ODataRequestHandler;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+
+public abstract class AbstractODataServlet extends HttpServlet {
+
+ private static final String HTTP_METHOD_OPTIONS = "OPTIONS";
+ private static final String HTTP_METHOD_HEAD = "HEAD";
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Get the service factory instance which is used for creation of the
+ * <code>ODataService</code> which handles the processing of the request.
+ *
+ * @param request the http request which is processed as an OData request
+ * @return an instance of an ODataServiceFactory
+ */
+ protected abstract ODataServiceFactory getServiceFactory(HttpServletRequest request);
+
+ @Override
+ protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
+ // We have to create the Service Factory here because otherwise we do not have access to the error callback
+ ODataServiceFactory serviceFactory = getServiceFactory(req);
+ if(serviceFactory == null) {
+ throw new ODataRuntimeException("Unable to get Service Factory. Check either '" +
+ ODataServiceFactory.FACTORY_LABEL + "' or '" + ODataServiceFactory.FACTORY_INSTANCE_LABEL + "' config.");
+ }
+
+ String xHttpMethod = req.getHeader("X-HTTP-Method");
+ String xHttpMethodOverride = req.getHeader("X-HTTP-Method-Override");
+ if (xHttpMethod != null && xHttpMethodOverride != null) {
+ if (!xHttpMethod.equalsIgnoreCase(xHttpMethodOverride)) {
+ ODataExceptionWrapper wrapper = new ODataExceptionWrapper(req, serviceFactory);
+ createResponse(resp, wrapper.wrapInExceptionResponse(
+ new ODataBadRequestException(ODataBadRequestException.AMBIGUOUS_XMETHOD)));
+ }
+ }
+
+ if (req.getPathInfo() != null) {
+ handle(req, resp, xHttpMethod, xHttpMethodOverride, serviceFactory);
+ } else {
+ handleRedirect(req, resp, serviceFactory);
+ }
+ }
+
+
+ protected void handle(final HttpServletRequest req, final HttpServletResponse resp, final String xHttpMethod,
+ final String xHttpMethodOverride, ODataServiceFactory serviceFactory) throws IOException {
+ String method = req.getMethod();
+ if (ODataHttpMethod.GET.name().equals(method)) {
+ handleRequest(req, ODataHttpMethod.GET, resp, serviceFactory);
+ } else if (ODataHttpMethod.POST.name().equals(method)) {
+ if (xHttpMethod == null && xHttpMethodOverride == null) {
+ handleRequest(req, ODataHttpMethod.POST, resp, serviceFactory);
+ } else if (xHttpMethod == null) {
+ /* tunneling */
+ boolean methodHandled = handleHttpTunneling(req, resp, xHttpMethodOverride, serviceFactory);
+ if (!methodHandled) {
+ createMethodNotAllowedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
+ }
+ } else {
+ /* tunneling */
+ boolean methodHandled = handleHttpTunneling(req, resp, xHttpMethod, serviceFactory);
+ if (!methodHandled) {
+ createNotImplementedResponse(req, ODataNotImplementedException.TUNNELING, resp, serviceFactory);
+ }
+ }
+
+ } else if (ODataHttpMethod.PUT.name().equals(method)) {
+ handleRequest(req, ODataHttpMethod.PUT, resp, serviceFactory);
+ } else if (ODataHttpMethod.DELETE.name().equals(method)) {
+ handleRequest(req, ODataHttpMethod.DELETE, resp, serviceFactory);
+ } else if (ODataHttpMethod.PATCH.name().equals(method)) {
+ handleRequest(req, ODataHttpMethod.PATCH, resp, serviceFactory);
+ } else if (ODataHttpMethod.MERGE.name().equals(method)) {
+ handleRequest(req, ODataHttpMethod.MERGE, resp, serviceFactory);
+ } else if (HTTP_METHOD_HEAD.equals(method) || HTTP_METHOD_OPTIONS.equals(method)) {
+ createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
+ } else {
+ createNotImplementedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
+ }
+ }
+
+ private boolean handleHttpTunneling(final HttpServletRequest req, final HttpServletResponse resp,
+ final String xHttpMethod, ODataServiceFactory serviceFactory) throws IOException {
+ if (ODataHttpMethod.MERGE.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.MERGE, resp, serviceFactory);
+ } else if (ODataHttpMethod.PATCH.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.PATCH, resp, serviceFactory);
+ } else if (ODataHttpMethod.DELETE.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.DELETE, resp, serviceFactory);
+ } else if (ODataHttpMethod.PUT.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.PUT, resp, serviceFactory);
+ } else if (ODataHttpMethod.GET.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.GET, resp, serviceFactory);
+ } else if (ODataHttpMethod.POST.name().equals(xHttpMethod)) {
+ handleRequest(req, ODataHttpMethod.POST, resp, serviceFactory);
+ } else if (HTTP_METHOD_HEAD.equals(xHttpMethod) || HTTP_METHOD_OPTIONS.equals(xHttpMethod)) {
+ createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
+ } else {
+ createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
+ }
+ return true;
+ }
+
+ private void
+ handleRequest(final HttpServletRequest req, final ODataHttpMethod method, final HttpServletResponse resp,
+ ODataServiceFactory serviceFactory)
+ throws IOException {
+ try {
+ final String pathSplitAsString = getInitParameter(ODataServiceFactory.PATH_SPLIT_LABEL);
+ int pathSplit = 0;
+ if (pathSplitAsString != null) {
+ pathSplit = Integer.parseInt(pathSplitAsString);
+ }
+ if (req.getHeader(HttpHeaders.ACCEPT) != null && req.getHeader(HttpHeaders.ACCEPT).isEmpty()) {
+ createNotAcceptableResponse(req, ODataNotAcceptableException.COMMON, resp, serviceFactory);
+ }
+ ODataRequest odataRequest = ODataRequest.method(method)
+ .contentType(RestUtil.extractRequestContentType(req.getContentType()).toContentTypeString())
+ .acceptHeaders(RestUtil.extractAcceptHeaders(req.getHeader(HttpHeaders.ACCEPT)))
+ .acceptableLanguages(RestUtil.extractAcceptableLanguage(req.getHeader(HttpHeaders.ACCEPT_LANGUAGE)))
+ .pathInfo(RestUtil.buildODataPathInfo(req, pathSplit))
+ .allQueryParameters(RestUtil.extractAllQueryParameters(req.getQueryString()))
+ .requestHeaders(RestUtil.extractHeaders(req))
+ .body(req.getInputStream())
+ .build();
+
+ ODataContextImpl context = new ODataContextImpl(odataRequest, serviceFactory);
+ context.setParameter(ODataContext.HTTP_SERVLET_REQUEST_OBJECT, req);
+
+ ODataService service = serviceFactory.createService(context);
+ if (service == null) {
+ createServiceUnavailableResponse(req, ODataInternalServerErrorException.NOSERVICE, resp, serviceFactory);
+ } else {
+ context.setService(service);
+ service.getProcessor().setContext(context);
+
+ ODataRequestHandler requestHandler = new ODataRequestHandler(serviceFactory, service, context);
+ final ODataResponse odataResponse = requestHandler.handle(odataRequest);
+ createResponse(resp, odataResponse);
+ }
+ } catch (Exception e) {
+ ODataExceptionWrapper wrapper = new ODataExceptionWrapper(req, serviceFactory);
+ createResponse(resp, wrapper.wrapInExceptionResponse(e));
+ }
+ }
+
+ protected void handleRedirect(final HttpServletRequest req, final HttpServletResponse resp,
+ ODataServiceFactory serviceFactory) throws IOException {
+ String method = req.getMethod();
+ if (ODataHttpMethod.GET.name().equals(method) ||
+ ODataHttpMethod.POST.name().equals(method) ||
+ ODataHttpMethod.PUT.name().equals(method) ||
+ ODataHttpMethod.DELETE.name().equals(method) ||
+ ODataHttpMethod.PATCH.name().equals(method) ||
+ ODataHttpMethod.MERGE.name().equals(method) ||
+ HTTP_METHOD_HEAD.equals(method) ||
+ HTTP_METHOD_OPTIONS.equals(method)) {
+ ODataResponse odataResponse = ODataResponse.status(HttpStatusCodes.TEMPORARY_REDIRECT)
+ .header(HttpHeaders.LOCATION, createLocation(req))
+ .build();
+ createResponse(resp, odataResponse);
+ } else {
+ createNotImplementedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
+ }
+
+ }
+
+ private String createLocation(final HttpServletRequest req) {
+ StringBuilder location = new StringBuilder();
+ String contextPath = req.getContextPath();
+ if (contextPath != null) {
+ location.append(contextPath);
+ }
+ String servletPath = req.getServletPath();
+ if (servletPath != null) {
+ location.append(servletPath);
+ }
+ location.append("/");
+ return location.toString();
+ }
+
+ protected void createResponse(final HttpServletResponse resp, final ODataResponse response) throws IOException {
+ resp.setStatus(response.getStatus().getStatusCode());
+ resp.setContentType(response.getContentHeader());
+ for (String headerName : response.getHeaderNames()) {
+ resp.setHeader(headerName, response.getHeader(headerName));
+ }
+
+ Object entity = response.getEntity();
+ if (entity != null) {
+ ServletOutputStream out = resp.getOutputStream();
+ int curByte;
+ int contentLength = 0;
+
+ if (entity instanceof InputStream) {
+ while ((curByte = ((InputStream) entity).read()) != -1) {
+ contentLength++;
+ out.write((char) curByte);
+ }
+ ((InputStream) entity).close();
+ } else if (entity instanceof String) {
+ String body = (String) entity;
+ final byte[] entityBytes = body.getBytes("utf-8");
+ out.write(entityBytes);
+ contentLength = entityBytes.length;
+ }
+
+ if (response.getHeader(HttpHeaders.CONTENT_LENGTH) != null) {
+ // Override content length
+ try {
+ contentLength = Integer.parseInt(response.getHeader(HttpHeaders.CONTENT_LENGTH));
+ } catch (NumberFormatException e) {
+ // Ignore
+ }
+ }
+
+ resp.setContentLength(contentLength);
+ out.flush();
+ out.close();
+ }
+ }
+
+ private void createNotImplementedResponse(final HttpServletRequest req, final MessageReference messageReference,
+ final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
+ // RFC 2616, 5.1.1: "An origin server SHOULD return the status code [...]
+ // 501 (Not Implemented) if the method is unrecognized [...] by the origin server."
+ ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
+ ODataResponse response =
+ exceptionWrapper.wrapInExceptionResponse(new ODataNotImplementedException(messageReference));
+// resp.setStatus(HttpStatusCodes.NOT_IMPLEMENTED.getStatusCode());
+ createResponse(resp, response);
+ }
+
+ private void createMethodNotAllowedResponse(final HttpServletRequest req, final MessageReference messageReference,
+ final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
+ ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
+ ODataResponse response =
+ exceptionWrapper.wrapInExceptionResponse(new ODataMethodNotAllowedException(messageReference));
+ createResponse(resp, response);
+ }
+
+ private void createNotAcceptableResponse(final HttpServletRequest req, final MessageReference messageReference,
+ final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
+ ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
+ ODataResponse response =
+ exceptionWrapper.wrapInExceptionResponse(new ODataNotAcceptableException(messageReference));
+ createResponse(resp, response);
+ }
+
+ private void createServiceUnavailableResponse(HttpServletRequest req, MessageReference messageReference,
+ HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
+ ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
+ ODataResponse response =
+ exceptionWrapper.wrapInExceptionResponse(new ODataInternalServerErrorException(messageReference));
+ createResponse(resp, response);
+ }
+
+ /**
+ * Create an instance of a ODataServiceFactory via factory class
+ * from servlet init parameter ODataServiceFactory.FACTORY_LABEL
+ * and ODataServiceFactory.FACTORY_CLASSLOADER_LABEL (if set).
+ *
+ * @see ODataServiceFactory#FACTORY_LABEL
+ * @see ODataServiceFactory#FACTORY_CLASSLOADER_LABEL
+ *
+ * @param req http servlet request
+ * @return instance of a ODataServiceFactory
+ */
+ protected ODataServiceFactory createODataServiceFactory(HttpServletRequest req)
+ throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+ final String factoryClassName = getInitParameter(ODataServiceFactory.FACTORY_LABEL);
+ if(factoryClassName == null) {
+ return null;
+ }
+
+ ClassLoader cl = (ClassLoader) req.getAttribute(ODataServiceFactory.FACTORY_CLASSLOADER_LABEL);
+ if (cl == null) {
+ return (ODataServiceFactory) Class.forName(factoryClassName).newInstance();
+ } else {
+ return (ODataServiceFactory) Class.forName(factoryClassName, true, cl).newInstance();
+ }
+ }
+
+ /**
+ * Get an instance of a ODataServiceFactory from request attribute
+ * ODataServiceFactory.FACTORY_INSTANCE_LABEL
+ *
+ * @see ODataServiceFactory#FACTORY_INSTANCE_LABEL
+ *
+ * @param req http servlet request
+ * @return instance of a ODataServiceFactory
+ */
+ protected ODataServiceFactory getServiceFactoryInstance(HttpServletRequest req) {
+ Object factory = req.getAttribute(ODataServiceFactory.FACTORY_INSTANCE_LABEL);
+ if(factory == null) {
+ return null;
+ } else if(factory instanceof ODataServiceFactory) {
+ return (ODataServiceFactory) factory;
+ }
+ throw new ODataRuntimeException("Invalid service factory instance of type " + factory.getClass());
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f1ca1a20/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
index 5607025..d3e95e8 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/ODataServlet.java
@@ -18,295 +18,28 @@
******************************************************************************/
package org.apache.olingo.odata2.core.servlet;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.olingo.odata2.api.ODataService;
import org.apache.olingo.odata2.api.ODataServiceFactory;
-import org.apache.olingo.odata2.api.commons.HttpHeaders;
-import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
-import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
-import org.apache.olingo.odata2.api.exception.MessageReference;
-import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
-import org.apache.olingo.odata2.api.exception.ODataHttpException;
-import org.apache.olingo.odata2.api.exception.ODataInternalServerErrorException;
-import org.apache.olingo.odata2.api.exception.ODataMethodNotAllowedException;
-import org.apache.olingo.odata2.api.exception.ODataNotAcceptableException;
-import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
-import org.apache.olingo.odata2.api.processor.ODataContext;
-import org.apache.olingo.odata2.api.processor.ODataRequest;
-import org.apache.olingo.odata2.api.processor.ODataResponse;
-import org.apache.olingo.odata2.core.ODataContextImpl;
-import org.apache.olingo.odata2.core.ODataRequestHandler;
import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
-public class ODataServlet extends HttpServlet {
+import javax.servlet.http.HttpServletRequest;
- private static final String HTTP_METHOD_OPTIONS = "OPTIONS";
- private static final String HTTP_METHOD_HEAD = "HEAD";
+public final class ODataServlet extends AbstractODataServlet {
- /**
- *
- */
private static final long serialVersionUID = 1L;
- @Override
- protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
- final String factoryClassName = getInitParameter(ODataServiceFactory.FACTORY_LABEL);
- if (factoryClassName == null) {
- throw new ODataRuntimeException("config missing: " + ODataServiceFactory.FACTORY_LABEL);
- }
-
- // We have to create the Service Factory here because otherwise we do not have access to the error callback
- ODataServiceFactory serviceFactory = createServiceFactory(req);
-
- String xHttpMethod = req.getHeader("X-HTTP-Method");
- String xHttpMethodOverride = req.getHeader("X-HTTP-Method-Override");
- if (xHttpMethod != null && xHttpMethodOverride != null) {
- if (!xHttpMethod.equalsIgnoreCase(xHttpMethodOverride)) {
- ODataExceptionWrapper wrapper = new ODataExceptionWrapper(req, serviceFactory);
- createResponse(resp, wrapper.wrapInExceptionResponse(
- new ODataBadRequestException(ODataBadRequestException.AMBIGUOUS_XMETHOD)));
- }
- }
-
- if (req.getPathInfo() != null) {
- handle(req, resp, xHttpMethod, xHttpMethodOverride, serviceFactory);
- } else {
- handleRedirect(req, resp, serviceFactory);
- }
- }
-
- private void handle(final HttpServletRequest req, final HttpServletResponse resp, final String xHttpMethod,
- final String xHttpMethodOverride, ODataServiceFactory serviceFactory) throws IOException {
- String method = req.getMethod();
- if (ODataHttpMethod.GET.name().equals(method)) {
- handleRequest(req, ODataHttpMethod.GET, resp, serviceFactory);
- } else if (ODataHttpMethod.POST.name().equals(method)) {
- if (xHttpMethod == null && xHttpMethodOverride == null) {
- handleRequest(req, ODataHttpMethod.POST, resp, serviceFactory);
- } else if (xHttpMethod == null) {
- /* tunneling */
- boolean methodHandled = handleHttpTunneling(req, resp, xHttpMethodOverride, serviceFactory);
- if (!methodHandled) {
- createMethodNotAllowedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
- }
- } else {
- /* tunneling */
- boolean methodHandled = handleHttpTunneling(req, resp, xHttpMethod, serviceFactory);
- if (!methodHandled) {
- createNotImplementedResponse(req, ODataNotImplementedException.TUNNELING, resp, serviceFactory);
- }
- }
-
- } else if (ODataHttpMethod.PUT.name().equals(method)) {
- handleRequest(req, ODataHttpMethod.PUT, resp, serviceFactory);
- } else if (ODataHttpMethod.DELETE.name().equals(method)) {
- handleRequest(req, ODataHttpMethod.DELETE, resp, serviceFactory);
- } else if (ODataHttpMethod.PATCH.name().equals(method)) {
- handleRequest(req, ODataHttpMethod.PATCH, resp, serviceFactory);
- } else if (ODataHttpMethod.MERGE.name().equals(method)) {
- handleRequest(req, ODataHttpMethod.MERGE, resp, serviceFactory);
- } else if (HTTP_METHOD_HEAD.equals(method) || HTTP_METHOD_OPTIONS.equals(method)) {
- createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
- } else {
- createNotImplementedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
- }
- }
-
- private boolean handleHttpTunneling(final HttpServletRequest req, final HttpServletResponse resp,
- final String xHttpMethod, ODataServiceFactory serviceFactory) throws IOException {
- if (ODataHttpMethod.MERGE.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.MERGE, resp, serviceFactory);
- } else if (ODataHttpMethod.PATCH.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.PATCH, resp, serviceFactory);
- } else if (ODataHttpMethod.DELETE.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.DELETE, resp, serviceFactory);
- } else if (ODataHttpMethod.PUT.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.PUT, resp, serviceFactory);
- } else if (ODataHttpMethod.GET.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.GET, resp, serviceFactory);
- } else if (ODataHttpMethod.POST.name().equals(xHttpMethod)) {
- handleRequest(req, ODataHttpMethod.POST, resp, serviceFactory);
- } else if (HTTP_METHOD_HEAD.equals(xHttpMethod) || HTTP_METHOD_OPTIONS.equals(xHttpMethod)) {
- createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
- } else {
- createNotImplementedResponse(req, ODataNotImplementedException.COMMON, resp, serviceFactory);
- }
- return true;
- }
-
- private void
- handleRequest(final HttpServletRequest req, final ODataHttpMethod method, final HttpServletResponse resp,
- ODataServiceFactory serviceFactory)
- throws IOException {
+ /**
+ * @{inherit}
+ */
+ protected ODataServiceFactory getServiceFactory(HttpServletRequest request) {
try {
- final String pathSplitAsString = getInitParameter(ODataServiceFactory.PATH_SPLIT_LABEL);
- int pathSplit = 0;
- if (pathSplitAsString != null) {
- pathSplit = Integer.parseInt(pathSplitAsString);
- }
- if (req.getHeader(HttpHeaders.ACCEPT) != null && req.getHeader(HttpHeaders.ACCEPT).isEmpty()) {
- createNotAcceptableResponse(req, ODataNotAcceptableException.COMMON, resp, serviceFactory);
+ ODataServiceFactory factoryInstance = getServiceFactoryInstance(request);
+ if(factoryInstance == null) {
+ return createODataServiceFactory(request);
}
- ODataRequest odataRequest = ODataRequest.method(method)
- .contentType(RestUtil.extractRequestContentType(req.getContentType()).toContentTypeString())
- .acceptHeaders(RestUtil.extractAcceptHeaders(req.getHeader(HttpHeaders.ACCEPT)))
- .acceptableLanguages(RestUtil.extractAcceptableLanguage(req.getHeader(HttpHeaders.ACCEPT_LANGUAGE)))
- .pathInfo(RestUtil.buildODataPathInfo(req, pathSplit))
- .allQueryParameters(RestUtil.extractAllQueryParameters(req.getQueryString()))
- .requestHeaders(RestUtil.extractHeaders(req))
- .body(req.getInputStream())
- .build();
-
- ODataContextImpl context = new ODataContextImpl(odataRequest, serviceFactory);
- context.setParameter(ODataContext.HTTP_SERVLET_REQUEST_OBJECT, req);
-
- ODataService service = serviceFactory.createService(context);
- if (service == null) {
- createServiceUnavailableResponse(req, ODataInternalServerErrorException.NOSERVICE, resp, serviceFactory);
- } else {
- context.setService(service);
- service.getProcessor().setContext(context);
-
- ODataRequestHandler requestHandler = new ODataRequestHandler(serviceFactory, service, context);
- final ODataResponse odataResponse = requestHandler.handle(odataRequest);
- createResponse(resp, odataResponse);
- }
- } catch (Exception e) {
- ODataExceptionWrapper wrapper = new ODataExceptionWrapper(req, serviceFactory);
- createResponse(resp, wrapper.wrapInExceptionResponse(e));
- }
- }
+ return factoryInstance;
- private ODataServiceFactory createServiceFactory(HttpServletRequest req) {
- try {
- final String factoryClassName = getInitParameter(ODataServiceFactory.FACTORY_LABEL);
- ClassLoader cl = (ClassLoader) req.getAttribute(ODataServiceFactory.FACTORY_CLASSLOADER_LABEL);
- if (cl == null) {
- return (ODataServiceFactory) Class.forName(factoryClassName).newInstance();
- } else {
- return (ODataServiceFactory) Class.forName(factoryClassName, true, cl).newInstance();
- }
} catch (Exception e) {
throw new ODataRuntimeException(e);
}
}
-
- private void handleRedirect(final HttpServletRequest req, final HttpServletResponse resp,
- ODataServiceFactory serviceFactory) throws IOException {
- String method = req.getMethod();
- if (ODataHttpMethod.GET.name().equals(method) ||
- ODataHttpMethod.POST.name().equals(method) ||
- ODataHttpMethod.PUT.name().equals(method) ||
- ODataHttpMethod.DELETE.name().equals(method) ||
- ODataHttpMethod.PATCH.name().equals(method) ||
- ODataHttpMethod.MERGE.name().equals(method) ||
- HTTP_METHOD_HEAD.equals(method) ||
- HTTP_METHOD_OPTIONS.equals(method)) {
- ODataResponse odataResponse = ODataResponse.status(HttpStatusCodes.TEMPORARY_REDIRECT)
- .header(HttpHeaders.LOCATION, createLocation(req))
- .build();
- createResponse(resp, odataResponse);
- } else {
- createNotImplementedResponse(req, ODataHttpException.COMMON, resp, serviceFactory);
- }
-
- }
-
- private String createLocation(final HttpServletRequest req) {
- StringBuilder location = new StringBuilder();
- String contextPath = req.getContextPath();
- if (contextPath != null) {
- location.append(contextPath);
- }
- String servletPath = req.getServletPath();
- if (servletPath != null) {
- location.append(servletPath);
- }
- location.append("/");
- return location.toString();
- }
-
- private void createResponse(final HttpServletResponse resp, final ODataResponse response) throws IOException {
- resp.setStatus(response.getStatus().getStatusCode());
- resp.setContentType(response.getContentHeader());
- for (String headerName : response.getHeaderNames()) {
- resp.setHeader(headerName, response.getHeader(headerName));
- }
-
- Object entity = response.getEntity();
- if (entity != null) {
- ServletOutputStream out = resp.getOutputStream();
- int curByte;
- int contentLength = 0;
-
- if (entity instanceof InputStream) {
- while ((curByte = ((InputStream) entity).read()) != -1) {
- contentLength++;
- out.write((char) curByte);
- }
- ((InputStream) entity).close();
- } else if (entity instanceof String) {
- String body = (String) entity;
- final byte[] entityBytes = body.getBytes("utf-8");
- out.write(entityBytes);
- contentLength = entityBytes.length;
- }
-
- if (response.getHeader(HttpHeaders.CONTENT_LENGTH) != null) {
- // Override content length
- try {
- contentLength = Integer.parseInt(response.getHeader(HttpHeaders.CONTENT_LENGTH));
- } catch (NumberFormatException e) {
- // Ignore
- }
- }
-
- resp.setContentLength(contentLength);
- out.flush();
- out.close();
- }
- }
-
- private void createNotImplementedResponse(final HttpServletRequest req, final MessageReference messageReference,
- final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
- // RFC 2616, 5.1.1: "An origin server SHOULD return the status code [...]
- // 501 (Not Implemented) if the method is unrecognized [...] by the origin server."
- ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
- ODataResponse response =
- exceptionWrapper.wrapInExceptionResponse(new ODataNotImplementedException(messageReference));
-// resp.setStatus(HttpStatusCodes.NOT_IMPLEMENTED.getStatusCode());
- createResponse(resp, response);
- }
-
- private void createMethodNotAllowedResponse(final HttpServletRequest req, final MessageReference messageReference,
- final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
- ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
- ODataResponse response =
- exceptionWrapper.wrapInExceptionResponse(new ODataMethodNotAllowedException(messageReference));
- createResponse(resp, response);
- }
-
- private void createNotAcceptableResponse(final HttpServletRequest req, final MessageReference messageReference,
- final HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
- ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
- ODataResponse response =
- exceptionWrapper.wrapInExceptionResponse(new ODataNotAcceptableException(messageReference));
- createResponse(resp, response);
- }
-
- private void createServiceUnavailableResponse(HttpServletRequest req, MessageReference messageReference,
- HttpServletResponse resp, ODataServiceFactory serviceFactory) throws IOException {
- ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(req, serviceFactory);
- ODataResponse response =
- exceptionWrapper.wrapInExceptionResponse(new ODataInternalServerErrorException(messageReference));
- createResponse(resp, response);
- }
-
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f1ca1a20/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/RestUtil.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/RestUtil.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/RestUtil.java
index 65aaf06..da7b05b 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/RestUtil.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/servlet/RestUtil.java
@@ -366,9 +366,10 @@ public class RestUtil {
pathInfoString = pathInfoString.substring(servletRequest.getContextPath().length());
}
- int indexServletPath = requestUri.indexOf(servletRequest.getServletPath());
+ int indexServletPath = pathInfoString.indexOf(servletRequest.getServletPath());
if (indexServletPath >= 0) {
- pathInfoString = pathInfoString.substring(servletRequest.getServletPath().length());
+ int substringFromPos = indexServletPath + servletRequest.getServletPath().length();
+ pathInfoString = pathInfoString.substring(substringFromPos);
}
return pathInfoString;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f1ca1a20/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/AbstractODataServletTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/AbstractODataServletTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/AbstractODataServletTest.java
new file mode 100644
index 0000000..de21917
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/AbstractODataServletTest.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * 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.odata2.core.servlet;
+
+import junit.framework.Assert;
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.ODataServiceFactory;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataProcessor;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.servicedocument.Collection;
+import org.apache.olingo.odata2.core.ODataResponseImpl;
+import org.apache.olingo.odata2.core.rest.ODataServiceFactoryImpl;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import javax.servlet.GenericServlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collections;
+
+/**
+ *
+ */
+public class AbstractODataServletTest {
+
+ private HttpServletRequest reqMock;
+ private HttpServletResponse respMock;
+ private ServletConfig configMock;
+
+ public AbstractODataServletTest() {
+ reqMock = Mockito.mock(HttpServletRequest.class);
+ respMock = Mockito.mock(HttpServletResponse.class);
+ configMock = Mockito.mock(ServletConfig.class);
+ }
+
+ private static class MyTestODataServlet extends AbstractODataServlet {
+ enum ServiceFactorySource {INSTANCE, CLASSLOADER, MOCK};
+
+ ODataServiceFactory viaInstance;
+ ODataServiceFactory viaClassLoader;
+ ODataServiceFactory viaMock;
+ final ServiceFactorySource source;
+
+ public MyTestODataServlet() {
+ this(ServiceFactorySource.MOCK);
+ }
+
+ public MyTestODataServlet(ServiceFactorySource source) {
+ this.source = source;
+ }
+
+ @Override
+ protected ODataServiceFactory getServiceFactory(HttpServletRequest request) {
+ viaInstance = getServiceFactoryInstance(request);
+ try {
+ viaClassLoader = createODataServiceFactory(request);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ viaMock = Mockito.mock(ODataServiceFactory.class);
+
+ switch (source) {
+ case INSTANCE: return viaInstance;
+ case CLASSLOADER: return viaClassLoader;
+ case MOCK: return viaMock;
+ }
+ return null;
+ }
+ }
+
+ @Test
+ public void handleRedirect() throws Exception {
+ AbstractODataServlet servlet = new MyTestODataServlet();
+ prepareServlet(servlet);
+ prepareRequest(reqMock);
+ servlet.service(reqMock, respMock);
+
+ Mockito.verify(respMock).setStatus(HttpStatusCodes.TEMPORARY_REDIRECT.getStatusCode());
+ Mockito.verify(respMock).setHeader(HttpHeaders.LOCATION, "/context-path/servlet-path/");
+ }
+
+ @Test
+ public void handleRedirectWoServletPath() throws Exception {
+ AbstractODataServlet servlet = new MyTestODataServlet();
+ prepareServlet(servlet);
+ prepareRequest(reqMock, "/context-path", null);
+ servlet.service(reqMock, respMock);
+
+ Mockito.verify(respMock).setStatus(HttpStatusCodes.TEMPORARY_REDIRECT.getStatusCode());
+ Mockito.verify(respMock).setHeader(HttpHeaders.LOCATION, "/context-path/");
+ }
+
+ @Test
+ public void handleRedirectWoContextPath() throws Exception {
+ AbstractODataServlet servlet = new MyTestODataServlet();
+ prepareServlet(servlet);
+ prepareRequest(reqMock, null, "/servlet-path");
+ servlet.service(reqMock, respMock);
+
+ Mockito.verify(respMock).setStatus(HttpStatusCodes.TEMPORARY_REDIRECT.getStatusCode());
+ Mockito.verify(respMock).setHeader(HttpHeaders.LOCATION, "/servlet-path/");
+ }
+
+ @Test
+ public void handleRedirectWoPath() throws Exception {
+ AbstractODataServlet servlet = new MyTestODataServlet();
+ prepareServlet(servlet);
+ prepareRequest(reqMock, null, null);
+ servlet.service(reqMock, respMock);
+
+ Mockito.verify(respMock).setStatus(HttpStatusCodes.TEMPORARY_REDIRECT.getStatusCode());
+ Mockito.verify(respMock).setHeader(HttpHeaders.LOCATION, "/");
+ }
+
+ @Test
+ public void contentLengthCalculatedString() throws Exception {
+ final Method createResponse =
+ AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
+ createResponse.setAccessible(true);
+
+ final AbstractODataServlet servlet = new MyTestODataServlet();
+ final String content = "Test\r\n";
+ final ODataResponse response = ODataResponseImpl.status(HttpStatusCodes.OK).entity(content).build();
+ prepareResponseMockToWrite(respMock);
+ prepareServlet(servlet);
+
+ createResponse.invoke(servlet, respMock, response);
+ Mockito.verify(respMock).setContentLength(content.getBytes("utf-8").length);
+ }
+
+ @Test
+ public void contentLengthCalculatedStream() throws Exception {
+ final Method createResponse =
+ AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
+ createResponse.setAccessible(true);
+
+ final AbstractODataServlet servlet = new MyTestODataServlet();
+ final String content = "Test\r\n";
+
+ final ODataResponse response =
+ ODataResponseImpl.status(HttpStatusCodes.OK).entity(new ByteArrayInputStream(content.getBytes("utf-8")))
+ .build();
+ prepareResponseMockToWrite(respMock);
+ prepareServlet(servlet);
+
+ createResponse.invoke(servlet, respMock, response);
+ Mockito.verify(respMock).setContentLength(content.getBytes("utf-8").length);
+ }
+
+ @Test
+ public void contentLengthHeader() throws Exception {
+ final Method createResponse =
+ AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
+ createResponse.setAccessible(true);
+ final AbstractODataServlet servlet = new MyTestODataServlet();
+ final ODataResponse response =
+ ODataResponseImpl.status(HttpStatusCodes.OK).header(HttpHeaders.CONTENT_LENGTH, "15").entity("").build();
+ prepareResponseMockToWrite(respMock);
+ prepareServlet(servlet);
+
+ createResponse.invoke(servlet, respMock, response);
+
+ Mockito.verify(respMock).setHeader(HttpHeaders.CONTENT_LENGTH, "15");
+ Mockito.verify(respMock).setContentLength(15);
+ }
+
+ @Test
+ public void contentLengthHeaderInvalid() throws Exception {
+ final Method createResponse =
+ AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
+ createResponse.setAccessible(true);
+ final AbstractODataServlet servlet = new MyTestODataServlet();
+ final ODataResponse response =
+ ODataResponseImpl.status(HttpStatusCodes.OK).header(HttpHeaders.CONTENT_LENGTH, "ab").entity("Test").build();
+ prepareResponseMockToWrite(respMock);
+ prepareServlet(servlet);
+
+ createResponse.invoke(servlet, respMock, response);
+
+ Mockito.verify(respMock).setHeader(HttpHeaders.CONTENT_LENGTH, "ab");
+ Mockito.verify(respMock).setContentLength(4); // ||"Test"|| = 4
+ }
+
+ @Test
+ public void serviceInstance() throws Exception {
+ MyTestODataServlet servlet = new MyTestODataServlet(MyTestODataServlet.ServiceFactorySource.INSTANCE);
+ prepareServlet(servlet, false);
+ prepareRequest(reqMock, "", "/servlet-path");
+ Mockito.when(reqMock.getPathInfo()).thenReturn("/request-path-info");
+ Mockito.when(reqMock.getRequestURI()).thenReturn("http://localhost:8080/servlet-path/request-path-info");
+ ODataServiceFactory factory = Mockito.mock(ODataServiceFactory.class);
+ ODataService service = Mockito.mock(ODataService.class);
+ Mockito.when(factory.createService(Mockito.any(ODataContext.class))).thenReturn(service);
+ ODataProcessor processor = Mockito.mock(ODataProcessor.class);
+ Mockito.when(service.getProcessor()).thenReturn(processor);
+ Mockito.when(reqMock.getAttribute(ODataServiceFactory.FACTORY_INSTANCE_LABEL)).thenReturn(factory);
+ Mockito.when(respMock.getOutputStream()).thenReturn(Mockito.mock(ServletOutputStream.class));
+
+ servlet.service(reqMock, respMock);
+
+ Mockito.verify(factory).createService(Mockito.any(ODataContext.class));
+ Assert.assertNotNull(servlet.viaInstance);
+ Assert.assertNull(servlet.viaClassLoader);
+ }
+
+ @Test
+ public void serviceClassloader() throws Exception {
+ MyTestODataServlet servlet = new MyTestODataServlet(MyTestODataServlet.ServiceFactorySource.CLASSLOADER);
+ prepareServlet(servlet);
+ prepareRequest(reqMock, "", "/servlet-path");
+ Mockito.when(reqMock.getPathInfo()).thenReturn("/request-path-info");
+ Mockito.when(reqMock.getRequestURI()).thenReturn("http://localhost:8080/servlet-path/request-path-info");
+ Mockito.when(respMock.getOutputStream()).thenReturn(Mockito.mock(ServletOutputStream.class));
+
+ servlet.service(reqMock, respMock);
+
+ Assert.assertNull(servlet.viaInstance);
+ Assert.assertNotNull(servlet.viaClassLoader);
+ }
+
+ private void prepareResponseMockToWrite(final HttpServletResponse response) throws IOException {
+ Mockito.when(response.getOutputStream()).thenReturn(new ServletOutputStream() {
+ @Override
+ public void write(int b) throws IOException {}
+ });
+ }
+
+ private void prepareRequest(final HttpServletRequest req, final String contextPath, final String servletPath) {
+ Mockito.when(req.getMethod()).thenReturn("GET");
+ Mockito.when(req.getContextPath()).thenReturn(contextPath);
+ Mockito.when(req.getServletPath()).thenReturn(servletPath);
+ Mockito.when(req.getHeaderNames()).thenReturn(Collections.emptyEnumeration());
+ }
+
+ private void prepareRequest(final HttpServletRequest req) {
+ prepareRequest(req, "/context-path", "/servlet-path");
+ }
+
+ private void prepareServlet(final GenericServlet servlet) throws Exception {
+ prepareServlet(servlet, true);
+ }
+
+ private void prepareServlet(final GenericServlet servlet, boolean withFactoryLabel) throws Exception {
+ // private transient ServletConfig config;
+ Field configField = GenericServlet.class.getDeclaredField("config");
+ configField.setAccessible(true);
+ configField.set(servlet, configMock);
+
+ if(withFactoryLabel) {
+ String factoryClassName = ODataServiceFactoryImpl.class.getName();
+ Mockito.when(configMock.getInitParameter(ODataServiceFactory.FACTORY_LABEL)).thenReturn(factoryClassName);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f1ca1a20/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/ODataServletTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/ODataServletTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/ODataServletTest.java
index 883ab96..e1ad5dc 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/ODataServletTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/servlet/ODataServletTest.java
@@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.util.Collections;
import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;
@@ -29,9 +30,13 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import junit.framework.Assert;
+import org.apache.olingo.odata2.api.ODataService;
import org.apache.olingo.odata2.api.ODataServiceFactory;
import org.apache.olingo.odata2.api.commons.HttpHeaders;
import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataProcessor;
import org.apache.olingo.odata2.api.processor.ODataResponse;
import org.apache.olingo.odata2.core.ODataResponseImpl;
import org.apache.olingo.odata2.core.rest.ODataServiceFactoryImpl;
@@ -100,7 +105,7 @@ public class ODataServletTest {
@Test
public void contentLengthCalculatedString() throws Exception {
final Method createResponse =
- ODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
+ AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
createResponse.setAccessible(true);
final ODataServlet servlet = new ODataServlet();
@@ -116,7 +121,7 @@ public class ODataServletTest {
@Test
public void contentLengthCalculatedStream() throws Exception {
final Method createResponse =
- ODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
+ AbstractODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
createResponse.setAccessible(true);
final ODataServlet servlet = new ODataServlet();
@@ -133,39 +138,43 @@ public class ODataServletTest {
}
@Test
- public void contentLengthHeader() throws Exception {
- final Method createResponse =
- ODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
- createResponse.setAccessible(true);
- final ODataServlet servlet = new ODataServlet();
- final ODataResponse response =
- ODataResponseImpl.status(HttpStatusCodes.OK).header(HttpHeaders.CONTENT_LENGTH, "15").entity("").build();
- prepareResponseMockToWrite(respMock);
+ public void serviceInstance() throws Exception {
+ ODataServlet servlet = new ODataServlet();
prepareServlet(servlet);
+ prepareRequest(reqMock, "", "/servlet-path");
+ Mockito.when(reqMock.getPathInfo()).thenReturn("/request-path-info");
+ Mockito.when(reqMock.getRequestURI()).thenReturn("http://localhost:8080/servlet-path/request-path-info");
+ ODataServiceFactory factory = Mockito.mock(ODataServiceFactory.class);
+ ODataService service = Mockito.mock(ODataService.class);
+ Mockito.when(factory.createService(Mockito.any(ODataContext.class))).thenReturn(service);
+ ODataProcessor processor = Mockito.mock(ODataProcessor.class);
+ Mockito.when(service.getProcessor()).thenReturn(processor);
+ Mockito.when(reqMock.getAttribute(ODataServiceFactory.FACTORY_INSTANCE_LABEL)).thenReturn(factory);
+ Mockito.when(respMock.getOutputStream()).thenReturn(Mockito.mock(ServletOutputStream.class));
- createResponse.invoke(servlet, respMock, response);
+ servlet.service(reqMock, respMock);
- Mockito.verify(respMock).setHeader(HttpHeaders.CONTENT_LENGTH, "15");
- Mockito.verify(respMock).setContentLength(15);
+ Mockito.verify(factory).createService(Mockito.any(ODataContext.class));
}
@Test
- public void contentLengthHeaderInvalid() throws Exception {
- final Method createResponse =
- ODataServlet.class.getDeclaredMethod("createResponse", HttpServletResponse.class, ODataResponse.class);
- createResponse.setAccessible(true);
- final ODataServlet servlet = new ODataServlet();
- final ODataResponse response =
- ODataResponseImpl.status(HttpStatusCodes.OK).header(HttpHeaders.CONTENT_LENGTH, "ab").entity("Test").build();
- prepareResponseMockToWrite(respMock);
+ public void serviceClassloader() throws Exception {
+ ODataServlet servlet = new ODataServlet();
prepareServlet(servlet);
+ prepareRequest(reqMock, "", "/servlet-path");
+ Mockito.when(reqMock.getPathInfo()).thenReturn("/request-path-info");
+ Mockito.when(reqMock.getRequestURI()).thenReturn("http://localhost:8080/servlet-path/request-path-info");
+ Mockito.when(respMock.getOutputStream()).thenReturn(Mockito.mock(ServletOutputStream.class));
- createResponse.invoke(servlet, respMock, response);
+ servlet.service(reqMock, respMock);
- Mockito.verify(respMock).setHeader(HttpHeaders.CONTENT_LENGTH, "ab");
- Mockito.verify(respMock).setContentLength(4); // ||"Test"|| = 4
+ Mockito.verify(configMock).getInitParameter(ODataServiceFactory.FACTORY_LABEL);
+ Mockito.verify(reqMock).getAttribute(ODataServiceFactory.FACTORY_CLASSLOADER_LABEL);
+
+ Assert.assertEquals(ODataServiceFactoryImpl.class, servlet.createODataServiceFactory(reqMock).getClass());
}
+
private void prepareResponseMockToWrite(final HttpServletResponse response) throws IOException {
Mockito.when(response.getOutputStream()).thenReturn(new ServletOutputStream() {
@Override
@@ -177,6 +186,7 @@ public class ODataServletTest {
Mockito.when(req.getMethod()).thenReturn("GET");
Mockito.when(req.getContextPath()).thenReturn(contextPath);
Mockito.when(req.getServletPath()).thenReturn(servletPath);
+ Mockito.when(req.getHeaderNames()).thenReturn(Collections.emptyEnumeration());
}
private void prepareRequest(final HttpServletRequest req) {