You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2013/07/26 13:22:13 UTC

[08/51] [partial] initial commit

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/resources/i18n_en.properties
----------------------------------------------------------------------
diff --git a/odata-core/src/main/resources/i18n_en.properties b/odata-core/src/main/resources/i18n_en.properties
new file mode 100644
index 0000000..d6d0654
--- /dev/null
+++ b/odata-core/src/main/resources/i18n_en.properties
@@ -0,0 +1,166 @@
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+# English translations
+#
+##################################
+# CommonExceptions (Should these exist?)
+##################################
+org.apache.olingo.odata2.api.exception.ODataMessageException.COMMON=Common exception
+
+##################################
+# UriParserExceptions
+##################################
+org.apache.olingo.odata2.api.uri.UriNotMatchingException.MATCHPROBLEM=Could not match segment: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriNotMatchingException.NOTFOUND=Could not find an entity set or function import for '%1$s'.
+org.apache.olingo.odata2.api.uri.UriNotMatchingException.CONTAINERNOTFOUND=Could not find container with name: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriNotMatchingException.ENTITYNOTFOUND=Could not find entity with name: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriNotMatchingException.PROPERTYNOTFOUND=Could not find property with name: '%1$s'.
+
+org.apache.olingo.odata2.api.uri.UriSyntaxException.URISYNTAX=Invalid URI syntax.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.ENTITYSETINSTEADOFENTITY=Must be an entity set instead of an entity: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.NOTEXT=An exception occurred.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.NOMEDIARESOURCE=The requested resource is no media resource.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.NONAVIGATIONPROPERTY=Property '%1$s' must be a navigation property. 
+org.apache.olingo.odata2.api.uri.UriSyntaxException.MISSINGPARAMETER=Missing parameter.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.MISSINGKEYPREDICATENAME=Missing key predicate name for key: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.DUPLICATEKEYNAMES=Duplicate key names: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.EMPTYSEGMENT=No empty segment allowed.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.MUSTNOTBELASTSEGMENT='%1$s' must not be the last segment. 
+org.apache.olingo.odata2.api.uri.UriSyntaxException.MUSTBELASTSEGMENT='%1$s' must be the last segment.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDSEGMENT=Invalid segment: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDVALUE=Invalid value: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDNULLVALUE=Value for '%1$s' must not be null.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDNEGATIVEVALUE=Provided value '%1$s' must not be negative.  
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDRETURNTYPE=Invalid return type: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDPROPERTYTYPE=Invalid type for property: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDKEYPREDICATE=Invalid key predicate: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDSYSTEMQUERYOPTION=Invalid system query option: '%1$s'. 
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDFILTEREXPRESSION=Invalid filter expression: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INVALIDORDERBYEXPRESSION=Invalid order by expression: '%1$s'. 
+org.apache.olingo.odata2.api.uri.UriSyntaxException.LITERALFORMAT=Wrong literal format for literal: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.UNKNOWNLITERAL=Unknown literal: '%1$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INCOMPATIBLELITERAL=Format of '%1$s' is not compatible with '%2$s'.
+org.apache.olingo.odata2.api.uri.UriSyntaxException.INCOMPATIBLESYSTEMQUERYOPTION=System query option '%1$s' is not compatible with the return type.
+
+##################################
+# EDMExceptions
+##################################
+org.apache.olingo.odata2.api.edm.EdmLiteralException.NOTEXT=An exception occurred.
+org.apache.olingo.odata2.api.edm.EdmLiteralException.LITERALFORMAT=Wrong literal format for literal: '%1$s'.
+org.apache.olingo.odata2.api.edm.EdmLiteralException.UNKNOWNLITERAL=Unknown literal: '%1$s'.
+
+org.apache.olingo.odata2.api.edm.EdmException.COMMON=An exception occurred.
+org.apache.olingo.odata2.api.edm.EdmException.PROVIDERPROBLEM=A problem has been detected in the metadata provided by the EDM provider.
+
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.COMMON=An exception occurred.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_KIND_MISSING=The literal kind is missing.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_KIND_NOT_SUPPORTED=The literal kind '%1$s' is not supported.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_NULL_NOT_ALLOWED=The metadata do not allow a null literal.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT=The literal '%1$s' is not formatted properly.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_FACETS_NOT_MATCHED=The metadata constraints '%2$s' do not match the literal '%1$s'.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE=The literal '%1$s' can not be converted into the type '%1$s'.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED=The type '%1$s' of the value object is not supported.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.VALUE_NULL_NOT_ALLOWED=The metadata do not allow a null value.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT=The value object '%1$s' can not be formatted properly due to its content.
+org.apache.olingo.odata2.api.edm.EdmSimpleTypeException.VALUE_FACETS_NOT_MATCHED=The metadata constraints '%2$s' do not allow to format the value '%1$s'.
+
+##################################
+# EPexceptions
+##################################
+org.apache.olingo.odata2.api.ep.EntityProviderException.COMMON=An exception occurred.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_STATE=Invalid consuming state for parsing with message '%1$s'.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_PROPERTY=Invalid property '%1$s' found.
+org.apache.olingo.odata2.api.ep.EntityProviderException.MISSING_PROPERTY=Property with name '%1$s' was not found.
+org.apache.olingo.odata2.api.ep.EntityProviderException.MISSING_ATTRIBUTE=Mandatory attribute '%1$s' was not found.
+org.apache.olingo.odata2.api.ep.EntityProviderException.UNSUPPORTED_PROPERTY_TYPE=The given property type '%1$s' is not supported.
+org.apache.olingo.odata2.api.ep.EntityProviderException.INLINECOUNT_INVALID=Invalid inline count found.
+org.apache.olingo.odata2.api.ep.EntityProviderException.ILLEGAL_ARGUMENT=Illegal argument for method call with message '%1$s'.
+
+##################################
+# HttpExceptions
+##################################
+org.apache.olingo.odata2.api.exception.ODataHttpException.COMMON=Common exception
+
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.COMMON=Bad Request.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.NOTSUPPORTED=The request is not supported by the processor.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.URLTOOSHORT=The URL is too short.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.VERSIONERROR=The Data Services Request version '%1$s' is not supported for the request payload.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.PARSEVERSIONERROR=The Data Services Request version '%1$s' cannot be parsed.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.BODY=The request body is malformed.
+org.apache.olingo.odata2.api.exception.ODataBadRequestException.AMBIGUOUS_XMETHOD=Ambiguous X-HTTP-Method and X-HTTP-Method-Override header.
+
+org.apache.olingo.odata2.api.exception.ODataForbiddenException.COMMON=Forbidden
+
+org.apache.olingo.odata2.api.exception.ODataNotFoundException.MATRIX=Matrix parameter '%1$s' with path segment '%2$s' not found!
+org.apache.olingo.odata2.api.exception.ODataNotFoundException.ENTITY=Requested entity could not be found.
+
+org.apache.olingo.odata2.api.exception.ODataMethodNotAllowedException.DISPATCH=The request dispatcher does not allow the HTTP method used for the request.
+
+org.apache.olingo.odata2.api.exception.ODataNotAcceptableException.COMMON=The request can not be accepted.
+org.apache.olingo.odata2.api.exception.ODataNotAcceptableException.NOT_SUPPORTED_CONTENT_TYPE=Content type '%1$s' is not supported.
+
+org.apache.olingo.odata2.api.exception.ODataConflictException.COMMON=Conflict
+
+org.apache.olingo.odata2.api.exception.ODataPreconditionFailedException.COMMON=Precondition failed
+
+org.apache.olingo.odata2.api.exception.ODataUnsupportedMediaTypeException.COMMON=Unsupported media type
+
+org.apache.olingo.odata2.api.exception.ODataPreconditionRequiredException.COMMON=Precondition required
+
+org.apache.olingo.odata2.api.exception.ODataNotImplementedException.COMMON=Not implemented
+org.apache.olingo.odata2.api.exception.ODataNotImplementedException.TUNNELING=Method not recognized for X-HTTP-Method or X-HTTP-Method-Override header.
+
+org.apache.olingo.odata2.api.exception.ODataServiceUnavailableException.COMMON=Service Unavailable
+
+##################################
+# FilterParserExceptions
+##################################
+org.apache.olingo.odata2.api.uri.expression.ExceptionVisitExpression.COMMON=Error while traversing a ODATA expression tree.
+
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMON=Error while parsing a ODATA expression.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_TRAILING_TOKEN_DETECTED_AFTER_PARSING=Invalid token "%1$s" detected after parsing at position %2$s in "%3$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.TOKEN_UNDETERMINATED_STRING=Unterminated string literal at position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_TYPES_FOR_BINARY_OPERATOR=Operator "%1$s" incompatible with operand types "%2$s" and "%3$s" at position %4$s in "%5$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.MISSING_CLOSING_PHARENTHESIS=Missing closing parenthesis ")" for opening parenthesis "(" at position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.ERROR_IN_TOKENIZER=Error while tokenizing a ODATA expression on token '%1$s' at position '%2$s'.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.EXPRESSION_EXPECTED_AFTER_POS=Expression expected after position %1$s in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.EXPRESSION_EXPECTED_AT_POS=Expression expected at position %1$s.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.COMMA_OR_CLOSING_PHARENTHESIS_EXPECTED_AFTER_POS=")" or "," expected after position %1$s.
+
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_EXACT=No applicable method found for "%1$s" at position %2$s in "%3$s" with the specified arguments. Method "%1$s" requires exact %4$s argument(s).
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_BETWEEN=No applicable method found for "%1$s" at position %2$s in "%3$s" with the specified arguments. Method "%1$s" requires between %4$s and %5$s arguments.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_X_OR_MORE=No applicable method found for "%1$s" at position %2$s in "%3$s" with the specified arguments. Method "%1$s" requires %4$s or more arguments.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.METHOD_WRONG_ARG_X_OR_LESS=No applicable method found for "%1$s" at position %2$s in "%3$s" with the specified arguments. Method "%1$s" requires maximal %4$s arguments.
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.LEFT_SIDE_NOT_STRUCTURAL_TYPE=No property "%1$s" exists in type "%2$s" at position %3$s in "%4$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.LEFT_SIDE_NOT_A_PROPERTY=Leftside of method operator at position %1$s is not a property in "%2$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.PROPERTY_NAME_NOT_FOUND_IN_TYPE=No property "%1$s" exists in type "%2$s" at position %3$s in "%4$s".
+org.apache.olingo.odata2.api.uri.expression.ExpressionParserException.INVALID_SORT_ORDER=Invalid sort order in OData orderby parser at position %1$s in %2$s.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.ERROR_PARSING_METHOD=Internal error in OData filter parser while parsing a method expression.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.ERROR_PARSING_PARENTHESIS=Internal error in OData filter parser while parsing a parenthesis expression.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.ERROR_ACCESSING_EDM=Internal error in OData filter parser while accessing the EDM.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.INVALID_TYPE_COUNT=Internal error in OData filter parser while validating the allowed types.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.INVALID_TOKEN_AT    =Expect token '%1$s', but invalid token '%2$s' detected at position '%3$s'.
+org.apache.olingo.odata2.core.uri.expression.ExpressionParserInternalError.INVALID_TOKENKIND_AT=Expect tokenkind '%1$s', but invalid tokenkind '%2$s'(with value:'%3$s' detected at position '%4$s'.
+
+org.apache.olingo.odata2.core.uri.expression.TokenizerExpectError.NO_TOKEN_AVAILABLE       =Expect token %1$s, but no token left in token list.
+org.apache.olingo.odata2.core.uri.expression.TokenizerExpectError.INVALID_TOKEN_AT         =Expect token '%1$s', but invalid token '%2$s' detected at position '%3$s'.
+org.apache.olingo.odata2.core.uri.expression.TokenizerExpectError.INVALID_TOKENKIND_AT     =Expect tokenkind '%1$s', but invalid tokenkind '%2$s'(with value:'%3$s' detected at position '%4$s'.
+org.apache.olingo.odata2.core.uri.expression.TokenizerException.TYPEDECTECTION_FAILED_ON_STRING=Type detection error for string like token '%1$s' at position '%2$s'.
+org.apache.olingo.odata2.core.uri.expression.TokenizerException.TYPEDECTECTION_FAILED_ON_EDMTYPE=Type detection error for edmType like token '%1$s' at position '%2$s'.
+org.apache.olingo.odata2.core.uri.expression.TokenizerException.UNKNOWN_CHARACTER=Unknown character '%1$s' at position '%2$s' detected.

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/resources/i18n_en_US.properties
----------------------------------------------------------------------
diff --git a/odata-core/src/main/resources/i18n_en_US.properties b/odata-core/src/main/resources/i18n_en_US.properties
new file mode 100644
index 0000000..593c033
--- /dev/null
+++ b/odata-core/src/main/resources/i18n_en_US.properties
@@ -0,0 +1,20 @@
+#-------------------------------------------------------------------------------
+# 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.
+#-------------------------------------------------------------------------------
+# English translations
+#

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/META-INF/MANIFEST.MF
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/META-INF/MANIFEST.MF b/odata-core/src/test/java/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..254272e
--- /dev/null
+++ b/odata-core/src/test/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: 
+

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/org/apache/olingo/odata2/core/ContentNegotiatorTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/ContentNegotiatorTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/ContentNegotiatorTest.java
new file mode 100644
index 0000000..2f9c53e
--- /dev/null
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/ContentNegotiatorTest.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataNotAcceptableException;
+import org.apache.olingo.odata2.core.commons.ContentType;
+import org.apache.olingo.odata2.core.uri.UriInfoImpl;
+import org.apache.olingo.odata2.core.uri.UriType;
+
+/**
+ * @author SAP AG
+ */
+public class ContentNegotiatorTest {
+  private void negotiateContentType(final List<ContentType> contentTypes, final List<ContentType> supportedTypes, final String expected) throws ODataException {
+    final ContentType contentType = new ContentNegotiator().contentNegotiation(contentTypes, supportedTypes);
+    assertEquals(expected, contentType.toContentTypeString());
+  }
+
+  @Test
+  public void contentNegotiationEmptyRequest() throws Exception {
+    negotiateContentType(
+        contentTypes(),
+        contentTypes("sup/111", "sup/222"),
+        "sup/111");
+  }
+
+  @Test
+  public void contentNegotiationConcreteRequest() throws Exception {
+    negotiateContentType(
+        contentTypes("sup/222"),
+        contentTypes("sup/111", "sup/222"),
+        "sup/222");
+  }
+
+  @Test(expected = ODataNotAcceptableException.class)
+  public void contentNegotiationNotSupported() throws Exception {
+    negotiateContentType(contentTypes("image/gif"), contentTypes("sup/111", "sup/222"), null);
+  }
+
+  @Test
+  public void contentNegotiationSupportedWildcard() throws Exception {
+    negotiateContentType(
+        contentTypes("image/gif"),
+        contentTypes("sup/111", "sup/222", "*/*"),
+        "image/gif");
+  }
+
+  @Test
+  public void contentNegotiationSupportedSubWildcard() throws Exception {
+    negotiateContentType(
+        contentTypes("image/gif"),
+        contentTypes("sup/111", "sup/222", "image/*"),
+        "image/gif");
+  }
+
+  @Test
+  public void contentNegotiationRequestWildcard() throws Exception {
+    negotiateContentType(
+        contentTypes("*/*"),
+        contentTypes("sup/111", "sup/222"),
+        "sup/111");
+  }
+
+  @Test
+  public void contentNegotiationRequestSubWildcard() throws Exception {
+    negotiateContentType(
+        contentTypes("sup/*", "*/*"),
+        contentTypes("bla/111", "sup/222"),
+        "sup/222");
+  }
+
+  @Test
+  public void contentNegotiationRequestSubtypeWildcard() throws Exception {
+    negotiateContentType(
+        contentTypes("sup2/*"),
+        contentTypes("sup1/111", "sup2/222", "sup2/333"),
+        "sup2/222");
+  }
+
+  @Test
+  public void contentNegotiationRequestResponseWildcard() throws Exception {
+    negotiateContentType(contentTypes("*/*"), contentTypes("*/*"), "*/*");
+  }
+
+  @Test
+  public void contentNegotiationManyRequests() throws Exception {
+    negotiateContentType(
+        contentTypes("bla/111", "bla/blub", "sub2/222"),
+        contentTypes("sub1/666", "sub2/222", "sub3/333"),
+        "sub2/222");
+  }
+
+  @Test(expected = ODataNotAcceptableException.class)
+  public void contentNegotiationCharsetNotSupported() throws Exception {
+    negotiateContentType(
+        contentTypes("text/plain;charset=iso-8859-1"),
+        contentTypes("sup/111", "sup/222"),
+        "sup/222");
+  }
+
+  @Test
+  public void contentNegotiationWithODataVerbose() throws Exception {
+    negotiateContentType(
+        contentTypes("text/plain;q=0.5", "application/json;odata=verbose;q=0.2", "*/*"),
+        contentTypes("application/json;charset=utf-8", "sup/222"),
+        "application/json;charset=utf-8");
+  }
+
+  @Test
+  public void contentNegotiationDefaultCharset() throws Exception {
+    negotiateContentTypeCharset("application/xml", "application/xml;charset=utf-8", false);
+  }
+
+  @Test
+  public void contentNegotiationDefaultCharsetAsDollarFormat() throws Exception {
+    negotiateContentTypeCharset("application/xml", "application/xml;charset=utf-8", true);
+  }
+
+  @Test
+  public void contentNegotiationSupportedCharset() throws Exception {
+    negotiateContentTypeCharset("application/xml; charset=utf-8", "application/xml;charset=utf-8", false);
+  }
+
+  @Test
+  public void contentNegotiationSupportedCharsetAsDollarFormat() throws Exception {
+    negotiateContentTypeCharset("application/xml; charset=utf-8", "application/xml;charset=utf-8", true);
+  }
+
+  private void negotiateContentTypeCharset(final String requestType, final String supportedType, final boolean asFormat) throws ODataException {
+    UriInfoImpl uriInfo = Mockito.mock(UriInfoImpl.class);
+    Mockito.when(uriInfo.getUriType()).thenReturn(UriType.URI1);
+    if (asFormat) {
+      Mockito.when(uriInfo.getFormat()).thenReturn(requestType);
+    }
+
+    List<String> acceptedContentTypes = Arrays.asList(requestType);
+    List<String> supportedContentTypes = Arrays.asList(supportedType);
+
+    ContentNegotiator negotiator = new ContentNegotiator();
+    String negotiatedContentType = negotiator.doContentNegotiation(uriInfo, acceptedContentTypes, supportedContentTypes);
+
+    assertEquals(supportedType, negotiatedContentType);
+  }
+
+  private List<ContentType> contentTypes(final String... contentType) {
+    List<ContentType> ctList = new ArrayList<ContentType>();
+    for (String ct : contentType) {
+      ctList.add(ContentType.create(ct));
+    }
+    return ctList;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/org/apache/olingo/odata2/core/DispatcherTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/DispatcherTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/DispatcherTest.java
new file mode 100644
index 0000000..b38b86a
--- /dev/null
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/DispatcherTest.java
@@ -0,0 +1,451 @@
+/*******************************************************************************
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.InputStream;
+import java.util.Arrays;
+
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.ODataServiceFactory;
+import org.apache.olingo.odata2.api.batch.BatchHandler;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataMethodNotAllowedException;
+import org.apache.olingo.odata2.api.processor.ODataProcessor;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.processor.part.BatchProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntityComplexPropertyProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntityLinkProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntityLinksProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntityMediaProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntityProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntitySetProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntitySimplePropertyProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntitySimplePropertyValueProcessor;
+import org.apache.olingo.odata2.api.processor.part.FunctionImportProcessor;
+import org.apache.olingo.odata2.api.processor.part.FunctionImportValueProcessor;
+import org.apache.olingo.odata2.api.processor.part.MetadataProcessor;
+import org.apache.olingo.odata2.api.processor.part.ServiceDocumentProcessor;
+import org.apache.olingo.odata2.core.uri.UriInfoImpl;
+import org.apache.olingo.odata2.core.uri.UriType;
+import org.apache.olingo.odata2.testutil.fit.BaseTest;
+
+/**
+ * Tests for request dispatching according to URI type and HTTP method.
+ * @author SAP AG
+ */
+public class DispatcherTest extends BaseTest {
+
+  public static ODataService getMockService() throws ODataException {
+    ServiceDocumentProcessor serviceDocument = mock(ServiceDocumentProcessor.class);
+    when(serviceDocument.readServiceDocument(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+
+    EntitySetProcessor entitySet = mock(EntitySetProcessor.class);
+    when(entitySet.readEntitySet(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entitySet.countEntitySet(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entitySet.createEntity(any(UriInfoImpl.class), any(InputStream.class), anyString(), anyString())).thenAnswer(getAnswer());
+
+    EntityProcessor entity = mock(EntityProcessor.class);
+    when(entity.readEntity(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entity.existsEntity(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entity.deleteEntity(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entity.updateEntity(any(UriInfoImpl.class), any(InputStream.class), anyString(), anyBoolean(), anyString())).thenAnswer(getAnswer());
+
+    EntityComplexPropertyProcessor entityComplexProperty = mock(EntityComplexPropertyProcessor.class);
+    when(entityComplexProperty.readEntityComplexProperty(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entityComplexProperty.updateEntityComplexProperty(any(UriInfoImpl.class), any(InputStream.class), anyString(), anyBoolean(), anyString())).thenAnswer(getAnswer());
+
+    EntitySimplePropertyProcessor entitySimpleProperty = mock(EntitySimplePropertyProcessor.class);
+    when(entitySimpleProperty.readEntitySimpleProperty(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entitySimpleProperty.updateEntitySimpleProperty(any(UriInfoImpl.class), any(InputStream.class), anyString(), anyString())).thenAnswer(getAnswer());
+
+    EntitySimplePropertyValueProcessor entitySimplePropertyValue = mock(EntitySimplePropertyValueProcessor.class);
+    when(entitySimplePropertyValue.readEntitySimplePropertyValue(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entitySimplePropertyValue.deleteEntitySimplePropertyValue(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entitySimplePropertyValue.updateEntitySimplePropertyValue(any(UriInfoImpl.class), any(InputStream.class), anyString(), anyString())).thenAnswer(getAnswer());
+
+    EntityLinkProcessor entityLink = mock(EntityLinkProcessor.class);
+    when(entityLink.readEntityLink(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entityLink.existsEntityLink(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entityLink.deleteEntityLink(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entityLink.updateEntityLink(any(UriInfoImpl.class), any(InputStream.class), anyString(), anyString())).thenAnswer(getAnswer());
+
+    EntityLinksProcessor entityLinks = mock(EntityLinksProcessor.class);
+    when(entityLinks.readEntityLinks(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entityLinks.countEntityLinks(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entityLinks.createEntityLink(any(UriInfoImpl.class), any(InputStream.class), anyString(), anyString())).thenAnswer(getAnswer());
+
+    MetadataProcessor metadata = mock(MetadataProcessor.class);
+    when(metadata.readMetadata(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+
+    BatchProcessor batch = mock(BatchProcessor.class);
+    when(batch.executeBatch(any(BatchHandler.class), anyString(), any(InputStream.class))).thenAnswer(getAnswer());
+
+    FunctionImportProcessor functionImport = mock(FunctionImportProcessor.class);
+    when(functionImport.executeFunctionImport(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+
+    FunctionImportValueProcessor functionImportValue = mock(FunctionImportValueProcessor.class);
+    when(functionImportValue.executeFunctionImportValue(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+
+    EntityMediaProcessor entityMedia = mock(EntityMediaProcessor.class);
+    when(entityMedia.readEntityMedia(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entityMedia.deleteEntityMedia(any(UriInfoImpl.class), anyString())).thenAnswer(getAnswer());
+    when(entityMedia.updateEntityMedia(any(UriInfoImpl.class), any(InputStream.class), anyString(), anyString())).thenAnswer(getAnswer());
+
+    ODataService service = mock(ODataService.class);
+    when(service.getServiceDocumentProcessor()).thenReturn(serviceDocument);
+    when(service.getEntitySetProcessor()).thenReturn(entitySet);
+    when(service.getEntityProcessor()).thenReturn(entity);
+    when(service.getEntityComplexPropertyProcessor()).thenReturn(entityComplexProperty);
+    when(service.getEntitySimplePropertyProcessor()).thenReturn(entitySimpleProperty);
+    when(service.getEntitySimplePropertyValueProcessor()).thenReturn(entitySimplePropertyValue);
+    when(service.getEntityLinkProcessor()).thenReturn(entityLink);
+    when(service.getEntityLinksProcessor()).thenReturn(entityLinks);
+    when(service.getMetadataProcessor()).thenReturn(metadata);
+    when(service.getBatchProcessor()).thenReturn(batch);
+    when(service.getFunctionImportProcessor()).thenReturn(functionImport);
+    when(service.getFunctionImportValueProcessor()).thenReturn(functionImportValue);
+    when(service.getEntityMediaProcessor()).thenReturn(entityMedia);
+
+    return service;
+  }
+
+  private static Answer<ODataResponse> getAnswer() {
+    return new Answer<ODataResponse>() {
+      @Override
+      public ODataResponse answer(final InvocationOnMock invocation) {
+        return mockResponse(invocation.getMethod().getName());
+      }
+    };
+  }
+
+  private static ODataResponse mockResponse(final String value) {
+    ODataResponse response = mock(ODataResponse.class);
+    when(response.getStatus()).thenReturn(HttpStatusCodes.PAYMENT_REQUIRED);
+    when(response.getEntity()).thenReturn(value);
+
+    return response;
+  }
+
+  private static UriInfoImpl mockUriInfo(final UriType uriType, final boolean isValue) throws EdmException {
+    UriInfoImpl uriInfo = mock(UriInfoImpl.class);
+    when(uriInfo.getUriType()).thenReturn(uriType);
+    when(uriInfo.isValue()).thenReturn(isValue);
+    return uriInfo;
+  }
+
+  private static void checkDispatch(final ODataHttpMethod method, final UriType uriType, final boolean isValue, final String expectedMethodName) throws ODataException {
+    ODataServiceFactory factory = mock(ODataServiceFactory.class);
+
+    final ODataResponse response = new Dispatcher(factory, getMockService())
+        .dispatch(method, mockUriInfo(uriType, isValue), null, "application/xml", "*/*");
+    assertEquals(expectedMethodName, response.getEntity());
+  }
+
+  private static void checkDispatch(final ODataHttpMethod method, final UriType uriType, final String expectedMethodName) throws ODataException {
+    checkDispatch(method, uriType, false, expectedMethodName);
+  }
+
+  private static void wrongDispatch(final ODataHttpMethod method, final UriType uriType) {
+    try {
+      checkDispatch(method, uriType, null);
+      fail("Expected ODataException not thrown");
+    } catch (ODataMethodNotAllowedException e) {
+      assertNotNull(e);
+    } catch (ODataException e) {
+      fail("Expected ODataMethodNotAllowedException not thrown");
+    }
+  }
+
+  private static void notSupportedDispatch(final ODataHttpMethod method, final UriType uriType) {
+    try {
+      checkDispatch(method, uriType, null);
+      fail("Expected ODataException not thrown");
+    } catch (ODataBadRequestException e) {
+      assertNotNull(e);
+    } catch (ODataException e) {
+      fail("Expected ODataBadRequestException not thrown");
+    }
+  }
+
+  @Test
+  public void dispatch() throws Exception {
+    checkDispatch(ODataHttpMethod.GET, UriType.URI0, "readServiceDocument");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI1, "readEntitySet");
+    checkDispatch(ODataHttpMethod.POST, UriType.URI1, "createEntity");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI2, "readEntity");
+    checkDispatch(ODataHttpMethod.PUT, UriType.URI2, "updateEntity");
+    checkDispatch(ODataHttpMethod.DELETE, UriType.URI2, "deleteEntity");
+    checkDispatch(ODataHttpMethod.PATCH, UriType.URI2, "updateEntity");
+    checkDispatch(ODataHttpMethod.MERGE, UriType.URI2, "updateEntity");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI3, "readEntityComplexProperty");
+    checkDispatch(ODataHttpMethod.PUT, UriType.URI3, "updateEntityComplexProperty");
+    checkDispatch(ODataHttpMethod.PATCH, UriType.URI3, "updateEntityComplexProperty");
+    checkDispatch(ODataHttpMethod.MERGE, UriType.URI3, "updateEntityComplexProperty");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI4, "readEntitySimpleProperty");
+    checkDispatch(ODataHttpMethod.PUT, UriType.URI4, "updateEntitySimpleProperty");
+    checkDispatch(ODataHttpMethod.PATCH, UriType.URI4, "updateEntitySimpleProperty");
+    checkDispatch(ODataHttpMethod.MERGE, UriType.URI4, "updateEntitySimpleProperty");
+    checkDispatch(ODataHttpMethod.GET, UriType.URI4, true, "readEntitySimplePropertyValue");
+    checkDispatch(ODataHttpMethod.PUT, UriType.URI4, true, "updateEntitySimplePropertyValue");
+    checkDispatch(ODataHttpMethod.DELETE, UriType.URI4, true, "deleteEntitySimplePropertyValue");
+    checkDispatch(ODataHttpMethod.PATCH, UriType.URI4, true, "updateEntitySimplePropertyValue");
+    checkDispatch(ODataHttpMethod.MERGE, UriType.URI4, true, "updateEntitySimplePropertyValue");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI5, "readEntitySimpleProperty");
+    checkDispatch(ODataHttpMethod.PUT, UriType.URI5, "updateEntitySimpleProperty");
+    checkDispatch(ODataHttpMethod.PATCH, UriType.URI5, "updateEntitySimpleProperty");
+    checkDispatch(ODataHttpMethod.MERGE, UriType.URI5, "updateEntitySimpleProperty");
+    checkDispatch(ODataHttpMethod.GET, UriType.URI5, true, "readEntitySimplePropertyValue");
+    checkDispatch(ODataHttpMethod.PUT, UriType.URI5, true, "updateEntitySimplePropertyValue");
+    checkDispatch(ODataHttpMethod.DELETE, UriType.URI5, true, "deleteEntitySimplePropertyValue");
+    checkDispatch(ODataHttpMethod.PATCH, UriType.URI5, true, "updateEntitySimplePropertyValue");
+    checkDispatch(ODataHttpMethod.MERGE, UriType.URI5, true, "updateEntitySimplePropertyValue");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI6A, "readEntity");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI6B, "readEntitySet");
+    checkDispatch(ODataHttpMethod.POST, UriType.URI6B, "createEntity");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI7A, "readEntityLink");
+    checkDispatch(ODataHttpMethod.PUT, UriType.URI7A, "updateEntityLink");
+    checkDispatch(ODataHttpMethod.DELETE, UriType.URI7A, "deleteEntityLink");
+    checkDispatch(ODataHttpMethod.PATCH, UriType.URI7A, "updateEntityLink");
+    checkDispatch(ODataHttpMethod.MERGE, UriType.URI7A, "updateEntityLink");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI7B, "readEntityLinks");
+    checkDispatch(ODataHttpMethod.POST, UriType.URI7B, "createEntityLink");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI8, "readMetadata");
+
+    checkDispatch(ODataHttpMethod.POST, UriType.URI9, "executeBatch");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI10, "executeFunctionImport");
+    checkDispatch(ODataHttpMethod.GET, UriType.URI11, "executeFunctionImport");
+    checkDispatch(ODataHttpMethod.GET, UriType.URI12, "executeFunctionImport");
+    checkDispatch(ODataHttpMethod.GET, UriType.URI13, "executeFunctionImport");
+    checkDispatch(ODataHttpMethod.GET, UriType.URI14, "executeFunctionImport");
+    checkDispatch(ODataHttpMethod.GET, UriType.URI14, true, "executeFunctionImportValue");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI15, "countEntitySet");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI16, "existsEntity");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI17, "readEntityMedia");
+    checkDispatch(ODataHttpMethod.PUT, UriType.URI17, "updateEntityMedia");
+    checkDispatch(ODataHttpMethod.DELETE, UriType.URI17, "deleteEntityMedia");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI50A, "existsEntityLink");
+
+    checkDispatch(ODataHttpMethod.GET, UriType.URI50B, "countEntityLinks");
+  }
+
+  @Test
+  public void dispatchNotAllowedCombinations() throws Exception {
+    wrongDispatch(null, UriType.URI0);
+
+    wrongDispatch(ODataHttpMethod.PUT, UriType.URI0);
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI0);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI0);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI0);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI0);
+
+    wrongDispatch(ODataHttpMethod.PUT, UriType.URI1);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI1);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI1);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI1);
+
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI2);
+
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI3);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI3);
+
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI4);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI4);
+
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI5);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI5);
+
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI6A);
+
+    wrongDispatch(ODataHttpMethod.PUT, UriType.URI6B);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI6B);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI6B);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI6B);
+
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI7A);
+
+    wrongDispatch(ODataHttpMethod.PUT, UriType.URI7B);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI7B);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI7B);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI7B);
+
+    wrongDispatch(ODataHttpMethod.PUT, UriType.URI8);
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI8);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI8);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI8);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI8);
+
+    wrongDispatch(ODataHttpMethod.GET, UriType.URI9);
+    wrongDispatch(ODataHttpMethod.PUT, UriType.URI9);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI9);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI9);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI9);
+
+    wrongDispatch(ODataHttpMethod.PUT, UriType.URI15);
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI15);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI15);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI15);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI15);
+
+    wrongDispatch(ODataHttpMethod.PUT, UriType.URI16);
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI16);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI16);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI16);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI16);
+
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI17);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI17);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI17);
+
+    wrongDispatch(ODataHttpMethod.PUT, UriType.URI50A);
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI50A);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI50A);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI50A);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI50A);
+
+    wrongDispatch(ODataHttpMethod.PUT, UriType.URI50B);
+    wrongDispatch(ODataHttpMethod.POST, UriType.URI50B);
+    wrongDispatch(ODataHttpMethod.DELETE, UriType.URI50B);
+    wrongDispatch(ODataHttpMethod.PATCH, UriType.URI50B);
+    wrongDispatch(ODataHttpMethod.MERGE, UriType.URI50B);
+  }
+
+  @Test
+  public void dispatchNotSupportedCombinations() throws Exception {
+    notSupportedDispatch(ODataHttpMethod.PUT, UriType.URI6A);
+    notSupportedDispatch(ODataHttpMethod.DELETE, UriType.URI6A);
+    notSupportedDispatch(ODataHttpMethod.PATCH, UriType.URI6A);
+    notSupportedDispatch(ODataHttpMethod.MERGE, UriType.URI6A);
+  }
+
+  private static void checkFeature(final UriType uriType, final boolean isValue, final Class<? extends ODataProcessor> feature) throws ODataException {
+    ODataServiceFactory factory = mock(ODataServiceFactory.class);
+    new Dispatcher(factory, getMockService());
+    assertEquals(feature, Dispatcher.mapUriTypeToProcessorFeature(mockUriInfo(uriType, isValue)));
+    assertEquals(feature, Dispatcher.mapUriTypeToProcessorFeature(mockUriInfo(uriType, isValue)));
+  }
+
+  @Test
+  public void processorFeature() throws Exception {
+    checkFeature(UriType.URI0, false, ServiceDocumentProcessor.class);
+    checkFeature(UriType.URI1, false, EntitySetProcessor.class);
+    checkFeature(UriType.URI2, false, EntityProcessor.class);
+    checkFeature(UriType.URI3, false, EntityComplexPropertyProcessor.class);
+    checkFeature(UriType.URI4, false, EntitySimplePropertyProcessor.class);
+    checkFeature(UriType.URI4, true, EntitySimplePropertyValueProcessor.class);
+    checkFeature(UriType.URI5, false, EntitySimplePropertyProcessor.class);
+    checkFeature(UriType.URI5, true, EntitySimplePropertyValueProcessor.class);
+    checkFeature(UriType.URI6A, false, EntityProcessor.class);
+    checkFeature(UriType.URI6B, false, EntitySetProcessor.class);
+    checkFeature(UriType.URI7A, false, EntityLinkProcessor.class);
+    checkFeature(UriType.URI7B, false, EntityLinksProcessor.class);
+    checkFeature(UriType.URI8, false, MetadataProcessor.class);
+    checkFeature(UriType.URI9, false, BatchProcessor.class);
+    checkFeature(UriType.URI10, false, FunctionImportProcessor.class);
+    checkFeature(UriType.URI11, false, FunctionImportProcessor.class);
+    checkFeature(UriType.URI12, false, FunctionImportProcessor.class);
+    checkFeature(UriType.URI13, false, FunctionImportProcessor.class);
+    checkFeature(UriType.URI14, false, FunctionImportProcessor.class);
+    checkFeature(UriType.URI14, true, FunctionImportValueProcessor.class);
+    checkFeature(UriType.URI15, false, EntitySetProcessor.class);
+    checkFeature(UriType.URI16, false, EntityProcessor.class);
+    checkFeature(UriType.URI17, false, EntityMediaProcessor.class);
+    checkFeature(UriType.URI50A, false, EntityLinkProcessor.class);
+    checkFeature(UriType.URI50B, false, EntityLinksProcessor.class);
+  }
+
+  @Test
+  public void contentNegotiationDefaultCharset() throws Exception {
+    negotiateContentTypeCharset("application/xml", "application/xml;charset=utf-8", false);
+  }
+
+  @Test
+  public void contentNegotiationDefaultCharsetAsDollarFormat() throws Exception {
+    negotiateContentTypeCharset("application/xml", "application/xml;charset=utf-8", true);
+  }
+
+  @Test
+  public void contentNegotiationSupportedCharset() throws Exception {
+    negotiateContentTypeCharset("application/xml;charset=utf-8", "application/xml;charset=utf-8", false);
+  }
+
+  @Test
+  public void contentNegotiationSupportedCharsetAsDollarFormat() throws Exception {
+    negotiateContentTypeCharset("application/xml;charset=utf-8", "application/xml;charset=utf-8", true);
+  }
+
+  @SuppressWarnings("unchecked")
+  private void negotiateContentTypeCharset(final String requestType, final String supportedType, final boolean asFormat)
+      throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException, ODataException {
+
+    ODataServiceFactory factory = mock(ODataServiceFactory.class);
+    ODataService service = Mockito.mock(ODataService.class);
+    Dispatcher dispatcher = new Dispatcher(factory, service);
+
+    UriInfoImpl uriInfo = new UriInfoImpl();
+    uriInfo.setUriType(UriType.URI1); // 
+    if (asFormat) {
+      uriInfo.setFormat(requestType);
+    }
+
+    Mockito.when(service.getSupportedContentTypes(Matchers.any(Class.class))).thenReturn(Arrays.asList(supportedType));
+    EntitySetProcessor processor = Mockito.mock(EntitySetProcessor.class);
+    ODataResponse response = Mockito.mock(ODataResponse.class);
+    Mockito.when(response.getContentHeader()).thenReturn(supportedType);
+    Mockito.when(processor.readEntitySet(uriInfo, supportedType)).thenReturn(response);
+    Mockito.when(service.getEntitySetProcessor()).thenReturn(processor);
+
+    InputStream content = null;
+    ODataResponse odataResponse = dispatcher.dispatch(ODataHttpMethod.GET, uriInfo, content, requestType, supportedType);
+    assertEquals(supportedType, odataResponse.getContentHeader());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataContextImplTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataContextImplTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataContextImplTest.java
new file mode 100644
index 0000000..8c3f040
--- /dev/null
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataContextImplTest.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.olingo.odata2.api.ODataServiceFactory;
+import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataRequest;
+
+/**
+ * @author SAP AG
+ */
+public class ODataContextImplTest {
+
+  ODataContextImpl context;
+
+  @Before
+  public void before() {
+    ODataServiceFactory factory = mock(ODataServiceFactory.class);
+    ODataRequest request = mock(ODataRequest.class);
+
+    when(request.getMethod()).thenReturn(ODataHttpMethod.GET);
+    when(request.getPathInfo()).thenReturn(new PathInfoImpl());
+
+    context = new ODataContextImpl(request, factory);
+  }
+
+  @Test
+  public void httpMethod() {
+    context.setHttpMethod(ODataHttpMethod.GET.name());
+    assertEquals(ODataHttpMethod.GET.name(), context.getHttpMethod());
+  }
+
+  @Test
+  public void debugMode() {
+    context.setDebugMode(true);
+    assertTrue(context.isInDebugMode());
+  }
+
+  @Test
+  public void parentContext() {
+
+    assertFalse(context.isInBatchMode());
+    assertNull(context.getBatchParentContext());
+
+    ODataContext parentContext = mock(ODataContext.class);
+    context.setBatchParentContext(parentContext);
+
+    assertTrue(context.isInBatchMode());
+    assertNotNull(context.getBatchParentContext());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataExceptionWrapperTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataExceptionWrapperTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataExceptionWrapperTest.java
new file mode 100644
index 0000000..bc68292
--- /dev/null
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataExceptionWrapperTest.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.when;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedHashMap;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import org.apache.olingo.odata2.api.ODataCallback;
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.ODataServiceFactory;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataErrorCallback;
+import org.apache.olingo.odata2.api.processor.ODataErrorContext;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.apache.olingo.odata2.core.rest.ODataErrorHandlerCallbackImpl;
+import org.apache.olingo.odata2.testutil.fit.BaseTest;
+
+/**
+ * @author SAP AG
+ */
+public class ODataExceptionWrapperTest extends BaseTest {
+
+  /**
+   * Wrap an exception and verify that {@link PathInfo} is available and filled with correct values.
+   * 
+   */
+  @Test
+  public void testCallbackPathInfoAvailable() throws Exception {
+    ODataContextImpl context = getMockedContext("http://localhost:80/test", "ODataServiceRoot");
+    ODataErrorCallback errorCallback = new ODataErrorCallback() {
+      @Override
+      public ODataResponse handleError(final ODataErrorContext context) throws ODataApplicationException {
+        PathInfo pathInfo = context.getPathInfo();
+        assertEquals("ODataServiceRoot", pathInfo.getServiceRoot().toString());
+        assertEquals("http://localhost:80/test", pathInfo.getRequestUri().toString());
+        return ODataResponse.entity("bla").status(HttpStatusCodes.BAD_REQUEST).contentHeader("text/html").build();
+      }
+    };
+    when(context.getServiceFactory()).thenReturn(new MapperServiceFactory(errorCallback));
+
+    //
+    Map<String, String> queryParameters = Collections.emptyMap();
+    List<String> acceptContentTypes = Arrays.asList("text/html");
+    ODataExceptionWrapper exceptionWrapper = createWrapper(context, queryParameters, acceptContentTypes);
+    ODataResponse response = exceptionWrapper.wrapInExceptionResponse(new Exception());
+
+    // verify
+    assertNotNull(response);
+    assertEquals(HttpStatusCodes.BAD_REQUEST.getStatusCode(), response.getStatus().getStatusCode());
+    String errorMessage = (String) response.getEntity();
+    assertEquals("bla", errorMessage);
+    String contentTypeHeader = response.getContentHeader();
+    assertEquals("text/html", contentTypeHeader);
+  }
+
+  private ODataExceptionWrapper createWrapper(final ODataContextImpl context, final Map<String, String> queryParameters, final List<String> acceptContentTypes) throws URISyntaxException {
+    ODataExceptionWrapper exceptionWrapper = new ODataExceptionWrapper(context, queryParameters, acceptContentTypes);
+
+    return exceptionWrapper;
+  }
+
+  private ODataContextImpl getMockedContext(final String requestUri, final String serviceRoot) throws ODataException, URISyntaxException {
+    ODataContextImpl context = Mockito.mock(ODataContextImpl.class);
+    PathInfoImpl pathInfo = new PathInfoImpl();
+    pathInfo.setRequestUri(new URI(requestUri));
+    pathInfo.setServiceRoot(new URI(serviceRoot));
+    when(context.getPathInfo()).thenReturn(pathInfo);
+    when(context.getRequestHeaders()).thenReturn(new MultivaluedHashMap<String, String>());
+    return context;
+  }
+
+  public static final class MapperServiceFactory extends ODataServiceFactory {
+    private ODataErrorCallback errorCallback;
+
+    public MapperServiceFactory(final ODataErrorCallback callback) {
+      errorCallback = callback;
+    }
+
+    @Override
+    public ODataService createService(final ODataContext ctx) throws ODataException {
+      return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends ODataCallback> T getCallback(final Class<? extends ODataCallback> callbackInterface) {
+      if (callbackInterface == ODataErrorCallback.class) {
+        if (errorCallback == null) {
+          return (T) new ODataErrorHandlerCallbackImpl();
+        }
+        return (T) errorCallback;
+      }
+      // only error callbacks are handled here
+      return null;
+    }
+  }
+}