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 2014/09/30 11:19:43 UTC

git commit: Minor Bugfix: Double system query options result in server error

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 7e0b013ce -> 493879173


Minor Bugfix: Double system query options result in server error


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/49387917
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/49387917
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/49387917

Branch: refs/heads/master
Commit: 493879173a277c14dceaa81ca18556c535243fd6
Parents: 7e0b013
Author: Michael Bolz <mi...@sap.com>
Authored: Tue Sep 30 11:19:29 2014 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Tue Sep 30 11:19:29 2014 +0200

----------------------------------------------------------------------
 .../olingo/server/core/uri/UriInfoImpl.java     |  61 ++---
 .../olingo/server/core/uri/parser/Parser.java   | 223 ++++++++++---------
 .../uri/parser/UriParserSyntaxException.java    |   1 +
 .../server-core-exceptions-i18n.properties      |   1 +
 .../olingo/server/core/uri/UriInfoImplTest.java |   8 +
 .../core/uri/antlr/TestUriParserImpl.java       |   3 +-
 .../core/uri/validator/UriValidatorTest.java    |   5 +
 7 files changed, 165 insertions(+), 137 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/49387917/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
index 2b4b266..9990da6 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriInfoImpl.java
@@ -53,6 +53,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 public class UriInfoImpl implements UriInfo {
 
@@ -62,9 +63,9 @@ public class UriInfoImpl implements UriInfo {
   private EdmEntityType entityTypeCast; // for $entity
 
   private List<CustomQueryOptionImpl> customQueryOptions = new ArrayList<CustomQueryOptionImpl>();
-  private HashMap<String, String> aliasToValue = new HashMap<String, String>();
+  private Map<String, String> aliasToValue = new HashMap<String, String>();
 
-  HashMap<SystemQueryOptionKind, SystemQueryOption> systemQueryOptions =
+  Map<SystemQueryOptionKind, SystemQueryOption> systemQueryOptions =
       new HashMap<SystemQueryOptionKind, SystemQueryOption>();
 
   private String fragment;
@@ -239,36 +240,36 @@ public class UriInfoImpl implements UriInfo {
     }
   }
 
-  public UriInfoImpl setSystemQueryOption(final SystemQueryOptionImpl systemOption) {
-
-    if (systemOption.getKind() == SystemQueryOptionKind.EXPAND) {
-      systemQueryOptions.put(SystemQueryOptionKind.EXPAND, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.FILTER) {
-      systemQueryOptions.put(SystemQueryOptionKind.FILTER, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.FORMAT) {
-      systemQueryOptions.put(SystemQueryOptionKind.FORMAT, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.ID) {
-      systemQueryOptions.put(SystemQueryOptionKind.ID, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.COUNT) {
-      systemQueryOptions.put(SystemQueryOptionKind.COUNT, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.ORDERBY) {
-      systemQueryOptions.put(SystemQueryOptionKind.ORDERBY, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.SEARCH) {
-      systemQueryOptions.put(SystemQueryOptionKind.SEARCH, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.SELECT) {
-      systemQueryOptions.put(SystemQueryOptionKind.SELECT, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.SKIP) {
-      systemQueryOptions.put(SystemQueryOptionKind.SKIP, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.SKIPTOKEN) {
-      systemQueryOptions.put(SystemQueryOptionKind.SKIPTOKEN, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.TOP) {
-      systemQueryOptions.put(SystemQueryOptionKind.TOP, systemOption);
-    } else if (systemOption.getKind() == SystemQueryOptionKind.LEVELS) {
-      systemQueryOptions.put(SystemQueryOptionKind.LEVELS, systemOption);
-    } else {
+  /** Adds system query option.
+   * @param systemOption the option to be added
+   * @return this object for method chaining
+   * @throws ODataRuntimeException if an unsupported option is provided
+   *                               or an option of this kind has been added before
+   */
+  public UriInfoImpl setSystemQueryOption(final SystemQueryOption systemOption) {
+    final SystemQueryOptionKind kind = systemOption.getKind();
+    switch (kind) {
+    case EXPAND:
+    case FILTER:
+    case FORMAT:
+    case ID:
+    case COUNT:
+    case ORDERBY:
+    case SEARCH:
+    case SELECT:
+    case SKIP:
+    case SKIPTOKEN:
+    case TOP:
+    case LEVELS:
+      if (systemQueryOptions.containsKey(kind)) {
+        throw new ODataRuntimeException("Double System Query Option: " + systemOption.getName());
+      } else {
+        systemQueryOptions.put(kind, systemOption);
+      }
+      break;
+    default:
       throw new ODataRuntimeException("Unsupported System Query Option: " + systemOption.getName());
     }
-
     return this;
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/49387917/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
index c2be438..450ad2b 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
@@ -27,12 +27,14 @@ import org.antlr.v4.runtime.RecognitionException;
 import org.antlr.v4.runtime.Token;
 import org.antlr.v4.runtime.atn.PredictionMode;
 import org.antlr.v4.runtime.misc.ParseCancellationException;
+import org.apache.olingo.commons.api.ODataRuntimeException;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.server.api.uri.UriInfo;
 import org.apache.olingo.server.api.uri.UriInfoKind;
 import org.apache.olingo.server.api.uri.UriResource;
 import org.apache.olingo.server.api.uri.UriResourcePartTyped;
+import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
 import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
 import org.apache.olingo.server.core.uri.UriInfoImpl;
 import org.apache.olingo.server.core.uri.antlr.UriLexer;
@@ -161,118 +163,127 @@ public class Parser {
       }
 
       if (readQueryParameter) {
-        // second, read the simple systemQueryOptions and the Custom QueryOptions
+        // second, read the system query options and the custom query options
         for (RawUri.QueryOption option : uri.queryOptionListDecoded) {
-          if (!option.name.startsWith("$")) {
-            CustomQueryOptionImpl customOption = new CustomQueryOptionImpl();
-            customOption.setName(option.name);
-            customOption.setText(option.value);
-            context.contextUriInfo.addCustomQueryOption(customOption);
-          } else if (option.name.equals(SystemQueryOptionKind.FILTER.toString())) {
-            FilterExpressionEOFContext ctxFilterExpression =
-                (FilterExpressionEOFContext) parseRule(option.value, ParserEntryRules.FilterExpression);
-
-            FilterOptionImpl filterOption =
-                (FilterOptionImpl) uriParseTreeVisitor.visitFilterExpressionEOF(ctxFilterExpression);
-
-            context.contextUriInfo.setSystemQueryOption(filterOption);
-
-          } else if (option.name.equals(SystemQueryOptionKind.FORMAT.toString())) {
-            FormatOptionImpl formatOption = new FormatOptionImpl();
-            formatOption.setName(option.name);
-            formatOption.setText(option.value);
-            if (option.value.equalsIgnoreCase(ODataFormat.JSON.name())
-                || option.value.equalsIgnoreCase(ODataFormat.XML.name())
-                || option.value.equalsIgnoreCase(ODataFormat.ATOM.name())
-                || isFormatSyntaxValid(option)) {
-              formatOption.setFormat(option.value);
+          if (option.name.startsWith("$")) {
+            SystemQueryOption systemOption = null;
+            if (option.name.equals(SystemQueryOptionKind.FILTER.toString())) {
+              FilterExpressionEOFContext ctxFilterExpression =
+                  (FilterExpressionEOFContext) parseRule(option.value, ParserEntryRules.FilterExpression);
+
+              FilterOptionImpl filterOption =
+                  (FilterOptionImpl) uriParseTreeVisitor.visitFilterExpressionEOF(ctxFilterExpression);
+
+              systemOption = filterOption;
+
+            } else if (option.name.equals(SystemQueryOptionKind.FORMAT.toString())) {
+              FormatOptionImpl formatOption = new FormatOptionImpl();
+              formatOption.setName(option.name);
+              formatOption.setText(option.value);
+              if (option.value.equalsIgnoreCase(ODataFormat.JSON.name())
+                  || option.value.equalsIgnoreCase(ODataFormat.XML.name())
+                  || option.value.equalsIgnoreCase(ODataFormat.ATOM.name())
+                  || isFormatSyntaxValid(option)) {
+                formatOption.setFormat(option.value);
+              } else {
+                throw new UriParserSyntaxException("Illegal value of $format option!",
+                    UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT, option.value);
+              }
+              systemOption = formatOption;
+
+            } else if (option.name.equals(SystemQueryOptionKind.EXPAND.toString())) {
+              ExpandItemsEOFContext ctxExpandItems =
+                  (ExpandItemsEOFContext) parseRule(option.value, ParserEntryRules.ExpandItems);
+
+              ExpandOptionImpl expandOption =
+                  (ExpandOptionImpl) uriParseTreeVisitor.visitExpandItemsEOF(ctxExpandItems);
+
+              systemOption = expandOption;
+
+            } else if (option.name.equals(SystemQueryOptionKind.ID.toString())) {
+              IdOptionImpl idOption = new IdOptionImpl();
+              idOption.setName(option.name);
+              idOption.setText(option.value);
+              idOption.setValue(option.value);
+              systemOption = idOption;
+            } else if (option.name.equals(SystemQueryOptionKind.LEVELS.toString())) {
+              throw new UriParserSyntaxException("System query option '$levels' is allowed only inside '$expand'!",
+                  UriParserSyntaxException.MessageKeys.SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE);
+            } else if (option.name.equals(SystemQueryOptionKind.ORDERBY.toString())) {
+              OrderByEOFContext ctxOrderByExpression =
+                  (OrderByEOFContext) parseRule(option.value, ParserEntryRules.Orderby);
+
+              OrderByOptionImpl orderByOption =
+                  (OrderByOptionImpl) uriParseTreeVisitor.visitOrderByEOF(ctxOrderByExpression);
+
+              systemOption = orderByOption;
+            } else if (option.name.equals(SystemQueryOptionKind.SEARCH.toString())) {
+              throw new RuntimeException("System query option '$search' not implemented!");
+            } else if (option.name.equals(SystemQueryOptionKind.SELECT.toString())) {
+              SelectEOFContext ctxSelectEOF =
+                  (SelectEOFContext) parseRule(option.value, ParserEntryRules.Select);
+
+              SelectOptionImpl selectOption =
+                  (SelectOptionImpl) uriParseTreeVisitor.visitSelectEOF(ctxSelectEOF);
+
+              systemOption = selectOption;
+            } else if (option.name.equals(SystemQueryOptionKind.SKIP.toString())) {
+              SkipOptionImpl skipOption = new SkipOptionImpl();
+              skipOption.setName(option.name);
+              skipOption.setText(option.value);
+              try {
+                skipOption.setValue(Integer.parseInt(option.value));
+              } catch (final NumberFormatException e) {
+                throw new UriParserSyntaxException("Illegal value of $skip option!", e,
+                    UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
+                    option.name, option.value);
+              }
+              systemOption = skipOption;
+            } else if (option.name.equals(SystemQueryOptionKind.SKIPTOKEN.toString())) {
+              SkipTokenOptionImpl skipTokenOption = new SkipTokenOptionImpl();
+              skipTokenOption.setName(option.name);
+              skipTokenOption.setText(option.value);
+              skipTokenOption.setValue(option.value);
+              systemOption = skipTokenOption;
+            } else if (option.name.equals(SystemQueryOptionKind.TOP.toString())) {
+              TopOptionImpl topOption = new TopOptionImpl();
+              topOption.setName(option.name);
+              topOption.setText(option.value);
+              try {
+                topOption.setValue(Integer.parseInt(option.value));
+              } catch (final NumberFormatException e) {
+                throw new UriParserSyntaxException("Illegal value of $top option!", e,
+                    UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
+                    option.name, option.value);
+              }
+              systemOption = topOption;
+            } else if (option.name.equals(SystemQueryOptionKind.COUNT.toString())) {
+              CountOptionImpl inlineCountOption = new CountOptionImpl();
+              inlineCountOption.setName(option.name);
+              inlineCountOption.setText(option.value);
+              if (option.value.equals("true") || option.value.equals("false")) {
+                inlineCountOption.setValue(Boolean.parseBoolean(option.value));
+              } else {
+                throw new UriParserSyntaxException("Illegal value of $count option!",
+                    UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
+                    option.name, option.value);
+              }
+              systemOption = inlineCountOption;
             } else {
-              throw new UriParserSyntaxException("Illegal value of $format option!",
-                  UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT, option.value);
-            }
-            context.contextUriInfo.setSystemQueryOption(formatOption);
-
-          } else if (option.name.equals(SystemQueryOptionKind.EXPAND.toString())) {
-            ExpandItemsEOFContext ctxExpandItems =
-                (ExpandItemsEOFContext) parseRule(option.value, ParserEntryRules.ExpandItems);
-
-            ExpandOptionImpl expandOption =
-                (ExpandOptionImpl) uriParseTreeVisitor.visitExpandItemsEOF(ctxExpandItems);
-
-            context.contextUriInfo.setSystemQueryOption(expandOption);
-
-          } else if (option.name.equals(SystemQueryOptionKind.ID.toString())) {
-            IdOptionImpl idOption = new IdOptionImpl();
-            idOption.setName(option.name);
-            idOption.setText(option.value);
-            idOption.setValue(option.value);
-            context.contextUriInfo.setSystemQueryOption(idOption);
-          } else if (option.name.equals(SystemQueryOptionKind.LEVELS.toString())) {
-            throw new UriParserSyntaxException("System query option '$levels' is allowed only inside '$expand'!",
-                UriParserSyntaxException.MessageKeys.SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE);
-          } else if (option.name.equals(SystemQueryOptionKind.ORDERBY.toString())) {
-            OrderByEOFContext ctxOrderByExpression =
-                (OrderByEOFContext) parseRule(option.value, ParserEntryRules.Orderby);
-
-            OrderByOptionImpl orderByOption =
-                (OrderByOptionImpl) uriParseTreeVisitor.visitOrderByEOF(ctxOrderByExpression);
-
-            context.contextUriInfo.setSystemQueryOption(orderByOption);
-          } else if (option.name.equals(SystemQueryOptionKind.SEARCH.toString())) {
-            throw new RuntimeException("System query option '$search' not implemented!");
-          } else if (option.name.equals(SystemQueryOptionKind.SELECT.toString())) {
-            SelectEOFContext ctxSelectEOF =
-                (SelectEOFContext) parseRule(option.value, ParserEntryRules.Select);
-
-            SelectOptionImpl selectOption =
-                (SelectOptionImpl) uriParseTreeVisitor.visitSelectEOF(ctxSelectEOF);
-
-            context.contextUriInfo.setSystemQueryOption(selectOption);
-          } else if (option.name.equals(SystemQueryOptionKind.SKIP.toString())) {
-            SkipOptionImpl skipOption = new SkipOptionImpl();
-            skipOption.setName(option.name);
-            skipOption.setText(option.value);
-            try {
-              skipOption.setValue(Integer.parseInt(option.value));
-            } catch (final NumberFormatException e) {
-              throw new UriParserSyntaxException("Illegal value of $skip option!", e,
-                  UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
-                  option.name, option.value);
+              throw new UriParserSyntaxException("Unknown system query option!",
+                  UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION, option.name);
             }
-            context.contextUriInfo.setSystemQueryOption(skipOption);
-          } else if (option.name.equals(SystemQueryOptionKind.SKIPTOKEN.toString())) {
-            SkipTokenOptionImpl skipTokenOption = new SkipTokenOptionImpl();
-            skipTokenOption.setName(option.name);
-            skipTokenOption.setText(option.value);
-            skipTokenOption.setValue(option.value);
-            context.contextUriInfo.setSystemQueryOption(skipTokenOption);
-          } else if (option.name.equals(SystemQueryOptionKind.TOP.toString())) {
-            TopOptionImpl topOption = new TopOptionImpl();
-            topOption.setName(option.name);
-            topOption.setText(option.value);
             try {
-              topOption.setValue(Integer.parseInt(option.value));
-            } catch (final NumberFormatException e) {
-              throw new UriParserSyntaxException("Illegal value of $top option!", e,
-                  UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
-                  option.name, option.value);
+              context.contextUriInfo.setSystemQueryOption(systemOption);
+            } catch (final ODataRuntimeException e) {
+              throw new UriParserSyntaxException("Double system query option!", e,
+                  UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION, option.name);
             }
-            context.contextUriInfo.setSystemQueryOption(topOption);
-          } else if (option.name.equals(SystemQueryOptionKind.COUNT.toString())) {
-            CountOptionImpl inlineCountOption = new CountOptionImpl();
-            inlineCountOption.setName(option.name);
-            inlineCountOption.setText(option.value);
-            if (option.value.equals("true") || option.value.equals("false")) {
-              inlineCountOption.setValue(Boolean.parseBoolean(option.value));
-            } else {
-              throw new UriParserSyntaxException("Illegal value of $count option!",
-                  UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
-                  option.name, option.value);
-            }
-            context.contextUriInfo.setSystemQueryOption(inlineCountOption);
           } else {
-            throw new UriParserSyntaxException("Unknown system query option!",
-                UriParserSyntaxException.MessageKeys.UNKNOWN_SYSTEM_QUERY_OPTION, option.name);
+            CustomQueryOptionImpl customOption = new CustomQueryOptionImpl();
+            customOption.setName(option.name);
+            customOption.setText(option.value);
+            context.contextUriInfo.addCustomQueryOption(customOption);
           }
         }
       }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/49387917/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSyntaxException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSyntaxException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSyntaxException.java
index 454ed3b..e5e1955 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSyntaxException.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParserSyntaxException.java
@@ -25,6 +25,7 @@ public class UriParserSyntaxException extends UriParserException {
 
   public static enum MessageKeys implements MessageKey {
     /** parameter: query-option name */ UNKNOWN_SYSTEM_QUERY_OPTION,
+    /** parameter: query-option name */ DOUBLE_SYSTEM_QUERY_OPTION,
     /** parameters: query-option name, query-option value */ WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION,
     SYNTAX,
     SYSTEM_QUERY_OPTION_LEVELS_NOT_ALLOWED_HERE, 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/49387917/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
index 57e805c..d9fa6f7 100644
--- a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
+++ b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
@@ -25,6 +25,7 @@ ODataHandlerException.FUNCTIONALITY_NOT_IMPLEMENTED=The requested functionality
 ODataHandlerException.ODATA_VERSION_NOT_SUPPORTED=OData version '%1$s' is not supported.
 
 UriParserSyntaxException.UNKNOWN_SYSTEM_QUERY_OPTION=The system query option '%1$s' is not defined.
+UriParserSyntaxException.DOUBLE_SYSTEM_QUERY_OPTION=The system query option '%1$s' can be specified only once.
 UriParserSyntaxException.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION=The system query option '%1$s' has the not-allowed value '%2$s'.
 UriParserSyntaxException.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION_FORMAT=The system query option '$format' must be either 'json', 'xml', 'atom', or a valid content type; the value '%1$s' is neither.
 UriParserSyntaxException.SYNTAX=The URI is malformed.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/49387917/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
index 91b58c0..d4e8ebd 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/UriInfoImplTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.olingo.server.core.uri;
 
+import org.apache.olingo.commons.api.ODataRuntimeException;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.server.api.uri.UriInfoAll;
@@ -122,6 +123,13 @@ public class UriInfoImplTest {
     assertEquals(entitySet1, uriInfo.getLastResourcePart());
   }
 
+  @Test(expected = ODataRuntimeException.class)
+  public void doubleSystemQueryOptions() {
+    new UriInfoImpl()
+        .setSystemQueryOption(new FormatOptionImpl())
+        .setSystemQueryOption(new FormatOptionImpl());
+  }
+
   @Test
   public void testCustomQueryOption() {
     UriInfoImpl uriInfo = new UriInfoImpl();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/49387917/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestUriParserImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestUriParserImpl.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestUriParserImpl.java
index c1eae93..d1fa59e 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestUriParserImpl.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestUriParserImpl.java
@@ -30,6 +30,7 @@ import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
 import org.apache.olingo.server.core.edm.provider.EdmProviderImpl;
 import org.apache.olingo.server.core.uri.parser.UriParserException;
 import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
+import org.apache.olingo.server.core.uri.parser.UriParserSyntaxException;
 import org.apache.olingo.server.core.uri.testutil.EdmTechTestProvider;
 import org.apache.olingo.server.core.uri.testutil.FilterValidator;
 import org.apache.olingo.server.core.uri.testutil.ResourceValidator;
@@ -240,7 +241,7 @@ public class TestUriParserImpl {
         .goFilter().is("<<PropertyInt16> eq <123>>");
   }
 
-  @Test(expected = UriValidationException.class)
+  @Test(expected = UriParserSyntaxException.class)
   public void testEntityFailOnValidation2() throws Exception {
     // simple entity set; with qualifiedentityTypeName; with 2xformat(before and after), expand, filter
     testUri.run("$entity/olingo.odata.test1.ETTwoPrim?"

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/49387917/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
index e3e0fc4..ee1378b 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/validator/UriValidatorTest.java
@@ -314,6 +314,11 @@ public class UriValidatorTest {
     parseAndValidate("ESAllPrim?$skip=foo", HttpMethod.GET);
   }
 
+  @Test(expected = UriParserSyntaxException.class)
+  public void validateDoubleSystemOptions() throws Exception {
+    parseAndValidate("ESAllPrim?$skip=1&$skip=2", HttpMethod.GET);
+  }
+
   @Test(expected = UriValidationException.class)
   public void validateKeyPredicatesWrongKey() throws Exception {
     String uri = "ESTwoKeyNav(xxx=1, yyy='abc')";