You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by sk...@apache.org on 2013/11/19 09:33:33 UTC

[2/2] git commit: [OLINGO-63] Uri Parser: complete lexer grammar and tests

[OLINGO-63] Uri Parser: complete lexer grammar and tests

Uri Parser: start cleanup parser grammar


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

Branch: refs/heads/master
Commit: 9aec30fd16ed6bb59dc2909bcc3b83a8fa475ded
Parents: eea0324
Author: Sven Kobler <sv...@sap.com>
Authored: Mon Nov 18 14:28:15 2013 +0100
Committer: Stephan Klevenz <st...@sap.com>
Committed: Tue Nov 19 09:31:53 2013 +0100

----------------------------------------------------------------------
 .../apache/olingo/producer/api/uri/UriInfo.java |  56 +++
 .../apache/olingo/producer/api/uri/UriType.java |  84 +++++
 .../olingo/producer/core/uri/antlr/.gitignore   |   1 +
 .../olingo/producer/core/uri/antlr/Uri.g4       | 372 ++++++++++--------
 .../producer/core/uri/antlr/UriLexerPart.g4     | 359 ++++++++++--------
 .../olingo/producer/core/uri/UriInfo.java       |  54 ---
 .../olingo/producer/core/uri/UriInfoImpl.java   |   1 +
 .../olingo/producer/core/uri/UriParserImpl.java |  95 +++++
 .../olingo/producer/core/uri/UriTreeReader.java | 105 ------
 .../producer/core/uri/UriTreeVisitor.java       |   6 +-
 .../olingo/producer/core/uri/UriType.java       |  83 ----
 .../producer/core/testutil/EdmTechProvider.java | 218 +++++++++++
 .../producer/core/testutil/TokenValidator.java  | 167 ++++++++
 .../core/testutil/UriResourcePathValidator.java |  83 ++++
 .../producer/core/uri/antlr/TestLexer.java      | 378 +++++++++++++++++++
 .../core/uri/antlr/UriTreeReaderTest.java       |  75 ++--
 pom.xml                                         |   3 +-
 17 files changed, 1534 insertions(+), 606 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-api/src/main/java/org/apache/olingo/producer/api/uri/UriInfo.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-api/src/main/java/org/apache/olingo/producer/api/uri/UriInfo.java b/odata4-lib/odata4-producer-api/src/main/java/org/apache/olingo/producer/api/uri/UriInfo.java
new file mode 100644
index 0000000..9ff3c50
--- /dev/null
+++ b/odata4-lib/odata4-producer-api/src/main/java/org/apache/olingo/producer/api/uri/UriInfo.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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.producer.api.uri;
+
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.olingo.commons.api.edm.EdmBindingTarget;
+
+
+public class UriInfo {
+  private UriType uriType;
+  private EdmBindingTarget bindingTarget;
+  private List<String> keyNames = Collections.emptyList();
+
+  public UriType getUriType() {
+    return uriType;
+  }
+
+  public void setUriType(final UriType uriType) {
+    this.uriType = uriType;
+  }
+
+  public EdmBindingTarget getBindingTarget() {
+    return bindingTarget;
+  }
+
+  public void setBindingTarget(final EdmBindingTarget bindingTarget) {
+    this.bindingTarget = bindingTarget;
+  }
+
+  public void setKeyNames(final List<String> keyNames) {
+    this.keyNames = keyNames;
+  }
+
+  public List<String> getKeyNames() {
+    return keyNames;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-api/src/main/java/org/apache/olingo/producer/api/uri/UriType.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-api/src/main/java/org/apache/olingo/producer/api/uri/UriType.java b/odata4-lib/odata4-producer-api/src/main/java/org/apache/olingo/producer/api/uri/UriType.java
new file mode 100644
index 0000000..11e1521
--- /dev/null
+++ b/odata4-lib/odata4-producer-api/src/main/java/org/apache/olingo/producer/api/uri/UriType.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * 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.producer.api.uri;
+
+
+public enum UriType {
+  TYPE_ENTITY_SET,
+  TYPE_ENTITY_SET_COUNT,
+  TYPE_MEDIA_REFERENCE,
+  TYPE_REFERENCE_COLLECTION,
+  /*
+   * Singleton
+   */
+  TYPE_ENTITY,
+  TYPE_MEDIA_STREAM,
+  TYPE_REFERENCE,
+
+  /*
+   * Property Path
+   */
+  TYPE_PROPERTY_PRIMITIVE,
+  TYPE_PROPERTY_PRIMITIVE_COLLECTION,
+  TYPE_PROPERTY_PRIMITIVE_VALUE,
+  TYPE_PROPERTY_COMPLEX,
+
+  /*
+   * Crossjoin
+   */
+  TYPE_CROSSJOIN,
+
+  /*
+   * $all
+   */
+  TYPE_SERVICE_ALL,
+  /*
+   * ActionImport
+   */
+  TYPE_AI_ENTITY,
+  /*
+   * FunctionImport
+   */
+  TYPE_FI_ENTITY,
+  TYPE_FI_ENTITY_SET,
+  TYPE_FI_ENTITY_SET_COUNT,
+  TYPE_FI_PROPERTY_PRIMITIVE,
+  TYPE_FI_PROPERTY_PRIMITIVE_COLL,
+  TYPE_FI_PROPERTY_PRIMITIVE_COLL_COUNT,
+  TYPE_FI_PROPERTY_COMPLEX,
+  TYPE_FI_PROPERTY_COMPLEX_COLL,
+  TYPE_FI_PROPERTY_COMPLEX_COLL_COUNT,
+  /*
+   * BoundFunction
+   */
+  TYPE_BF_ENTITY,
+  TYPE_BF_ENTITY_SET,
+  TYPE_BF_PROP_PRIM,
+  TYPE_BF_PROP_COMP,
+  TYPE_BF_PROP_COMP_COLL,
+  TYPE_BF_PROP_PRIM_COLL,
+  /*
+   * BoundAction
+   */
+  TYPE_BA_ENTITY_SET,
+  TYPE_BA_ENTITY,
+  TYPE_BA_PROP_PRIM,
+  TYPE_BA_PROP_PRIM_COLL,
+  TYPE_BA_PROP_COMP;
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/.gitignore
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/.gitignore b/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/.gitignore
new file mode 100644
index 0000000..e45d6e3
--- /dev/null
+++ b/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/.gitignore
@@ -0,0 +1 @@
+*.local
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/Uri.g4
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/Uri.g4 b/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/Uri.g4
index a659199..99091df 100644
--- a/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/Uri.g4
+++ b/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/Uri.g4
@@ -18,18 +18,12 @@
  ******************************************************************************/
  grammar Uri;
 //Naming convention 
-//- Helper Rules ending with "Path" like "colNavigationPath" are expected to be used behind a 
-//  slash ('/') e.g. "rule : entitySetName( '/' colNavigationPath)?;"
-//- Helper Rules ending with "OnQual" like "colNavigationPathOnQual" are expected to be used behind a 
-//  qualified identifiere.g. "colNavigationPath           : ...| qualified colNavigationPathOnQual;"
-//- Helper Rules ending with "OnCast" like "singleNavigationPathOnCast" are expected to be used behind a 
-//  cast to a typename e.g. "singleNavigationPathOnQual  : ... | entityTypeName '/' singleNavigationPathOnCast;"
+//  ...
 //Decoding encoding
 //- within rule "resourcePath": special chars used in EDM.Strings must still be encoded when 
 //  used as tokenizer input
-//  e.g. .../Employees(id='Hugo%2FMueller')/EmployeeName <-- '/' must be encodet to '%2F' in "Hugo/Mueller"
+//  e.g. .../Employees(id='Hugo%2FMueller')/EmployeeName <-- '/' must be encoded to '%2F' in "Hugo/Mueller"
 //    but it must not be encoded before the EmployeeName
-//- within rules "entityOptions"/"format"/"queryOptions": 
 
 options {
     language = Java;
@@ -37,8 +31,6 @@ options {
 
 import UriLexerPart; //contain Lexer rules
 
-
-
 //;------------------------------------------------------------------------------
 //; 0. URI
 //;------------------------------------------------------------------------------
@@ -51,76 +43,62 @@ import UriLexerPart; //contain Lexer rules
 //              "/" *( segment-nz "/" )
 
 
-
-odataRelativeUri    : ( '$batch'                                //; Note: case-sensitive!
-                        | '$entity' '?' entityOptions           //; Note: case-sensitive!
-                        | '$metadata' ( '?' format )? ( FRAGMENT contextFragment )?
-                        | resourcePath ( '?' queryOptions )?
-                      ) EOF;
-
-odataRelativeUriA   : odataRelativeUriB? EOF;
-odataRelativeUriB   : '$batch'  # batch                         //; Note: case-sensitive!
-                    | '$entity' '?' entityOptions # entityA     //; Note: case-sensitive!
-                    | '$metadata' ( '?' format )? ( FRAGMENT contextFragment )? # metadata
-                    | resourcePath ( '?' queryOptions )?  # resourcePathA
+odataRelativeUriEOF : odataRelativeUri? EOF;
+odataRelativeUri    : '$batch'                                                  # batchAlt
+                    | '$entity' '?' entityOptions                               # entityAlt
+                    | '$metadata' ( '?' format )? ( FRAGMENT contextFragment )? # metadataAlt
+                    | resourcePath ( '?' queryOptions )?                        # resourcePathAlt
                     ;
 
 //;------------------------------------------------------------------------------
 //; 1. Resource Path
 //;------------------------------------------------------------------------------
                    
-resourcePath        : '$all'  # all
-                    | crossjoin #crossjoinA
-                    | pathSegments #pathSegmentsA
+resourcePath        : '$all'        # allAlt
+                    | crossjoin     # crossjoinAlt
+                    | pathSegments  # pathSegmentsAlt
                     ;
-crossjoin           : '$crossjoin' OPEN odataIdentifier ( COMMA odataIdentifier )* CLOSE;
+crossjoin           : '$crossjoin' OPEN odi+=odataIdentifier ( COMMA odi+=odataIdentifier )* CLOSE;
 
-pathSegments        : pathSegment ('/' pathSegment)* constSegment?;
+pathSegments        : ps+=pathSegment ('/' ps+=pathSegment)* constSegment?;
 
 pathSegment         : ns=namespace* odi=odataIdentifier fp=functionParameters? kp=keypredicates?;
 
-pathOdataIdentifier : ODATAIDENTIFIER;
-
 functionParameters  : OPEN ( fps+=functionParameter ( COMMA fps+=functionParameter )* )? CLOSE;
 functionParameter   : odi=parameterName EQ ( ali=parameterAlias | val=primitiveLiteral );
 parameterName       : odataIdentifier;
 parameterAlias      : AT_ODATAIDENTIFIER;      
 
-keypredicates       : simpleKey | compoundKey;
+keypredicates       : sk=simpleKey | ck=compoundKey;
 simpleKey           : OPEN keyPropertyValue CLOSE;
 compoundKey         : OPEN kvp+=keyValuePair ( COMMA kvp+=keyValuePair )* CLOSE;
 keyValuePair        : odi=odataIdentifier EQ val=keyPropertyValue;
 keyPropertyValue    : primitiveLiteral;
 
                
-constSegment        : '/' (value | count | ref );
-count               : COUNT;
-ref                 : REF;
-value               : VALUE;
+constSegment        : '/' (v=VALUE | c=COUNT | r=REF );
 
 //;------------------------------------------------------------------------------
 //; 2. Query Options
 //;------------------------------------------------------------------------------
 
-queryOptions : queryOption ( '&' queryOption )*;
-queryOption  : systemQueryOption 
-             | aliasAndValue 
-             | customQueryOption  
-             ;
+queryOptions    : qo+=queryOption ( '&' qo+=queryOption )*;
+queryOption     : systemQueryOption 
+                | aliasAndValue 
+                | customQueryOption  
+                ;
              
-entityOptions : (entityOption '&' )* id ( '&' entityOption )*;
-entityOption  : expand 
-              | format
-              | select
-              | customQueryOption
-              ;
-
-id            : ID;
+entityOptions   : (eob+=entityOption '&' )* id=ID ( '&' eoa+=entityOption )*;
+entityOption    : expand 
+                | format
+                | select
+                | customQueryOption
+                ;
 
 systemQueryOption   : expand
                     | filter 
                     | format 
-                    | id
+                    | ID
                     | inlinecount 
                     | orderby 
                     | search
@@ -133,12 +111,12 @@ expand              : '$expand' EQ expandItemList;
 
 expandItemList      : expandItem ( COMMA expandItem )*;
 
-expandItem          : STAR ( '/' ref | OPEN LEVELS CLOSE )?
+expandItem          : STAR ( '/' REF | OPEN LEVELS CLOSE )?
                     | expandPath expandPathExtension?;
 
 expandPath          : ( namespace* odataIdentifier ) ( '/' namespace* odataIdentifier )*;
-expandPathExtension : '/' ref   ( OPEN expandRefOption   ( SEMI expandRefOption   )* CLOSE )?
-                    | '/' count ( OPEN expandCountOption ( SEMI expandCountOption )* CLOSE )?
+expandPathExtension : '/' REF   ( OPEN expandRefOption   ( SEMI expandRefOption   )* CLOSE )?
+                    | '/' COUNT ( OPEN expandCountOption ( SEMI expandCountOption )* CLOSE )?
                     |             OPEN expandOption      ( SEMI expandOption      )* CLOSE 
                     ;  
 expandCountOption   : filter
@@ -165,14 +143,13 @@ skip                : SKIP;
 top                 : TOP;
 format              : FORMAT;
 
-inlinecount         : '$count' EQ BOOLEAN;
+inlinecount         : '$count' EQ booleanNonCase;
 
-//search is not like the ABNF to support operator precedence
 search              : '$search' searchSpecialToken;
 
-searchSpecialToken  : { ((UriLexer) this.getInputStream().getTokenSource()).SetSWallowed(true); }
+searchSpecialToken  : { ((UriLexer) this.getInputStream().getTokenSource()).setInSearch(true); }
                       EQ WS* searchExpr
-                      { ((UriLexer) this.getInputStream().getTokenSource()).SetSWallowed(false); }
+                      { ((UriLexer) this.getInputStream().getTokenSource()).setInSearch(false); }
                     ;
 
 searchExpr          : 'NOT' WS+ searchExpr
@@ -191,11 +168,12 @@ selectItem          : namespace* '*'
                     ;
 
 aliasAndValue       : parameterAlias EQ parameterValue;
-parameterValue      : /*arrayOrObject*/
-                      commonExpr;
-customQueryOption   : { ((UriLexer) this.getInputStream().getTokenSource()).SetCUSTallowed(true); }
+parameterValue      : arrayOrObject
+                      commonExpr
+                    ;
+customQueryOption   : { ((UriLexer) this.getInputStream().getTokenSource()).setINCustomOption(true); }
                       customName ( EQ customValue)?
-                      { ((UriLexer) this.getInputStream().getTokenSource()).SetCUSTallowed(false); }
+                      { ((UriLexer) this.getInputStream().getTokenSource()).setINCustomOption(false); }
                     ;
 customName          : 'CUSTOMNAME';
 customValue         : 'CUSTOMVALUE';
@@ -209,26 +187,24 @@ contextFragment     : 'Collection($ref)'
                     | 'Collection(Edm.EntityType)'
                     | 'Collection(Edm.ComplexType)'
                     | PRIMITIVETYPENAME
-                    | 'collection' OPEN 
-                      ( PRIMITIVETYPENAME 
-                      | namespace odataIdentifier
-                      ) CLOSE
-                    | namespace* odataIdentifier ( '/$deletedEntity'
-                                      | '/$link'
-                                      | '/$deletedLink'
-                                      | keypredicates? ( '/' namespace* odataIdentifier)* ( propertyList )? ( '/$delta'  )? ( entity )?
-                                      )?
+                    | 'collection' OPEN ( PRIMITIVETYPENAME | namespace odataIdentifier ) CLOSE
+                    | namespace* odataIdentifier 
+                      ( '/$deletedEntity'
+                      | '/$link'
+                      | '/$deletedLink'
+                      | keypredicates? ( '/' namespace* odataIdentifier)* ( propertyList )? ( '/$delta'  )? ( entity )?
+                      )?
                     ;              
 
 propertyList         : OPEN propertyListItem ( COMMA propertyListItem )* CLOSE;
-propertyListItem     : STAR //; all structural properties
+propertyListItem     : STAR           //; all structural properties
                      | propertyListProperty
                      ;
 propertyListProperty : odataIdentifier ( '+' )? ( propertyList )?
                      | odataIdentifier ( '/' propertyListProperty )?
                      ;
                  
-entity                  : '/$entity';
+entity               : '/$entity';
 //;------------------------------------------------------------------------------
 //; 4. Expressions
 //;------------------------------------------------------------------------------
@@ -237,7 +213,7 @@ entity                  : '/$entity';
 // we had to introduced operator precesence witch is not reflected in the ABNF
 
 
-commonExpr          : OPEN commonExpr  CLOSE
+commonExpr          : OPEN commonExpr CLOSE
                     | methodCallExpr
                     | unary WS+ commonExpr
                     | memberExpr
@@ -258,122 +234,198 @@ rootExpr            : '$root/' pathSegments;
 
 memberExpr          : '$it' | '$it/'? pathSegments;
 
-anyExpr                 : 'any' OPEN WS* /* [ lambdaVariableExpr BWS COLON BWS lambdaPredicateExpr ] WS* */ CLOSE;
-allExpr                 : 'all' OPEN WS* /*   lambdaVariableExpr BWS COLON BWS lambdaPredicateExpr   WS* */ CLOSE;
-
-methodCallExpr          : indexOfMethodCallExpr 
-                        | toLowerMethodCallExpr 
-                        | toUpperMethodCallExpr  
-                        | trimMethodCallExpr 
-                        | substringMethodCallExpr 
-                        | concatMethodCallExpr 
-                        | lengthMethodCallExpr 
-                        | yearMethodCallExpr 
-                        | monthMethodCallExpr 
-                        | dayMethodCallExpr 
-                        | hourMethodCallExpr 
-                        | minuteMethodCallExpr 
-                        | secondMethodCallExpr 
-                        | fractionalsecondsMethodCallExpr
-                        | totalsecondsMethodCallExpr
-                        | dateMethodCallExpr 
-                        | timeMethodCallExpr 
-                        | roundMethodCallExpr 
-                        | floorMethodCallExpr 
-                        | ceilingMethodCallExpr 
-                        | distanceMethodCallExpr 
-                        | geoLengthMethodCallExpr 
-                        | totalOffsetMinutesMethodCallExpr
-                        | minDateTimeMethodCallExpr
-                        | maxDateTimeMethodCallExpr
-                        | nowMethodCallExpr
-                        //from boolean
-                        | isofExpr
-                        | castExpr 
-                        | endsWithMethodCallExpr  
-                        | startsWithMethodCallExpr
-                        | containsMethodCallExpr
-                        | intersectsMethodCallExpr
+anyExpr             : 'any' OPEN WS* /* [ lambdaVariableExpr BWS COLON BWS lambdaPredicateExpr ] WS* */ CLOSE;
+allExpr             : 'all' OPEN WS* /*   lambdaVariableExpr BWS COLON BWS lambdaPredicateExpr   WS* */ CLOSE;
+
+methodCallExpr      : indexOfMethodCallExpr
+                    | toLowerMethodCallExpr
+                    | toUpperMethodCallExpr
+                    | trimMethodCallExpr
+                    | substringMethodCallExpr
+                    | concatMethodCallExpr
+                    | lengthMethodCallExpr
+                    | yearMethodCallExpr
+                    | monthMethodCallExpr
+                    | dayMethodCallExpr
+                    | hourMethodCallExpr
+                    | minuteMethodCallExpr
+                    | secondMethodCallExpr
+                    | fractionalsecondsMethodCallExpr
+                    | totalsecondsMethodCallExpr
+                    | dateMethodCallExpr
+                    | timeMethodCallExpr
+                    | roundMethodCallExpr
+                    | floorMethodCallExpr
+                    | ceilingMethodCallExpr
+                    | distanceMethodCallExpr
+                    | geoLengthMethodCallExpr
+                    | totalOffsetMinutesMethodCallExpr
+                    | minDateTimeMethodCallExpr
+                    | maxDateTimeMethodCallExpr
+                    | nowMethodCallExpr
+                    //from boolean
+                    | isofExpr
+                    | castExpr
+                    | endsWithMethodCallExpr
+                    | startsWithMethodCallExpr
+                    | containsMethodCallExpr
+                    | intersectsMethodCallExpr
+                    ;
+
+
+containsMethodCallExpr    : CONTAINS   OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
+startsWithMethodCallExpr  : STARTSWITH OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
+endsWithMethodCallExpr    : ENDSWITH   OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
+lengthMethodCallExpr      : LENGTH     OPEN WS* commonExpr WS* CLOSE;
+indexOfMethodCallExpr     : INDEXOF    OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
+substringMethodCallExpr   : SUBSTRING  OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* ( COMMA WS* commonExpr WS* ) CLOSE;
+toLowerMethodCallExpr     : TOLOWER    OPEN WS* commonExpr WS* CLOSE;
+toUpperMethodCallExpr     : TOUPPER    OPEN WS* commonExpr WS* CLOSE;
+trimMethodCallExpr        : TRIM       OPEN WS* commonExpr WS* CLOSE;
+concatMethodCallExpr      : CONCAT     OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
+
+yearMethodCallExpr                : 'year'               OPEN WS* commonExpr WS* CLOSE;
+monthMethodCallExpr               : 'month'              OPEN WS* commonExpr WS* CLOSE;
+dayMethodCallExpr                 : 'day'                OPEN WS* commonExpr WS* CLOSE;
+hourMethodCallExpr                : 'hour'               OPEN WS* commonExpr WS* CLOSE;
+minuteMethodCallExpr              : 'minute'             OPEN WS* commonExpr WS* CLOSE;
+secondMethodCallExpr              : 'second'             OPEN WS* commonExpr WS* CLOSE;
+fractionalsecondsMethodCallExpr   : 'fractionalseconds'  OPEN WS* commonExpr WS* CLOSE;
+totalsecondsMethodCallExpr        : 'totalseconds'       OPEN WS* commonExpr WS* CLOSE;
+dateMethodCallExpr                : 'date'               OPEN WS* commonExpr WS* CLOSE;
+timeMethodCallExpr                : 'time'               OPEN WS* commonExpr WS* CLOSE;
+totalOffsetMinutesMethodCallExpr  : 'totaloffsetminutes' OPEN WS* commonExpr WS* CLOSE;
+
+minDateTimeMethodCallExpr         : 'mindatetime' OPEN WS* CLOSE;
+maxDateTimeMethodCallExpr         : 'maxdatetime' OPEN WS* CLOSE;
+nowMethodCallExpr                 : 'now' OPEN WS* CLOSE;
+
+roundMethodCallExpr               : 'round'   OPEN WS* commonExpr WS* CLOSE;
+floorMethodCallExpr               : 'floor'   OPEN WS* commonExpr WS* CLOSE;
+ceilingMethodCallExpr             : 'ceiling' OPEN WS* commonExpr WS* CLOSE;
+
+distanceMethodCallExpr            : 'geo.distance'   OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
+geoLengthMethodCallExpr           : 'geo.length'     OPEN WS* commonExpr WS* CLOSE;
+intersectsMethodCallExpr          : 'geo.intersects' OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
+
+isofExpr                          : 'isof' OPEN  WS*  commonExpr WS* COMMA WS*  qualifiedtypename WS* CLOSE;
+castExpr                          : 'cast' OPEN WS*  ( commonExpr WS* COMMA WS* ) qualifiedtypename WS* CLOSE;
+
+//;------------------------------------------------------------------------------
+//; 5. JSON format for function parameters
+//;------------------------------------------------------------------------------
+//; Note: the query part of a URI needs to be partially percent-decoded before
+//; applying these rules, see comment at the top of this file
+//;------------------------------------------------------------------------------
+
+arrayOrObject       : complexColInUri  
+                    | complexInUri
+                    | rootExprCol
+                    | primitiveColInUri;
+               
+complexColInUri     : BEGIN_ARRAY 
+                      ( complexInUri ( VALUE_SEPARATOR complexInUri )* )?
+                      END_ARRAY;
+                  
+complexInUri        : BEGIN_OBJECT ( jv+=json_value ( VALUE_SEPARATOR jv+=json_value)* )? END_OBJECT;
+
+json_value          : annotationInUri 
+                    | primitivePropertyInUri 
+                    | complexPropertyInUri 
+                    | collectionPropertyInUri  
+                    | navigationPropertyInUri
+                    ;
+
+collectionPropertyInUri : QUOTATION_MARK ODATAIDENTIFIER QUOTATION_MARK
+                          NAME_SEPARATOR 
+                          ( primitiveColInUri | complexColInUri )
+                        ;
+
+primitiveColInUri       : BEGIN_ARRAY ( plj+=primitiveLiteralInJSON *( VALUE_SEPARATOR plj+=primitiveLiteralInJSON )  )? END_ARRAY
+                        ;
+                    
+complexPropertyInUri    : QUOTATION_MARK ODATAIDENTIFIER QUOTATION_MARK 
+                          NAME_SEPARATOR 
+                           complexInUri
                         ;
 
+annotationInUri         : QUOTATION_MARK ns=namespace* odi=odataIdentifier QUOTATION_MARK
+                          NAME_SEPARATOR
+                          ( complexInUri | complexColInUri | primitiveLiteralInJSON | primitiveColInUri );
+
+primitivePropertyInUri  : QUOTATION_MARK ODATAIDENTIFIER QUOTATION_MARK 
+                          NAME_SEPARATOR 
+                          primitiveLiteralInJSON;
+
+
+navigationPropertyInUri : QUOTATION_MARK ODATAIDENTIFIER QUOTATION_MARK
+                          NAME_SEPARATOR ( rootExpr | rootExprCol )
+                        ;
+
+rootExprCol   : BEGIN_ARRAY 
+                ( rootExpr *( VALUE_SEPARATOR rootExpr ) )?
+                END_ARRAY
+              ;
+                                        
+//; JSON syntax: adapted to URI restrictions from [RFC4627]                 
+BEGIN_OBJECT    : WS* ( '{' / '%7B' ) WS*;
+END_OBJECT      : WS* ( '}' / '%7D' ) WS*;
+
+BEGIN_ARRAY     : WS* ( '[' / '%5B' ) WS*;
+END_ARRAY       : WS* ( ']' / '%5D' ) WS*;
+
+NAME_SEPARATOR  : WS* COLON WS*;
+VALUE_SEPARATOR : WS* COMMA WS*;
+
+primitiveLiteralInJSON  : STRING_IN_JSON
+                        | number_in_json
+                        | TRUE
+                        | FALSE
+                        | 'null'
+                        ;
+
+number_in_json          : INT | DECIMAL;
 
-containsMethodCallExpr   : 'contains'   OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
-startsWithMethodCallExpr : 'startswith' OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
-endsWithMethodCallExpr   : 'endswith'   OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
-lengthMethodCallExpr     : 'length'     OPEN WS* commonExpr WS* CLOSE;
-indexOfMethodCallExpr    : 'indexof'    OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
-substringMethodCallExpr  : 'substring'  OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* ( COMMA WS* commonExpr WS* ) CLOSE;
-toLowerMethodCallExpr    : 'tolower'    OPEN WS* commonExpr WS* CLOSE;
-toUpperMethodCallExpr    : 'toupper'    OPEN WS* commonExpr WS* CLOSE;
-trimMethodCallExpr       : 'trim'       OPEN WS* commonExpr WS* CLOSE;
-concatMethodCallExpr     : 'concat'     OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
-
-yearMethodCallExpr               : 'year'               OPEN WS* commonExpr WS* CLOSE;
-monthMethodCallExpr              : 'month'              OPEN WS* commonExpr WS* CLOSE;
-dayMethodCallExpr                : 'day'                OPEN WS* commonExpr WS* CLOSE;
-hourMethodCallExpr               : 'hour'               OPEN WS* commonExpr WS* CLOSE;
-minuteMethodCallExpr             : 'minute'             OPEN WS* commonExpr WS* CLOSE;
-secondMethodCallExpr             : 'second'             OPEN WS* commonExpr WS* CLOSE;
-fractionalsecondsMethodCallExpr  : 'fractionalseconds'  OPEN WS* commonExpr WS* CLOSE;
-totalsecondsMethodCallExpr       : 'totalseconds'       OPEN WS* commonExpr WS* CLOSE;
-dateMethodCallExpr               : 'date'               OPEN WS* commonExpr WS* CLOSE;
-timeMethodCallExpr               : 'time'               OPEN WS* commonExpr WS* CLOSE;
-totalOffsetMinutesMethodCallExpr : 'totaloffsetminutes' OPEN WS* commonExpr WS* CLOSE;
-
-minDateTimeMethodCallExpr : 'mindatetime' OPEN WS* CLOSE;
-maxDateTimeMethodCallExpr : 'maxdatetime' OPEN WS* CLOSE;
-nowMethodCallExpr         : 'now' OPEN WS* CLOSE;
-
-roundMethodCallExpr   : 'round'   OPEN WS* commonExpr WS* CLOSE;
-floorMethodCallExpr   : 'floor'   OPEN WS* commonExpr WS* CLOSE;
-ceilingMethodCallExpr : 'ceiling' OPEN WS* commonExpr WS* CLOSE;
-
-distanceMethodCallExpr   : 'geo.distance'   OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
-geoLengthMethodCallExpr  : 'geo.length'     OPEN WS* commonExpr WS* CLOSE;
-intersectsMethodCallExpr : 'geo.intersects' OPEN WS* commonExpr WS* COMMA WS* commonExpr WS* CLOSE;
-
-isofExpr            : 'isof' OPEN  WS*  commonExpr WS* COMMA WS*  qualifiedtypename WS* CLOSE;
-castExpr            : 'cast' OPEN WS*  ( commonExpr WS* COMMA WS* ) qualifiedtypename WS* CLOSE;
 //;------------------------------------------------------------------------------
 //; 6. Names and identifiers
 //;------------------------------------------------------------------------------
-POINT : '.';
+POINT                   : '.';
 
 qualifiedtypename       : PRIMITIVETYPENAME
                         | namespace odataIdentifier
-                        | 'collection' OPEN 
-                          ( PRIMITIVETYPENAME 
-                            | namespace odataIdentifier
-                          ) CLOSE
+                        | 'collection' OPEN ( PRIMITIVETYPENAME | namespace odataIdentifier ) CLOSE
                         ;
 
 namespace               : (odataIdentifier POINT)+;
 
-odataIdentifier     : ODATAIDENTIFIER;
+odataIdentifier         : ODATAIDENTIFIER;
+
 //;------------------------------------------------------------------------------
 //; 7. Literal Data Values
 //;------------------------------------------------------------------------------
 
+
 /*TODO add missing values*/
 primitiveLiteral    : nullrule
-                    | BOOLEAN 
-                    | DECIMAL  
-                    | INT  
+                    | booleanNonCase
+                    | DECIMAL   //includes double and single literals
+                    | INT       //includes int16/int32 and int64 literals
                     | BINARY  
                     | DATE
                     | DATETIMEOFFSET
-                    //|duration
+                    | DURATION
                     | string
                     | TIMEOFDAY
-                    // enum
+                    | enumX
                     | parameterAlias
                     ;
 
 
 nullrule            : NULLVALUE;// (SQUOTE qualifiedtypename SQUOTE)?;
+booleanNonCase      : BOOLEAN | TRUE | FALSE;
 string              : STRING;
-/*TODO
-enum                : qualifiedEnumTypeName SQUOTE enumValue SQUOTE
-enumValue           : singleEnumValue *( COMMA singleEnumValue )
-singleEnumValue     : enumerationMember / int64Value
-*/
+
+
+enumX               : namespace* ODATAIDENTIFIER SQUOTE enumValue SQUOTE;
+enumValue           : singleEnumValue *( COMMA singleEnumValue );
+singleEnumValue     : ODATAIDENTIFIER / INT;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/UriLexerPart.g4
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/UriLexerPart.g4 b/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/UriLexerPart.g4
index 5cd7a4e..76a1b59 100644
--- a/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/UriLexerPart.g4
+++ b/odata4-lib/odata4-producer-core/src/main/antlr4/org/apache/olingo/producer/core/uri/antlr/UriLexerPart.g4
@@ -24,173 +24,212 @@
     private void out(String out) { if(debug) { System.out.println(out); } };
     
     
-    boolean SWallowed = false;
-    public boolean IsSWallowed() { out("?SW?="+SWallowed); return SWallowed; };
-    public void SetSWallowed(boolean value) { SWallowed=value; out("SW=set to "+ SWallowed); };
-    
-    boolean CUSTallowed = false;
-    public boolean IsCUSTallowed() { out("?CUST?="+CUSTallowed); return CUSTallowed; };
-    public void SetCUSTallowed(boolean value) { SWallowed=value; out("CUST=set to "+ CUSTallowed); };
+    boolean        bInSearch = false;
+    public boolean inSearch() { /*out("?SW?="+bInSearch);*/ return bInSearch; };
+    public void    setInSearch(boolean value) { bInSearch=value; /*out("SW=set to "+ bInSearch);*/ };
+
+    //testing
+    boolean        bInCustomOption = false;
+    public boolean inCustomOption() { /*out("?CUST?="+bInCustomOption);*/ return bInCustomOption; };
+    public void    setINCustomOption(boolean value) { bInCustomOption=value; /*out("CUST=set to "+ bInCustomOption);*/ };
+
     
 //<-- custom lexer members
 }
 
+
 //;------------------------------------------------------------------------------
 //; 0. URI
 //;------------------------------------------------------------------------------
 
-FRAGMENT:'#';
+FRAGMENT    : '#';
+
+COUNT       : '$count';
+REF         : '$ref';
+VALUE       : '$value';
 
-COUNT   : '$count';
-REF     : '$ref';
-VALUE   : '$value';
 
 //;------------------------------------------------------------------------------
 //; 2. Query Options
 //;------------------------------------------------------------------------------
 
+SKIP        : '$skip' EQ DIGIT+;
+TOP         : '$top'  EQ DIGIT+;
 
-SKIP                : '$skip' EQ DIGIT+;
-TOP                 : '$top'  EQ DIGIT+;
+LEVELS      : '$levels' EQ ( DIGIT+ | 'max' );
 
-LEVELS              : '$levels' EQ ( DIGIT+ | 'max' );
+FORMAT      : '$format' EQ
+               ( 'atom'
+               | 'json'
+               | 'xml'
+               | PCHAR+ '/' PCHAR+ //; <a data service specific value indicating a
+            );                     //; format specific to the specific data service> or
+                                   //; <An IANA-defined [IANA-MMT] content type>
 
-FORMAT              : '$format' EQ
-                    ( 'atom'
-                      | 'json'
-                      | 'xml'
-                      | PCHAR+ '/' PCHAR+ //; <a data service specific value indicating a
-                    );                       //; format specific to the specific data service> or
-                                            //; <An IANA-defined [IANA-MMT] content type>
-ID                  : '$id' EQ QCHAR_NO_AMP+;
+ID          : '$id' EQ QCHAR_NO_AMP+;
 
-SKIPTOKEN           : '$skiptoken' EQ QCHAR_NO_AMP+;
+SKIPTOKEN   : '$skiptoken' EQ QCHAR_NO_AMP+;
 
 
 //;------------------------------------------------------------------------------
 //; 4. Expressions
 //;------------------------------------------------------------------------------
 
+IMPLICIT_VARIABLE_EXPR  : '$it';
 
-ImplicitVariableExpr    : '$it';
+CONTAINS                : 'contains';
+STARTSWITH              : 'startswith';
+ENDSWITH                : 'endswith';
+LENGTH                  : 'length';
+INDEXOF                 : 'indexof';
+SUBSTRING               : 'substring';
+TOLOWER                 : 'tolower';
+TOUPPER                 : 'toupper';
+TRIM                    : 'trim';
+CONCAT                  : 'concat';
 
-INDEXOF: 'indexof';
 
 //;------------------------------------------------------------------------------
 //; 5. JSON format for function parameters
 //;------------------------------------------------------------------------------
-//; Note: the query part of a URI needs to be partially percent-decoded before
-//; applying these rules, see comment at the top of this file
-//;------------------------------------------------------------------------------
 
-SEARCHPHRASE        : QUOTATION_MARK QCHAR_NO_AMP_DQUOTE+ QUOTATION_MARK;
+QUOTATION_MARK                : DQUOTE | '%22';
 
+fragment CHAR_IN_JSON         : QCHAR_UNESCAPED  
+                              | QCHAR_JSON_SPECIAL
+                              | ESCAPE 
+                              ( QUOTATION_MARK 
+                                | ESCAPE
+                                | ( '/' | '%2F' ) //; solidus         U+002F
+                                | 'b'             //; backspace       U+0008                
+                                | 'f'             //; form feed       U+000C
+                                | 'n'             //; line feed       U+000A
+                                | 'r'             //; carriage return U+000D
+                                | 't'             //; tab             U+0009
+                                | 'u' HEXDIG HEXDIG HEXDIG HEXDIG //;                 U+XXXX
+                              );
 
-fragment QUOTATION_MARK  : DQUOTE | '%22';
+fragment  QCHAR_JSON_SPECIAL  : SP | ':' | '{' | '}' | '[' | ']'; //; some agents put these unencoded into the query part of a URL
+
+fragment  ESCAPE              : '\\' | '%5C'; //; reverse solidus U+005C
 
-fragment ESCAPE : '\\' | '%5C' ;    //     ; reverse solidus U+005C
 //;------------------------------------------------------------------------------
 //; 6. Names and identifiers
 //;------------------------------------------------------------------------------
 
-fragment IDENTIFIERLEADINGCHARACTER  : ALPHA | '_';         //TODO; plus Unicode characters from the categories L or Nl
-fragment IDENTIFIERCHARACTER         : ALPHA | '_' | DIGIT; //TODO; plus Unicode characters from the categories L, Nl, Nd, Mn, Mc, Pc, or Cf
-
-
-PRIMITIVETYPENAME           : ('Edm.')? ( 'Binary'
-
-                                        | 'Boolean'
-                                        | 'Byte'
-                                        | 'Date' 
-                                        | 'DateTimeOffset'
-                                        | 'Decimal'
-                                        | 'Double'
-                                        | 'Duration' 
-                                        | 'Guid' 
-                                        | 'Int16'
-                                        | 'Int32'
-                                        | 'Int64'
-                                        | 'SByte'
-                                        | 'Single'
-                                        | 'Stream'
-                                        | 'String'
-                                        | 'TimeOfDay'
-                                        | ABSTRACTSPATIALTYPENAME ( CONCRETESPATIALTYPENAME )?
-                                )
-                            ;
-
-ABSTRACTSPATIALTYPENAME : 'Geography'
-                        | 'Geometry';
-CONCRETESPATIALTYPENAME : 'Collection'
-                        | 'LineString'
-                        | 'MultiLineString'
-                        | 'MultiPoint'
-                        | 'MultiPolygon'
-                        | 'Point'
-                        | 'Polygon';
+fragment ODI_LEADINGCHARACTER : ALPHA | '_';         //TODO; plus Unicode characters from the categories L or Nl
+fragment ODI_CHARACTER        : ALPHA | '_' | DIGIT; //TODO; plus Unicode characters from the categories L, Nl, Nd, Mn, Mc, Pc, or Cf
+
+
+PRIMITIVETYPENAME             : ('Edm.')? 
+                                ( 'Binary'
+                                  | 'Boolean'
+                                  | 'Byte'
+                                  | 'Date' 
+                                  | 'DateTimeOffset'
+                                  | 'Decimal'
+                                  | 'Double'
+                                  | 'Duration' 
+                                  | 'Guid' 
+                                  | 'Int16'
+                                  | 'Int32'
+                                  | 'Int64'
+                                  | 'SByte'
+                                  | 'Single'
+                                  | 'Stream'
+                                  | 'String'
+                                  | 'TimeOfDay'
+                                  | ABSTRACTSPATIALTYPENAME ( CONCRETESPATIALTYPENAME )?
+                                );
+
+fragment ABSTRACTSPATIALTYPENAME  : 'Geography'
+                                  | 'Geometry'
+                                  ;
+
+fragment CONCRETESPATIALTYPENAME  : 'Collection'
+                                  | 'LineString'
+                                  | 'MultiLineString'
+                                  | 'MultiPoint'
+                                  | 'MultiPolygon'
+                                  | 'Point'
+                                  | 'Polygon'
+                                  ;
 
 //;------------------------------------------------------------------------------
 //; 7. Literal Data Values
 //;------------------------------------------------------------------------------
 
-NULLVALUE  : 'null';
-fragment SQUOTEinSTRING : SQUOTE SQUOTE ;
-
-BINARY              : ('X'| B I N A R Y) SQUOTE BINARYVALUE SQUOTE;
-fragment BINARYVALUE: (HEXDIG HEXDIG)*;
-
-BOOLEAN             : T R U E 
-                    | F A L S E
-                    ;
-//DIGITS :DIGIT+;
-
-DECIMAL : SIGN? DIGIT+ '.' DIGIT+; // decimal = [SIGN] 1*DIGIT ["." 1*DIGIT] der 2. optionale Teil erschwert der Unterschied zwischen INT und DECIMAL -> nicht optional
+NULLVALUE                 : 'null';
+fragment SQUOTEinSTRING   : SQUOTE SQUOTE ;
 
-INT     : SIGN? DIGIT+;// { !IsIRIallowed() }?;
+BINARY                    : ('X'| B I N A R Y) SQUOTE (HEXDIG HEXDIG)* SQUOTE;
 
+TRUE                      : 'true';
+FALSE                     : 'false';
+BOOLEAN                   :  T R U E 
+                          |  F A L S E 
+                          ; 
 
+fragment DIGITS           : DIGIT+;
 
+INT                       : SIGN? DIGITS;
+DECIMAL                   : INT '.' DIGITS ('e' SIGN?  DIGITS)?;
 
+NANINFINITY               : 'NaN' | '-INF' | 'INF';
 
 // --------------------- DATE ---------------------
-DATE                : DATETOKEN SQUOTE DATEVALUE SQUOTE;
-fragment DATETOKEN  : D A T E;
-fragment DATEVALUE  : YEAR '-' MONTH '-' DAY;
-                    
+DATE                     : DATETOKEN SQUOTE DATETOKEN_VALUE SQUOTE;
+fragment DATETOKEN       : D A T E;
+fragment DATETOKEN_VALUE : YEAR '-' MONTH '-' DAY;
 
 // --------------------- DATETIMEOFFSET ---------------------
-DATETIMEOFFSET      : DATEOSTOKEN SQUOTE DATETIMEOFFSETVALUE SQUOTE;
-fragment DATEOSTOKEN: D A T E T I M E O F F S E T;  
+DATETIMEOFFSET                : DATEOFFSETTOKEN SQUOTE DATETIMEOFFSET_VALUE SQUOTE;
+fragment DATEOFFSETTOKEN      : D A T E T I M E O F F S E T;  
+fragment DATETIMEOFFSET_VALUE : YEAR '-' MONTH '-' DAY T HOUR ':' MINUTE ( ':' SECOND ( '.' FRACTIONALSECONDS )? )? ( Z | SIGN HOUR ':' MINUTE );
+
+// --------------------- DURATION ---------------------
+DURATION                      : DURATIONTOKEN SQUOTE DURATIONVALUE SQUOTE;
+fragment DURATIONTOKEN        : D U R A T I O N;
+
+fragment DUDAYFRAG            : DIGITS 'D';
+fragment DUHOURFRAG           : DIGITS 'H';
+fragment DUMINUTEFRAG         : DIGITS 'M';
+fragment DUSECONDFRAG         : DIGITS ('.' DIGITS)? 'S';
+fragment DUTIMEFRAG           : 'T' ( 
+                                      ( DUHOURFRAG DUMINUTEFRAG? DUSECONDFRAG?) 
+                                      | (DUMINUTEFRAG DUSECONDFRAG?) 
+                                      | DUSECONDFRAG
+                                    );
+fragment DUDAYTIMEFRAG        : DUDAYFRAG DUTIMEFRAG? | DUTIMEFRAG;
                     
-fragment DATETIMEOFFSETVALUE
-                    :  YEAR '-' MONTH '-' DAY T HOUR ':' MINUTE ( ':' SECOND ( '.' FRACTIONALSECONDS )? )? ( Z | SIGN HOUR ':' MINUTE )
-                    ;
+fragment DURATIONVALUE        : '-'? 'P' DUDAYTIMEFRAG;
+
 // --------------------- TIMEOFDAY ---------------------
-TIMEOFDAY           : TIMEOFDAYTO SQUOTE TIMEOFDAYVALUE SQUOTE;
-fragment TIMEOFDAYTO: T I M E O F D A Y;  
-fragment TIMEOFDAYVALUE	: HOUR ':' MINUTE ( ':' SECOND ( '.' FRACTIONALSECONDS )? )?;
+TIMEOFDAY                     : TIMEOFDAYTO SQUOTE TIMEOFDAYVALUE SQUOTE;
+fragment TIMEOFDAYTO          : T I M E O F D A Y;  
+fragment TIMEOFDAYVALUE       : HOUR ':' MINUTE ( ':' SECOND ( '.' FRACTIONALSECONDS )? )?;
 
 // --------------------- date helper ---------------------
 
-fragment ONEtoNINE  : '1'..'9';                   
+fragment ONEtoNINE          : '1'..'9';                   
 
-fragment YEAR       : ('-')? ( '0' DIGIT DIGIT DIGIT | ONEtoNINE DIGIT DIGIT DIGIT );
+fragment YEAR               : ('-')? ( '0' DIGIT DIGIT DIGIT | ONEtoNINE DIGIT DIGIT DIGIT );
 
-fragment MONTH      : '0' ONEtoNINE
-                    | '1' ( '0' | '1' | '2' )
-                    ;
+fragment MONTH              : '0' ONEtoNINE
+                            | '1' ( '0' | '1' | '2' )
+                            ;
 
-fragment DAY        : '0' ONEtoNINE
-                    | ('1'|'2') DIGIT
-                    | '3' ('0'|'1')
-                    ;
+fragment DAY                : '0' ONEtoNINE
+                            | ('1'|'2') DIGIT
+                            | '3' ('0'|'1')
+                            ;
 
-fragment HOUR       : ('0' | '1') DIGIT
-                    | '2' ( '1'..'3')
-                    ;
+fragment HOUR               : ('0' | '1') DIGIT
+                            | '2' ( '0'..'3')
+                            ;
 
-fragment MINUTE     : ZEROtoFIFTYNINE;
-fragment SECOND     : ZEROtoFIFTYNINE;
+fragment MINUTE             : ZEROtoFIFTYNINE;
+fragment SECOND             : ZEROtoFIFTYNINE;
 fragment FRACTIONALSECONDS  : DIGIT+;
 fragment ZEROtoFIFTYNINE    : ('0'..'5') DIGIT;
 
@@ -199,57 +238,52 @@ fragment ZEROtoFIFTYNINE    : ('0'..'5') DIGIT;
 //; 9. Punctuation
 //;------------------------------------------------------------------------------
 
-WS : ( SP | HTAB | '%20' | '%09' );  //; "required" whitespace 
-//fragment OWS : WS*;
-//rws : WS+;
-
-
-AT 	: '@' | '%40';
+WS        : ( SP | HTAB | '%20' | '%09' );
 
-COMMA  	: ',' | '%2C';
-EQ     	:	 '=';
-SIGN    : '+' | '%2B' |'-';
-SEMI    : ';' | '%3B';
-STAR    : '*';
-SQUOTE  : '\'' | '%27';
-OPEN    : '(' | '%28';
-CLOSE   : ')' | '%29';
+AT        : '@' | '%40';
+COLON     : ':' | '%3A';
+COMMA     : ',' | '%2C';
+EQ        :  '=';
+SIGN      : '+' | '%2B' |'-';
+SEMI      : ';' | '%3B';
+STAR      : '*';
+SQUOTE    : '\'' | '%27';
+OPEN      : '(' | '%28';
+CLOSE     : ')' | '%29';
 
 
 //;------------------------------------------------------------------------------
 //; A. URI syntax [RFC3986]
 //;------------------------------------------------------------------------------
 
-QM                               : '?' -> channel(HIDDEN);
+QM                          :  '?' -> channel(HIDDEN);
 
-fragment PCHAR                   : UNRESERVED | PCT_ENCODED | SUB_DELIMS | ':' | '@';
+fragment PCHAR              : UNRESERVED | PCT_ENCODED | SUB_DELIMS | ':' | '@'; 
 
-fragment PCHARnoSQUOTE           : UNRESERVED| PCTENCODEDnoSQUOTE |  OTHERDELIMS | '$' | '&' | EQ | ':' | '@';
+fragment PCHARnoSQUOTE      : UNRESERVED| PCTENCODEDnoSQUOTE |  OTHER_DELIMS | '$' | '&' | EQ | ':' | '@';
 
-fragment PCT_ENCODED    : '%' HEXDIG HEXDIG;
-fragment UNRESERVED     : ALPHA | DIGIT | '-' |'.' | '_' | '~';
-fragment SUB_DELIMS     : '$' | '&' | '\'' | '=' | OTHER_DELIMS;
-fragment OTHER_DELIMS   : '!' | '(' | ')' | '*' | '+' | ',' | ';';
+fragment PCT_ENCODED        : '%' HEXDIG HEXDIG;
+fragment UNRESERVED         : ALPHA | DIGIT | '-' |'.' | '_' | '~'; 
+fragment SUB_DELIMS         : '$' | '&' | '\'' | '=' | OTHER_DELIMS;
+fragment OTHER_DELIMS       : '!' | '(' | ')' | '*' | '+' | ',' | ';';
 
-fragment OTHERDELIMS    : '!' |  '(' | ')' | '*' | '+' | ',' | ';'
-                        ;
 
-fragment PCTENCODEDnoSQUOTE
-                        :  '%' ( '0'|'1'|'3'..'9' | AtoF ) HEXDIG
-                        | '%' '2' ( '0'..'6'|'8'|'9' | AtoF )
-                        ;
+fragment PCTENCODEDnoSQUOTE :  '%' ( '0'|'1'|'3'..'9' | AtoF ) HEXDIG
+                            | '%' '2' ( '0'..'6'|'8'|'9' | AtoF )
+                            ;
+
+fragment QCHAR_NO_AMP               : UNRESERVED | PCT_ENCODED | OTHER_DELIMS | ':' | '@' | '/' | '?' | '$' | '\'' | EQ;
+fragment QCHAR_NO_AMP_EQ            : UNRESERVED | PCT_ENCODED | OTHER_DELIMS | ':' | '@' | '/' | '?' | '$' | '\'';
+fragment QCHAR_NO_AMP_EQ_AT_DOLLAR  : UNRESERVED | PCT_ENCODED | OTHER_DELIMS | ':' |       '/' | '?' |       '\'';
 
-fragment QCHAR_NO_AMP              : UNRESERVED | PCT_ENCODED | OTHERDELIMS | ':' | '@' | '/' | '?' | '$' | '\'' | '=';// { IsIRIallowed() }?; 
-fragment QCHAR_NO_AMP_EQ           : UNRESERVED | PCT_ENCODED | OTHERDELIMS | ':' | '@' | '/' | '?' | '$' | '\'';
-fragment QCHAR_NO_AMP_EQ_AT_DOLLAR : UNRESERVED | PCT_ENCODED | OTHERDELIMS | ':' |       '/' | '?' |       '\'';
+fragment QCHAR_UNESCAPED            : UNRESERVED | PCT_ENCODED_UNESCAPED | OTHER_DELIMS | ':' | '@' | '/' | '?' | '$' | '\'' | EQ;
+fragment PCT_ENCODED_UNESCAPED      : '%' ( '0' | '1' |   '3' | '4' |   '6' | '8' | '9' | 'A'..'F' ) HEXDIG 
+                                    | '%' '2' ( '0' | '1' |   '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'A'..'F' ) 
+                                    | '%' '5' ( DIGIT | 'A' | 'B' |   'D' | 'E' | 'F' );
 
-fragment QCHAR_UNESCAPED           : UNRESERVED | PCT_ENCODED_UNESCAPED | OTHERDELIMS | ':' | '@' | '/' | '?' | '$' | '\'' | '=';
-PCT_ENCODED_UNESCAPED              : '%' ( '0' | '1' |   '3' | '4' |   '6' | '8' | '9' | 'A'..'F' ) HEXDIG 
-                                   | '%' '2' ( '0' | '1' |   '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'A'..'F' ) 
-                                   | '%' '5' ( DIGIT | 'A' | 'B' |   'D' | 'E' | 'F' );
+fragment QCHAR_NO_AMP_DQUOTE        : QCHAR_UNESCAPED
+                                    | ESCAPE ( ESCAPE | QUOTATION_MARK );
 
-fragment QCHAR_NO_AMP_DQUOTE   : QCHAR_UNESCAPED
-                               | ESCAPE ( ESCAPE | QUOTATION_MARK );
 //;------------------------------------------------------------------------------
 //; B. IRI syntax [RFC3987]
 //;------------------------------------------------------------------------------
@@ -258,22 +292,20 @@ fragment QCHAR_NO_AMP_DQUOTE   : QCHAR_UNESCAPED
 
 //IRI_IN_HEADER           : ( VCHAR | obs-text )+;
 
-
 //;------------------------------------------------------------------------------
 //; C. ABNF core definitions [RFC5234]
 //;------------------------------------------------------------------------------
 
+fragment    ALPHA     : 'a'..'z'|'A'..'Z';
+fragment    HEXDIG    : DIGIT | AtoF;
+fragment    AtoF      : 'a'..'f'|'A'..'F';
 
-fragment    ALPHA   : 'a'..'z'|'A'..'Z';
-            DIGIT   : '0'..'9';/* ('0'|ONEtoNINE)
-                    | '%x3'('0'..'9');*/
-fragment    HEXDIG  : DIGIT | AtoF;
-fragment    AtoF    : 'a'..'f'|'A'..'F';
-            DQUOTE  : '\u0022';
-            SP      : ' ';//'\u0020'; // a simple space
-            HTAB    : '%09'; 
-           
-fragment    VCHAR   : '\u0021'..'\u007E';
+//fragment    VCHAR   : '\u0021'..'\u007E';
+
+DIGIT                 : '0'..'9';
+DQUOTE                : '\u0022';
+SP                    : ' ';//'\u0020'; // a simple space
+HTAB                  : '%09'; 
             
 //;------------------------------------------------------------------------------
 //; End of odata-abnf-construction-rules
@@ -302,24 +334,27 @@ fragment Y  : 'y'|'Y';
 fragment Z  : 'z'|'Z';
 
 
-
-
-
-
 /* D O N T   C H A N G E   T H E   O R D E R   O F   T H I S*/
 /* D O N T   C H A N G E   T H E   O R D E R   O F   T H I S*/
 /* D O N T   C H A N G E   T H E   O R D E R   O F   T H I S*/
 STRING              : SQUOTE (SQUOTEinSTRING | PCHARnoSQUOTE )* SQUOTE; 
 
-SEARCHWORD          : ALPHA+ { IsSWallowed() }?;    //; Actually: any character from the Unicode categories L or Nl, 
-//                                                  //; but not the words AND, OR, and NOT which are match far above
-//CUSTOMNAME          : QCHAR_NO_AMP_EQ_AT_DOLLAR QCHAR_NO_AMP_EQ* { IsCUSTallowed() }?;
-//CUSTOMVALUE         : QCHAR_NO_AMP+ { IsCUSTallowed() }?;
+//conflict with ODATAIDENTIFIER, fixed with predicate
+SEARCHWORD          : ALPHA+ { inSearch() }?;       //; Actually: any character from the Unicode categories L or Nl, 
+                                                    //; but not the words AND, OR, and NOT which are match far above
+
+//conflict with STRING_IN_JSON, fixed with predicate
+SEARCHPHRASE: QUOTATION_MARK QCHAR_NO_AMP_DQUOTE+ QUOTATION_MARK { inSearch() }?;
+
+//TODO fix conflict
+//CUSTOMNAME        : QCHAR_NO_AMP_EQ_AT_DOLLAR QCHAR_NO_AMP_EQ* { IsCUSTallowed() }?;
+//CUSTOMVALUE       : QCHAR_NO_AMP+ { IsCUSTallowed() }?;
 
+ODATAIDENTIFIER     : ODI_LEADINGCHARACTER (ODI_CHARACTER)*;
 
-ODATAIDENTIFIER     : IDENTIFIERLEADINGCHARACTER (IDENTIFIERCHARACTER)*;
+AT_ODATAIDENTIFIER  : AT ODATAIDENTIFIER;
 
-AT_ODATAIDENTIFIER   : AT ODATAIDENTIFIER;
+STRING_IN_JSON      : QUOTATION_MARK CHAR_IN_JSON* QUOTATION_MARK;
 /* D O N T   C H A N G E   T H E   O R D E R   O F   T H I S*/
 /* D O N T   C H A N G E   T H E   O R D E R   O F   T H I S*/
 /* D O N T   C H A N G E   T H E   O R D E R   O F   T H I S*/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriInfo.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriInfo.java b/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriInfo.java
deleted file mode 100644
index 97b196a..0000000
--- a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriInfo.java
+++ /dev/null
@@ -1,54 +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.producer.core.uri;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.olingo.commons.api.edm.EdmBindingTarget;
-
-public class UriInfo {
-  private UriType uriType;
-  private EdmBindingTarget bindingTarget;
-  private List<String> keyNames = Collections.emptyList();
-
-  public UriType getUriType() {
-    return uriType;
-  }
-
-  public void setUriType(final UriType uriType) {
-    this.uriType = uriType;
-  }
-
-  public EdmBindingTarget getBindingTarget() {
-    return bindingTarget;
-  }
-
-  public void setBindingTarget(final EdmBindingTarget bindingTarget) {
-    this.bindingTarget = bindingTarget;
-  }
-
-  public void setKeyNames(final List<String> keyNames) {
-    this.keyNames = keyNames;
-  }
-
-  public List<String> getKeyNames() {
-    return keyNames;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriInfoImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriInfoImpl.java b/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriInfoImpl.java
index 8303866..926fc38 100644
--- a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriInfoImpl.java
+++ b/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriInfoImpl.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.producer.api.uri.UriInfo;
 
 public class UriInfoImpl extends UriInfo {
   private Edm edm = null;

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriParserImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriParserImpl.java b/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriParserImpl.java
new file mode 100644
index 0000000..e9e4bf9
--- /dev/null
+++ b/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriParserImpl.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * 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.producer.core.uri;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.DefaultErrorStrategy;
+import org.antlr.v4.runtime.atn.PredictionMode;
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.producer.core.uri.antlr.UriLexer;
+import org.apache.olingo.producer.core.uri.antlr.UriParser;
+import org.apache.olingo.producer.core.uri.antlr.UriParser.OdataRelativeUriContext;
+
+public class UriParserImpl {
+
+  public UriInfoImpl readUri(final String uri, final Edm edm) {
+    UriInfoImpl ret = new UriInfoImpl();
+    OdataRelativeUriContext root = parseUri(uri);
+
+    root.accept(new UriTreeVisitor(ret, edm));
+
+    /*
+     * 
+     * 
+     * if (root.getChildCount() == 1 ) {
+     * System.out.println("is service");
+     * return null;
+     * }
+     * 
+     * ParserRuleContext c0 = (ParserRuleContext) root.children.get(0);
+     * if (c0 instanceof BatchContext)
+     * {
+     * System.out.print("is $batch");
+     * return null;
+     * } else if (c0 instanceof EntityAContext)
+     * {
+     * readEntity(c0);
+     * return null;
+     * } else if (c0 instanceof MetadataContext)
+     * {
+     * readMetadata(c0);
+     * return null;
+     * } else if (c0 instanceof ResourcePathAContext)
+     * {
+     * readResourcePath(c0.getChild(0));
+     * if (c0.getChildCount() > 2) {
+     * readQueryOptions(c0.getChild(0));
+     * }
+     * return null;
+     * }
+     * 
+     * System.out.println("Error");
+     */
+    return ret;
+  }
+
+  private OdataRelativeUriContext parseUri(final String uri) {
+
+    ANTLRInputStream input = new ANTLRInputStream(uri);
+
+    UriLexer lexer = new UriLexer(input);
+
+    CommonTokenStream tokens = new CommonTokenStream(lexer);
+    UriParser parser = new UriParser(tokens);
+
+    //parser.addErrorListener(new ErrorHandler());
+    // if (stage == 1) {
+    // //see https://github.com/antlr/antlr4/issues/192
+    // parser.setErrorHandler(new BailErrorStrategy());
+    // parser.getInterpreter().setPredictionMode(PredictionMode.LL);
+    // } else {
+    parser.setErrorHandler(new DefaultErrorStrategy());
+    parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
+    // }
+
+    // parser.d
+    return parser.odataRelativeUri();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriTreeReader.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriTreeReader.java b/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriTreeReader.java
deleted file mode 100644
index 2aeeb28..0000000
--- a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriTreeReader.java
+++ /dev/null
@@ -1,105 +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.producer.core.uri;
-
-import org.antlr.v4.runtime.ANTLRInputStream;
-import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.DefaultErrorStrategy;
-import org.antlr.v4.runtime.atn.PredictionMode;
-import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.producer.core.uri.antlr.UriLexer;
-import org.apache.olingo.producer.core.uri.antlr.UriParser;
-import org.apache.olingo.producer.core.uri.antlr.UriParser.OdataRelativeUriAContext;
-
-public class UriTreeReader {
-
-//  //@Test
-//  public void Test() {
-//    String uri = "EntityColFunctionImport(ParameterName1=1)(1)/Namespace1.EntityTypeName/EntityFunctionImport()/"
-//        + "Namespace1.EntityTypeName?$expand=ComplexColProperty/Namespace1.ComplexTypeName/EntityNavigationProperty"
-//        + "&$filter=Namespace1.EntityTypeName/Namespace1.EntityFunction() eq 1 and true";
-//    //String uri = "$entity?$id=1";
-//    readUri(uri);
-//  }
-
-  public UriInfoImpl readUri(final String uri, final Edm edm) {
-    UriInfoImpl ret = new UriInfoImpl();
-    OdataRelativeUriAContext root = parseUri(uri);
-
-    root.accept(new UriTreeVisitor(ret, edm));
-
-    /*
-     * 
-     * 
-     * if (root.getChildCount() == 1 ) {
-     * System.out.println("is service");
-     * return null;
-     * }
-     * 
-     * ParserRuleContext c0 = (ParserRuleContext) root.children.get(0);
-     * if (c0 instanceof BatchContext)
-     * {
-     * System.out.print("is $batch");
-     * return null;
-     * } else if (c0 instanceof EntityAContext)
-     * {
-     * readEntity(c0);
-     * return null;
-     * } else if (c0 instanceof MetadataContext)
-     * {
-     * readMetadata(c0);
-     * return null;
-     * } else if (c0 instanceof ResourcePathAContext)
-     * {
-     * readResourcePath(c0.getChild(0));
-     * if (c0.getChildCount() > 2) {
-     * readQueryOptions(c0.getChild(0));
-     * }
-     * return null;
-     * }
-     * 
-     * System.out.println("Error");
-     */
-    return ret;
-  }
-
-  private OdataRelativeUriAContext parseUri(final String uri) {
-
-    ANTLRInputStream input = new ANTLRInputStream(uri);
-
-    UriLexer lexer = new UriLexer(input);
-
-    CommonTokenStream tokens = new CommonTokenStream(lexer);
-    UriParser parser = new UriParser(tokens);
-
-    parser.addErrorListener(new ErrorHandler());
-
-    // if (stage == 1) {
-    // //see https://github.com/antlr/antlr4/issues/192
-    // parser.setErrorHandler(new BailErrorStrategy());
-    // parser.getInterpreter().setPredictionMode(PredictionMode.LL);
-    // } else {
-    parser.setErrorHandler(new DefaultErrorStrategy());
-    parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
-    // }
-
-    // parser.d
-    return parser.odataRelativeUriA();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriTreeVisitor.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriTreeVisitor.java b/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriTreeVisitor.java
index 6c4de80..5daa478 100644
--- a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriTreeVisitor.java
+++ b/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriTreeVisitor.java
@@ -72,14 +72,14 @@ public class UriTreeVisitor extends UriBaseVisitor<Object> {
   }
 
   @Override
-  public Object visitBatch(@NotNull final UriParser.BatchContext ctx) {
+  public Object visitBatchAlt(@NotNull final UriParser.BatchAltContext ctx) {
     // Set UriType to Batch
 
     return null;
   }
 
   @Override
-  public Object visitEntityA(@NotNull final UriParser.EntityAContext ctx) {
+  public Object visitEntityAlt(@NotNull final UriParser.EntityAltContext ctx) {
     // Set UriType to Entity
     // uriInfo.AddResSelector(new OriResourceSelector());
 
@@ -87,7 +87,7 @@ public class UriTreeVisitor extends UriBaseVisitor<Object> {
   }
 
   @Override
-  public Object visitMetadata(@NotNull final UriParser.MetadataContext ctx) {
+  public Object visitMetadataAlt(@NotNull final UriParser.MetadataAltContext ctx) {
     // Set UriType to Entity
     // uriInfo.AddResSelector(new OriResourceSelector());
 

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriType.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriType.java b/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriType.java
deleted file mode 100644
index 78d34ed..0000000
--- a/odata4-lib/odata4-producer-core/src/main/java/org/apache/olingo/producer/core/uri/UriType.java
+++ /dev/null
@@ -1,83 +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.producer.core.uri;
-
-public enum UriType {
-  TYPE_ENTITY_SET,
-  TYPE_ENTITY_SET_COUNT,
-  TYPE_MEDIA_REFERENCE,
-  TYPE_REFERENCE_COLLECTION,
-  /*
-   * Singleton
-   */
-  TYPE_ENTITY,
-  TYPE_MEDIA_STREAM,
-  TYPE_REFERENCE,
-
-  /*
-   * Property Path
-   */
-  TYPE_PROPERTY_PRIMITIVE,
-  TYPE_PROPERTY_PRIMITIVE_COLLECTION,
-  TYPE_PROPERTY_PRIMITIVE_VALUE,
-  TYPE_PROPERTY_COMPLEX,
-
-  /*
-   * Crossjoin
-   */
-  TYPE_CROSSJOIN,
-
-  /*
-   * $all
-   */
-  TYPE_SERVICE_ALL,
-  /*
-   * ActionImport
-   */
-  TYPE_AI_ENTITY,
-  /*
-   * FunctionImport
-   */
-  TYPE_FI_ENTITY,
-  TYPE_FI_ENTITY_SET,
-  TYPE_FI_ENTITY_SET_COUNT,
-  TYPE_FI_PROPERTY_PRIMITIVE,
-  TYPE_FI_PROPERTY_PRIMITIVE_COLL,
-  TYPE_FI_PROPERTY_PRIMITIVE_COLL_COUNT,
-  TYPE_FI_PROPERTY_COMPLEX,
-  TYPE_FI_PROPERTY_COMPLEX_COLL,
-  TYPE_FI_PROPERTY_COMPLEX_COLL_COUNT,
-  /*
-   * BoundFunction
-   */
-  TYPE_BF_ENTITY,
-  TYPE_BF_ENTITY_SET,
-  TYPE_BF_PROP_PRIM,
-  TYPE_BF_PROP_COMP,
-  TYPE_BF_PROP_COMP_COLL,
-  TYPE_BF_PROP_PRIM_COLL,
-  /*
-   * BoundAction
-   */
-  TYPE_BA_ENTITY_SET,
-  TYPE_BA_ENTITY,
-  TYPE_BA_PROP_PRIM,
-  TYPE_BA_PROP_PRIM_COLL,
-  TYPE_BA_PROP_COMP;
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/test/java/org/apache/olingo/producer/core/testutil/EdmTechProvider.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/test/java/org/apache/olingo/producer/core/testutil/EdmTechProvider.java b/odata4-lib/odata4-producer-core/src/test/java/org/apache/olingo/producer/core/testutil/EdmTechProvider.java
new file mode 100644
index 0000000..99dc52e
--- /dev/null
+++ b/odata4-lib/odata4-producer-core/src/test/java/org/apache/olingo/producer/core/testutil/EdmTechProvider.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * 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.producer.core.testutil;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import org.apache.olingo.commons.api.edm.EdmEntityContainer;
+import org.apache.olingo.commons.api.edm.helper.EntityContainerInfo;
+import org.apache.olingo.commons.api.edm.helper.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.provider.EdmProviderAdapter;
+import org.apache.olingo.commons.api.edm.provider.EntitySet;
+import org.apache.olingo.commons.api.edm.provider.EntityType;
+import org.apache.olingo.commons.api.edm.provider.Property;
+import org.apache.olingo.commons.api.edm.provider.PropertyRef;
+import org.apache.olingo.commons.api.exception.ODataException;
+import org.apache.olingo.commons.api.exception.ODataNotImplementedException;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.core.edm.provider.EdmEntityContainerImpl;
+
+public class EdmTechProvider extends EdmProviderAdapter {
+
+  Property propertyInt16NotNullable = new Property()
+      .setName("PropertyInt16")
+      .setType(EdmPrimitiveTypeKind.Int16.getFullQualifiedName())
+      .setNullable(false);
+//Simple typed Properties
+  Property propertyBinary = new Property()
+      .setName("PropertyBinary")
+      .setType(EdmPrimitiveTypeKind.Binary.getFullQualifiedName());
+  Property propertyBoolean = new Property()
+      .setName("PropertyBoolean")
+      .setType(EdmPrimitiveTypeKind.Boolean.getFullQualifiedName());
+  Property propertyByte = new Property()
+      .setName("PropertyByte")
+      .setType(EdmPrimitiveTypeKind.Byte.getFullQualifiedName());
+  Property propertyDate = new Property()
+      .setName("PropertyDate")
+      .setType(EdmPrimitiveTypeKind.Date.getFullQualifiedName());
+  Property propertyDateTimeOffset = new Property()
+      .setName("PropertyDateTimeOffset")
+      .setType(EdmPrimitiveTypeKind.DateTimeOffset.getFullQualifiedName());
+  Property propertyDecimal = new Property()
+      .setName("PropertyDecimal")
+      .setType(EdmPrimitiveTypeKind.Decimal.getFullQualifiedName());
+  Property propertyDouble = new Property()
+      .setName("PropertyDouble")
+      .setType(EdmPrimitiveTypeKind.Double.getFullQualifiedName());
+  Property propertyDuration = new Property()
+      .setName("PropertyDuration")
+      .setType(EdmPrimitiveTypeKind.Duration.getFullQualifiedName());
+  Property propertyGuid = new Property()
+      .setName("PropertyGuid")
+      .setType(EdmPrimitiveTypeKind.Guid.getFullQualifiedName());
+  Property propertyInt16 = new Property()
+      .setName("PropertyInt16")
+      .setType(EdmPrimitiveTypeKind.Int16.getFullQualifiedName());
+  Property propertyInt32 = new Property()
+      .setName("PropertyInt32")
+      .setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
+  Property propertyInt64 = new Property()
+      .setName("PropertyInt64")
+      .setType(EdmPrimitiveTypeKind.Int64.getFullQualifiedName());
+  Property propertySByte = new Property()
+      .setName("PropertySByte")
+      .setType(EdmPrimitiveTypeKind.SByte.getFullQualifiedName());
+  Property propertySingle = new Property()
+      .setName("PropertySingle")
+      .setType(EdmPrimitiveTypeKind.Single.getFullQualifiedName());
+  Property propertyString = new Property()
+      .setName("PropertyString")
+      .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+  Property propertyTimeOfDay = new Property()
+      .setName("PropertyTimeOfDay")
+      .setType(EdmPrimitiveTypeKind.TimeOfDay.getFullQualifiedName());
+
+  // Properties typed as collection of simple types
+  Property collectionPropertyBinary = new Property()
+      .setName("CollPropertyBinary")
+      .setType(EdmPrimitiveTypeKind.Binary.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyBoolean = new Property()
+      .setName("CollPropertyBoolean")
+      .setType(EdmPrimitiveTypeKind.Boolean.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyByte = new Property()
+      .setName("CollPropertyByte")
+      .setType(EdmPrimitiveTypeKind.Byte.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyDate = new Property()
+      .setName("CollPropertyDate")
+      .setType(EdmPrimitiveTypeKind.Date.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyDateTimeOffset = new Property()
+      .setName("CollPropertyDateTimeOffset")
+      .setType(EdmPrimitiveTypeKind.DateTimeOffset.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyDecimal = new Property()
+      .setName("CollPropertyDecimal")
+      .setType(EdmPrimitiveTypeKind.Decimal.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyDouble = new Property()
+      .setName("CollPropertyDouble")
+      .setType(EdmPrimitiveTypeKind.Double.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyDuration = new Property()
+      .setName("CollPropertyDuration")
+      .setType(EdmPrimitiveTypeKind.Duration.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyGuid = new Property()
+      .setName("CollPropertyGuid")
+      .setType(EdmPrimitiveTypeKind.Guid.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyInt16 = new Property()
+      .setName("CollPropertyInt16")
+      .setType(EdmPrimitiveTypeKind.Int16.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyInt32 = new Property()
+      .setName("CollPropertyInt32")
+      .setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyInt64 = new Property()
+      .setName("CollPropertyInt64")
+      .setType(EdmPrimitiveTypeKind.Int64.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertySByte = new Property()
+      .setName("CollPropertySByte")
+      .setType(EdmPrimitiveTypeKind.SByte.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertySingle = new Property()
+      .setName("CollPropertySingle")
+      .setType(EdmPrimitiveTypeKind.Single.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyString = new Property()
+      .setName("CollPropertyString")
+      .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName())
+      .setCollection(true);
+  Property collectionPropertyTimeOfDay = new Property()
+      .setName("CollPropertyTimeOfDay")
+      .setType(EdmPrimitiveTypeKind.TimeOfDay.getFullQualifiedName())
+      .setCollection(true);
+
+  EdmEntityContainer entityContainerTest1 = new EdmEntityContainerImpl(
+      new EntityContainerInfo()
+          .setContainerName(new FullQualifiedName("com.sap.odata.test1", "Container"))
+      );
+
+  @Override
+  public EntitySet getEntitySet(final FullQualifiedName entityContainer, final String name) throws ODataException {
+    if (entityContainer == null) {
+      if (name.equals("ESAllPrim")) {
+
+        return new EntitySet()
+            .setName("ETAllPrim")
+            .setEntityType(new FullQualifiedName("com.sap.odata.test1", "ESAllPrim"));
+
+      } else if (name.equals("ESCollAllPrim")) {
+
+        return new EntitySet()
+            .setName("ESCollAllPrim")
+            .setEntityType(new FullQualifiedName("com.sap.odata.test1", "ETCollAllPrim"));
+
+      }
+    }
+
+    throw new ODataNotImplementedException();
+  }
+
+  @Override
+  public EntityType getEntityType(final FullQualifiedName entityTypeName) throws ODataException {
+
+    if (entityTypeName.equals(new FullQualifiedName("com.sap.odata.test1", "ETAllPrim"))) {
+      return new EntityType()
+          .setName("ETAllPrim")
+          .setProperties(Arrays.asList(
+              propertyBinary, propertyBoolean, propertyByte,
+              propertyDate, propertyDateTimeOffset, propertyDecimal,
+              propertyDouble, propertyDuration, propertyDecimal,
+              propertyInt16NotNullable, propertyInt32, propertyInt64,
+              propertySByte, propertySingle, propertyString,
+              propertyTimeOfDay))
+          .setKey(Arrays.asList(
+              new PropertyRef().setName("PropertyInt16")));
+
+    } else if (entityTypeName.equals(new FullQualifiedName("com.sap.odata.test1", "ETCollAllPrim"))) {
+      return new EntityType()
+          .setName("ETCollAllPrim")
+          .setProperties(Arrays.asList(
+              propertyInt16NotNullable,
+              collectionPropertyBinary, collectionPropertyBoolean, collectionPropertyByte,
+              collectionPropertyDate, collectionPropertyDateTimeOffset, collectionPropertyDecimal,
+              collectionPropertyDouble, collectionPropertyDuration, collectionPropertyDecimal,
+              collectionPropertyInt16, collectionPropertyInt32, collectionPropertyInt64,
+              collectionPropertySByte, collectionPropertySingle, collectionPropertyString,
+              collectionPropertyTimeOfDay))
+          .setKey(Arrays.asList(
+              new PropertyRef().setName("PropertyInt16")));
+    }
+
+    throw new ODataNotImplementedException();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/9aec30fd/odata4-lib/odata4-producer-core/src/test/java/org/apache/olingo/producer/core/testutil/TokenValidator.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-producer-core/src/test/java/org/apache/olingo/producer/core/testutil/TokenValidator.java b/odata4-lib/odata4-producer-core/src/test/java/org/apache/olingo/producer/core/testutil/TokenValidator.java
new file mode 100644
index 0000000..06b6a0b
--- /dev/null
+++ b/odata4-lib/odata4-producer-core/src/test/java/org/apache/olingo/producer/core/testutil/TokenValidator.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * 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.producer.core.testutil;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+
+import org.antlr.v4.runtime.ANTLRErrorListener;
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.Parser;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.atn.ATNConfigSet;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.apache.olingo.producer.core.uri.antlr.UriLexer;
+
+public class TokenValidator {
+  List<? extends Token> tokens = null;
+  List<Exception> exceptions = new ArrayList<Exception>();
+  Token curToken = null;
+  Exception curException = null;
+  String input = null;
+
+  public TokenValidator run(String uri ) {
+    return run( uri,false);
+  }
+  public TokenValidator run(String uri, boolean searchMode) {
+    input = uri;
+    exceptions.clear();
+    tokens = parseInput(uri,searchMode);
+    first();
+    exFirst();
+    return this;
+  }
+
+  
+  public TokenValidator isText(String expected) {
+    assertEquals(expected, curToken.getText());
+    return this;
+  }
+  public TokenValidator isInput( ) {
+    assertEquals(input, curToken.getText());
+    return this;
+  }
+
+  public TokenValidator isType(int expected) {
+    assertEquals(UriLexer.tokenNames[expected], UriLexer.tokenNames[curToken.getType()]);
+    return this;
+  }
+
+  public TokenValidator isExType(Class<?> exClass) {
+    assertEquals(exClass, curException.getClass());
+    return this;
+  }
+
+  private List<? extends Token> parseInput(final String input, boolean searchMode) {
+    ANTLRInputStream inputStream = new ANTLRInputStream(input);
+
+    UriLexer lexer = new UriLexer(inputStream);
+    lexer.setInSearch(searchMode);
+    //lexer.removeErrorListeners();
+    lexer.addErrorListener(new ErrorCollector(this));
+    return lexer.getAllTokens();
+  }
+
+  public TokenValidator first() {
+    try {
+      curToken = tokens.get(0);
+    } catch (IndexOutOfBoundsException ex) {
+      curToken = null;
+    }
+    return this;
+  }
+
+  public TokenValidator exFirst() {
+    try {
+      curException = exceptions.get(0);
+    } catch (IndexOutOfBoundsException ex) {
+      curException = null;
+    }
+    return this;
+
+  }
+
+  public TokenValidator last() {
+    curToken = tokens.get(tokens.size() - 1);
+    return this;
+  }
+
+  public TokenValidator exLast() {
+    curException = exceptions.get(exceptions.size() - 1);
+    return this;
+  }
+
+  public TokenValidator at(int index) {
+    try {
+      curToken = tokens.get(index);
+    } catch (IndexOutOfBoundsException ex) {
+      curToken = null;
+    }
+    return this;
+  }
+
+  public TokenValidator exAt(int index) {
+    try {
+      curException = exceptions.get(index);
+    } catch (IndexOutOfBoundsException ex) {
+      curException = null;
+    }
+    return this;
+  }
+
+  private static class ErrorCollector implements ANTLRErrorListener {
+    TokenValidator tokenValidator;
+
+    public ErrorCollector(TokenValidator tokenValidator) {
+      this.tokenValidator = tokenValidator;
+    }
+
+    @Override
+    public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
+        String msg, RecognitionException e) {
+      tokenValidator.exceptions.add(e);
+    }
+
+    @Override
+    public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact,
+        BitSet ambigAlts, ATNConfigSet configs) {
+      fail("reportAmbiguity");
+    }
+
+    @Override
+    public void reportAttemptingFullContext(Parser recognizer, DFA dfa, int startIndex, int stopIndex,
+        BitSet conflictingAlts, ATNConfigSet configs) {
+      fail("reportAttemptingFullContext");
+    }
+
+    @Override
+    public void reportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction,
+        ATNConfigSet configs) {
+      fail("reportContextSensitivity");
+    }
+
+  }
+
+}