You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2014/02/17 16:35:58 UTC
[11/29] [OLINGO-161] Refactored module names
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/c49ff803/odata4-lib/odata4-server-core/src/main/antlr4/org/apache/olingo/odata4/producer/core/uri/antlr/UriParser.g4
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-server-core/src/main/antlr4/org/apache/olingo/odata4/producer/core/uri/antlr/UriParser.g4 b/odata4-lib/odata4-server-core/src/main/antlr4/org/apache/olingo/odata4/producer/core/uri/antlr/UriParser.g4
new file mode 100644
index 0000000..82d2d60
--- /dev/null
+++ b/odata4-lib/odata4-server-core/src/main/antlr4/org/apache/olingo/odata4/producer/core/uri/antlr/UriParser.g4
@@ -0,0 +1,518 @@
+/*******************************************************************************
+ * 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.
+ ******************************************************************************/
+
+ grammar UriParser;
+
+
+//Antlr4 (as most parsers) has a lexer for token detection and a parser which defines
+//rules based on the tokens. However its hard to define a clear lexer on the
+//ODATA URI syntax due to some reasons:
+// - the syntax is based on the URI specification and there fore contains the definition
+// of delimiters and percent encoding
+// - the syntax includes JSON
+// - the syntax includes a expression syntax which comes from ODATA itself (e.g. $filter)
+// - the syntax includes searchstring and searchword
+// - the ABNF describing syntax is not defined in a context free manner
+// so there are several kinds of "String" tokens:
+// - strings with single quotes,
+// - strings with single quotes and a special syntax within the quotes (like geometry data)
+// - strings with double quotes
+// - strings without quotes ( usually identifiers, searchstrings, searchwords, custom parameters)
+// but each with different allowed charactersets
+// Drawing a simple line between lexer and parser is not possible.
+//
+// This grammer is a compromiss we have choosen to satisfy the requirements we have
+// - the grammer is context free
+// - this makes the parser much simpler and we have a clear saparation between parsing and
+// EDM validation, but also creates a parse tree which is not semantically correct from the
+// EDM perspective ( e.g.it will not pass the EDM validation)
+// - the grammer can not be applied on a full URI string
+// - the URI should be split according the URI specification before used as input for the
+// ODATA parser
+// - while creating the grammer the antlr lexer modes where only allowed in pure lexer grammers
+// not in combined grammers, and is was not possible to include lexer grammer with a mode into
+// a combined grammar without creating JAVA errors.
+
+// see https://github.com/antlr/antlr4/issues/160 "Support importing multi-mode lexer grammars"
+
+
+//Naming convention
+// ...
+//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 <-- SLASH must be encoded to '%2F' in "Hugo/Mueller"
+// but it must not be encoded before the EmployeeName
+
+
+
+options {
+ language = Java;
+ tokenVocab=UriLexer;
+}
+
+
+//;------------------------------------------------------------------------------
+//; 0. URI
+//;------------------------------------------------------------------------------
+
+//ABNF odataUri and serviceRoot are currently not used here
+//odataUri = serviceRoot [ odataRelativeUri ]
+//
+//serviceRoot = ( "https" / "http" ) ; Note: case-insensitive
+// "://" host [ ":" port ]
+// "/" *( segment-nz "/" )
+
+
+odataRelativeUriEOF : odataRelativeUri? EOF;
+
+//QM and FRAGMENT enable next lexer mode
+//TODO add the new "ENTITYCAST"
+odataRelativeUri : BATCH # altBatch
+ | ENTITY QM vEO=entityOptions # altEntity
+ | ENTITY SLASH vNS=namespace vODI=odataIdentifier QM vEO=entityOptionsCast # altEntityCast
+ | METADATA ( QM vF=format )? ( FRAGMENT vCF=contextFragment )? # altMetadata
+ | vRP=resourcePath ( QM vQO=queryOptions )? # altResourcePath
+ ;
+
+//;------------------------------------------------------------------------------
+//; 1. Resource Path
+//;------------------------------------------------------------------------------
+
+resourcePath : vAll=ALL
+ | vCJ=crossjoin
+ | vlPS=pathSegments
+ ;
+crossjoin : CROSSJOIN OPEN WSP? vlODI+=odataIdentifier WSP? ( COMMA WSP? vlODI+=odataIdentifier WSP?)* CLOSE;
+
+pathSegments : vlPS+=pathSegment (SLASH vlPS+=pathSegment)* vCS=constSegment?;
+
+pathSegment : vNS=namespace? vODI=odataIdentifier vlNVO+=nameValueOptList*;
+
+nameValueOptList : OPEN (vVO=valueOnly | vNVL=nameValueList)? CLOSE;
+valueOnly : vV=commonExpr ;
+nameValueList : WSP* vlNVP+=nameValuePair WSP* ( COMMA WSP* vlNVP+=nameValuePair WSP*)* ;
+nameValuePair : vODI=odataIdentifier EQ (AT vALI=odataIdentifier | vCOM=commonExpr /*TODO | val2=enumX*/);
+
+constSegment : SLASH (vV=value | vC=count | vR=ref | vAll=allExpr | vAny=anyExpr);
+
+count : COUNT;
+ref : REF;
+value : VALUE;
+//;------------------------------------------------------------------------------
+//; 2. Query Options
+//;------------------------------------------------------------------------------
+
+queryOptions : vlQO+=queryOption ( AMP vlQO+=queryOption )*;
+
+queryOption : systemQueryOption
+ | AT_Q aliasAndValue
+ | customQueryOption
+ ;
+
+entityOptions : (vlEOb+=entityOption AMP )* vlEOm=id ( AMP vlEOa+=entityOption )*;
+entityOption : format
+ | customQueryOption
+ ;
+
+entityOptionsCast : (vlEOb+=entityOptionCast AMP )* vlEOm=id ( AMP vlEOa+=entityOptionCast )*;
+entityOptionCast : expand
+ | format
+ | select
+ | filter
+ | customQueryOption
+ ;
+
+systemQueryOption : expand
+ | filter
+ | format
+ | id
+ | inlinecount
+ | orderBy
+ | search
+ | select
+ | skip
+ | skiptoken
+ | top
+ ;
+
+id : ID EQ REST;
+skiptoken : SKIPTOKEN EQ REST;
+expand : EXPAND EQ vlEI+=expandItem ( COMMA vlEI+=expandItem )*;
+
+expandItem : vS=STAR ( SLASH vR=ref | OPEN LEVELS EQ ( vL=INT | vM=MAX) CLOSE )?
+ | vEP=expandPath vEPE=expandPathExtension?;
+
+
+expandPath : vlPS+=pathSegment (SLASH vlPS+=pathSegment)*;
+//expandPath : expandPathSegment ( SLASH expandPathSegment )*;
+//expandPathSegment : vNS=namespace? vODI=odataIdentifier;
+
+expandPathExtension : OPEN vlEO+=expandOption ( SEMI vlEO+=expandOption )* CLOSE
+ | SLASH vR=ref ( OPEN vlEOR+=expandRefOption ( SEMI vlEOR+=expandRefOption )* CLOSE )?
+ | SLASH vC=count ( OPEN vlEOC+=expandCountOption ( SEMI vlEOC+=expandCountOption )* CLOSE )?
+ ;
+expandCountOption : filter
+ | search
+ ;
+expandRefOption : expandCountOption
+ | orderBy
+ | skip
+ | top
+ | inlinecount
+ ;
+expandOption : expandRefOption
+ | select
+ | expand
+ | levels;
+
+levels : LEVELS EQ ( INT | MAX );
+
+filter : FILTER EQ commonExpr;
+
+orderBy : ORDERBY EQ WSP* vlOI+=orderByItem ( WSP* COMMA WSP* vlOI+=orderByItem )*;
+orderByItem : vC=commonExpr ( WSP ( vA=ASC | vD=DESC ) )?;
+
+//this is completly done in lexer grammer to avoid ambiguities with odataIdentifier and STRING
+skip : SKIP EQ INT;
+top : TOP EQ INT;
+format : FORMAT EQ ( ATOM | JSON | XML | PCHARS ( SLASH PCHARS)?);
+
+inlinecount : COUNT EQ booleanNonCase;
+
+search : SEARCH searchSpecialToken;
+searchInline : SEARCH_INLINE searchSpecialToken;
+
+searchSpecialToken : EQ WSP? searchExpr;
+
+searchExpr : (NOT WSP) searchExpr
+ | searchExpr searchExpr
+ | searchExpr WSP searchExpr
+ | searchExpr ( WSP AND WSP) searchExpr
+ | searchExpr ( WSP OR WSP) searchExpr
+ | searchPhrase
+ | searchWord
+ ;
+
+searchPhrase : SEARCHPHRASE;
+searchWord : SEARCHWORD;
+
+select : SELECT EQ vlSI+=selectItem ( COMMA vlSI+=selectItem )*;
+selectItem : vlSS+=selectSegment ( SLASH vlSS+=selectSegment ) *;
+selectSegment : vNS=namespace? ( vODI=odataIdentifier | vS=STAR );
+
+aliasAndValue : vODI=ODATAIDENTIFIER EQ vV=parameterValue;
+parameterValue : //TODO json not supported arrayOrObject
+ commonExpr
+ ;
+
+
+
+customQueryOption : customName ( EQ customValue)?
+ ;
+customName : CUSTOMNAME;
+customValue : REST;
+
+
+
+//;------------------------------------------------------------------------------
+//; 3. Context URL Fragments
+//;------------------------------------------------------------------------------
+//TODO add ps+=pathSegment (SLASH ps+=pathSegment)*
+contextFragment : REST;
+
+propertyList : OPEN propertyListItem ( COMMA propertyListItem )* CLOSE;
+propertyListItem : STAR //; all structural properties
+ | propertyListProperty
+ ;
+propertyListProperty : namespace? odataIdentifier ( SLASH namespace? odataIdentifier)* ( PLUS )? ( propertyList)?
+ ;
+
+
+//;------------------------------------------------------------------------------
+//; 4. Expressions
+//;------------------------------------------------------------------------------
+
+// this expression part of the grammer is not similar to the ABNF because
+// we had to introduced operator precesence witch is not reflected in the ABNF
+
+test : test_expr EOF;
+test_expr : INT
+ //| test_expr /*WSP*/ ( '!' | '*' ) /*WSP*/ test_expr;
+ //| test_expr WSP ( '!' | '*' ) WSP test_expr;
+ | test_expr ( WSP '!' WSP | WSP '*' WSP ) test_expr;
+
+commonExpr : OPEN commonExpr CLOSE #altPharenthesis
+ | vE1=commonExpr (WSP HAS WSP) vE2=commonExpr #altHas
+ | methodCallExpr #altMethod
+ | ( unary WSP ) commonExpr #altUnary
+ | anyExpr #altAny
+ | allExpr #altAll
+ | memberExpr #altMember
+ | vE1=commonExpr (WSP vO=MUL WSP | WSP vO=DIV WSP | WSP vO=MOD WSP ) vE2=commonExpr #altMult
+ | vE1=commonExpr (WSP vO=ADD WSP | WSP vO=SUB WSP) vE2=commonExpr #altAdd
+ | vE1=commonExpr (WSP vO=GT WSP | WSP vO=GE WSP | WSP vO=LT WSP
+ | WSP vO=LE WSP ) vE2=commonExpr #altComparism
+ | vE1=commonExpr (WSP vO=EQ_ALPHA WSP | WSP vO=NE WSP) vE2=commonExpr #altEquality
+ | vE1=commonExpr (WSP AND WSP) vE2=commonExpr #altAnd
+ | vE1=commonExpr (WSP OR WSP) vE2=commonExpr #altOr
+ | rootExpr #altRoot //; $...
+ | AT odataIdentifier #altAlias // @...
+ | primitiveLiteral #altLiteral // ...
+ ;
+
+unary : (MINUS| NOT) ;
+
+rootExpr : ROOT vPs=pathSegments;
+
+memberExpr : vIt=IT ( SLASH (vANY=anyExpr | vALL=allExpr))?
+ | vIts=ITSLASH? vPs=pathSegments ( SLASH (vANY=anyExpr | vALL=allExpr))?;
+
+anyExpr : ANY_LAMDA OPEN WSP? ( vLV=odataIdentifier WSP? COLON WSP? vLE=commonExpr WSP? )? CLOSE;
+allExpr : ALL_LAMDA OPEN WSP? vLV=odataIdentifier WSP? COLON WSP? vLE=commonExpr WSP? CLOSE;
+
+methodCallExpr : indexOfMethodCallExpr
+ | toLowerMethodCallExpr
+ | toUpperMethodCallExpr
+ | trimMethodCallExpr
+ | substringMethodCallExpr
+ | concatMethodCallExpr
+ | lengthMethodCallExpr
+ | yearMethodCallExpr
+ | monthMethodCallExpr
+ | dayMethodCallExpr
+ | hourMethodCallExpr
+ | minuteMethodCallExpr
+ | secondMethodCallExpr
+ | fractionalsecondsMethodCallExpr
+ | totalsecondsMethodCallExpr
+ | dateMethodCallExpr
+ | timeMethodCallExpr
+ | roundMethodCallExpr
+ | floorMethodCallExpr
+ | ceilingMethodCallExpr
+ | geoDistanceMethodCallExpr
+ | geoLengthMethodCallExpr
+ | totalOffsetMinutesMethodCallExpr
+ | minDateTimeMethodCallExpr
+ | maxDateTimeMethodCallExpr
+ | nowMethodCallExpr
+ //from boolean
+ | isofExpr
+ | castExpr
+ | endsWithMethodCallExpr
+ | startsWithMethodCallExpr
+ | containsMethodCallExpr
+ | geoIntersectsMethodCallExpr
+ ;
+
+
+containsMethodCallExpr : CONTAINS_WORD WSP? vE1=commonExpr WSP? COMMA WSP? vE2=commonExpr WSP? CLOSE;
+startsWithMethodCallExpr : STARTSWITH_WORD WSP? vE1=commonExpr WSP? COMMA WSP? vE2=commonExpr WSP? CLOSE;
+endsWithMethodCallExpr : ENDSWITH_WORD WSP? vE1=commonExpr WSP? COMMA WSP? vE2=commonExpr WSP? CLOSE;
+lengthMethodCallExpr : LENGTH_WORD WSP? vE1=commonExpr WSP? CLOSE;
+indexOfMethodCallExpr : INDEXOF_WORD WSP? vE1=commonExpr WSP? COMMA WSP? vE2=commonExpr WSP? CLOSE;
+substringMethodCallExpr : SUBSTRING_WORD WSP? vE1=commonExpr WSP? COMMA WSP? vE2=commonExpr WSP? ( COMMA WSP? vE3=commonExpr WSP? )? CLOSE;
+toLowerMethodCallExpr : TOLOWER_WORD WSP? vE1=commonExpr WSP? CLOSE;
+toUpperMethodCallExpr : TOUPPER_WORD WSP? vE1=commonExpr WSP? CLOSE;
+trimMethodCallExpr : TRIM_WORD WSP? vE1=commonExpr WSP? CLOSE;
+concatMethodCallExpr : CONCAT_WORD WSP? vE1=commonExpr WSP? COMMA WSP? vE2=commonExpr WSP? CLOSE;
+
+yearMethodCallExpr : YEAR_WORD WSP? vE1=commonExpr WSP? CLOSE;
+monthMethodCallExpr : MONTH_WORD WSP? vE1=commonExpr WSP? CLOSE;
+dayMethodCallExpr : DAY_WORD WSP? vE1=commonExpr WSP? CLOSE;
+hourMethodCallExpr : HOUR_WORD WSP? vE1=commonExpr WSP? CLOSE;
+minuteMethodCallExpr : MINUTE_WORD WSP? vE1=commonExpr WSP? CLOSE;
+secondMethodCallExpr : SECOND_WORD WSP? vE1=commonExpr WSP? CLOSE;
+fractionalsecondsMethodCallExpr : FRACTIONALSECONDS_WORD WSP? vE1=commonExpr WSP? CLOSE;
+totalsecondsMethodCallExpr : TOTALSECONDS_WORD WSP? vE1=commonExpr WSP? CLOSE;
+dateMethodCallExpr : DATE_WORD WSP? vE1=commonExpr WSP? CLOSE;
+timeMethodCallExpr : TIME_WORD WSP? vE1=commonExpr WSP? CLOSE;
+totalOffsetMinutesMethodCallExpr : TOTALOFFSETMINUTES_WORD WSP? vE1=commonExpr WSP? CLOSE;
+
+minDateTimeMethodCallExpr : MINDATETIME_WORD WSP? CLOSE;
+maxDateTimeMethodCallExpr : MAXDATETIME_WORD WSP? CLOSE;
+nowMethodCallExpr : NOW_WORD WSP? CLOSE;
+
+roundMethodCallExpr : ROUND_WORD WSP? vE1=commonExpr WSP? CLOSE;
+floorMethodCallExpr : FLOOR_WORD WSP? vE1=commonExpr WSP? CLOSE;
+ceilingMethodCallExpr : CEILING_WORD WSP? vE1=commonExpr WSP? CLOSE;
+
+geoDistanceMethodCallExpr : GEO_DISTANCE_WORD WSP? vE1=commonExpr WSP? COMMA WSP? vE2=commonExpr WSP? CLOSE;
+geoLengthMethodCallExpr : GEO_LENGTH_WORD WSP? vE1=commonExpr WSP? CLOSE;
+geoIntersectsMethodCallExpr : GEO_INTERSECTS_WORD WSP? vE1=commonExpr WSP? COMMA WSP? vE2=commonExpr WSP? CLOSE;
+
+isofExpr : ISOF_WORD WSP? ( vE1=commonExpr WSP? COMMA WSP? )? vNS=namespace vODI=odataIdentifier WSP? CLOSE;
+castExpr : CAST_WORD WSP? ( vE1=commonExpr WSP? COMMA WSP? )? vNS=namespace vODI=odataIdentifier WSP? 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 : json_array
+ | json_object;
+
+json_array : BEGIN_ARRAY json_value ( WSP? COMMA WSP? json_value)* END_ARRAY;
+
+json_value : jsonPrimitiv
+ | rootExpr
+ | json_object
+ | json_array;
+
+json_object : BEGIN_OBJECT
+ STRING_IN_JSON
+ WSP? COLON WSP?
+ json_value
+ END_OBJECT;
+
+
+//; JSON syntax: adapted to URI restrictions from [RFC4627]
+jsonPrimitiv : STRING_IN_JSON
+ | number_in_json
+ | TRUE
+ | FALSE
+ | 'null'
+ ;
+
+number_in_json : INT | DECIMAL;
+
+//;------------------------------------------------------------------------------
+//; 6. Names and identifiers
+//;------------------------------------------------------------------------------
+
+qualifiedtypename : namespace odataIdentifier
+ | 'collection' OPEN ( namespace odataIdentifier ) CLOSE
+ ;
+
+namespace : (odataIdentifier POINT)+;
+
+odataIdentifier : ODATAIDENTIFIER;
+
+//;------------------------------------------------------------------------------
+//; 7. Literal Data Values
+//;------------------------------------------------------------------------------
+
+
+/*TODO add missing values*/
+primitiveLiteral : nullrule
+ | booleanNonCase
+ | DECIMAL //includes double and single literals
+ | INT //includes int16/int32 and int64 literals
+ | BINARY
+ | DATE
+ | DATETIMEOFFSET
+ | DURATION
+ | GUID
+ | string
+ | TIMEOFDAY
+ | enumLit
+ | geographyCollection
+ | geographyLineString
+ | geographyMultilineString
+ | geographyMultipoint
+ | geographyMultipolygon
+ | geographyPoint
+ | geographyPolygon
+ | geometryCollection
+ | geometryLineString
+ | geometryMultilineString
+ | geometryMultipoint
+ | geometryMultipolygon
+ | geometryPoint
+ | geometryPolygon
+ ;
+
+
+nullrule : NULLVALUE;// (SQUOTE qualifiedtypename SQUOTE)?;
+booleanNonCase : BOOLEAN | TRUE | FALSE;
+string : STRING;
+
+enumLit : vNS=namespace vODI=odataIdentifier vValues=STRING;
+//enum : namespace odataIdentifier STRING;
+enumValues : vlODI+=odataIdentifier ( COMMA vlODI+=odataIdentifier )*;
+//singleEnumValue : odataIdentifier / INT;
+
+
+geographyCollection : GEOGRAPHY fullCollectionLiteral SQUOTE;
+fullCollectionLiteral : sridLiteral collectionLiteral;
+
+collectionLiteral : (COLLECTION ) OPEN geoLiteral ( COMMA geoLiteral )* CLOSE;
+
+geoLiteral : collectionLiteral
+ | lineStringLiteral
+ | multipointLiteral
+ | multilineStringLiteral
+ | multipolygonLiteral
+ | pointLiteral
+ | polygonLiteral;
+
+geographyLineString : GEOGRAPHY fullLineStringLiteral SQUOTE;
+fullLineStringLiteral : sridLiteral lineStringLiteral;
+lineStringLiteral : LINESTRING lineStringData;
+lineStringData : OPEN positionLiteral ( COMMA positionLiteral )* CLOSE;
+
+geographyMultilineString : GEOGRAPHY fullMultilineStringLiteral SQUOTE;
+fullMultilineStringLiteral : sridLiteral multilineStringLiteral;
+multilineStringLiteral : MULTILINESTRING OPEN ( lineStringData ( COMMA lineStringData )* )? CLOSE;
+
+geographyMultipoint : GEOGRAPHY fullMultipointLiteral SQUOTE;
+fullMultipointLiteral : sridLiteral multipointLiteral;
+multipointLiteral : MULTIPOINT OPEN ( pointData ( COMMA pointData )* )? CLOSE ;
+
+geographyMultipolygon : GEOGRAPHY fullmultipolygonLiteral SQUOTE;
+fullmultipolygonLiteral : sridLiteral multipolygonLiteral;
+multipolygonLiteral : MULTIPOLYGON OPEN ( polygonData ( COMMA polygonData )* )? CLOSE;
+
+geographyPoint : GEOGRAPHY fullpointLiteral SQUOTE;
+fullpointLiteral : sridLiteral pointLiteral;
+
+pointLiteral : GEO_POINT pointData;
+pointData : OPEN positionLiteral CLOSE;
+
+positionLiteral : (DECIMAL | INT ) WSP (DECIMAL | INT ); //; longitude, then latitude
+
+
+geographyPolygon : GEOGRAPHY fullPolygonLiteral SQUOTE;
+fullPolygonLiteral : sridLiteral polygonLiteral;
+polygonLiteral : POLYGON polygonData;
+polygonData : OPEN ringLiteral ( COMMA ringLiteral )* CLOSE;
+ringLiteral : OPEN positionLiteral ( COMMA positionLiteral )* CLOSE;
+
+
+geometryCollection : GEOMETRY fullCollectionLiteral SQUOTE;
+geometryLineString : GEOMETRY fullLineStringLiteral SQUOTE;
+geometryMultilineString : GEOMETRY fullMultilineStringLiteral SQUOTE;
+geometryMultipoint : GEOMETRY fullMultipointLiteral SQUOTE;
+geometryMultipolygon : GEOMETRY fullmultipolygonLiteral SQUOTE;
+geometryPoint : GEOMETRY fullpointLiteral SQUOTE;
+geometryPolygon : GEOMETRY fullPolygonLiteral SQUOTE;
+
+sridLiteral : SRID EQ INT SEMI;
+
+
+
+
+
+/*
+mode MODEd333gh;
+
+MO12E1 : 'ASD' -> mode(DEFAULT_MODE);*/
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/c49ff803/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/Parser.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/Parser.java b/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/Parser.java
new file mode 100644
index 0000000..367f027
--- /dev/null
+++ b/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/Parser.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * 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.odata4.producer.core.uri;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.BailErrorStrategy;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.atn.PredictionMode;
+import org.antlr.v4.runtime.misc.ParseCancellationException;
+import org.apache.olingo.odata4.producer.api.uri.UriInfo;
+import org.apache.olingo.odata4.producer.core.uri.antlr.UriLexer;
+import org.apache.olingo.odata4.producer.core.uri.antlr.UriParserParser;
+import org.apache.olingo.odata4.producer.core.uri.antlr.UriParserParser.OdataRelativeUriEOFContext;
+
+public class Parser {
+ public UriInfo parseUri(final String input, final UriParseTreeVisitor uriParseTreeVisitor)
+ throws UriParserException {
+
+ try {
+ OdataRelativeUriEOFContext parseTree = parseInput(input, true);
+
+ // reset visitor
+ uriParseTreeVisitor.init();
+ parseTree.accept(uriParseTreeVisitor);
+ UriInfoImpl uriInput = uriParseTreeVisitor.getUriInfo();
+
+ return uriInput;
+
+ } catch (ParseCancellationException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof UriParserException) {
+ throw (UriParserException) cause;
+ }
+ }
+ throw new UriParserSyntaxException("unknown syntax error");
+ }
+
+ private OdataRelativeUriEOFContext parseInput(final String input, boolean onResource)
+ throws UriParserSyntaxException {
+ UriParserParser parser = null;
+ UriLexer lexer = null;
+ OdataRelativeUriEOFContext ret = null;
+
+ // Use 2 stage approach to improve performance
+ // see https://github.com/antlr/antlr4/issues/192
+
+ // stage = 1
+ try {
+ // create parser
+ lexer = new UriLexer(new ANTLRInputStream(input));
+ parser = new UriParserParser(new CommonTokenStream(lexer));
+
+ // Set error strategy
+ addStage1ErrorStategy(parser);
+
+ // Set error collector
+ addStage1ErrorListener(parser);
+
+ // user the faster LL parsing
+ parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
+
+ // parse
+ ret = parser.odataRelativeUriEOF();
+
+ } catch (ParseCancellationException hardException) {
+ // stage = 2
+ try {
+
+ // create parser
+ lexer = new UriLexer(new ANTLRInputStream(input));
+ parser = new UriParserParser(new CommonTokenStream(lexer));
+
+ // Set error strategy
+ addStage2ErrorStategy(parser);
+
+ // Set error collector
+ addStage2ErrorListener(parser);
+
+ // Use the slower SLL parsing
+ parser.getInterpreter().setPredictionMode(PredictionMode.LL);
+
+ // parse
+ ret = parser.odataRelativeUriEOF();
+
+ } catch (Exception weakException) {
+ throw new UriParserSyntaxException("Error in syntax", weakException);
+
+ // exceptionOnStage = 2;
+ }
+ } catch (Exception hardException) {
+ throw new UriParserSyntaxException("Error in syntax", hardException);
+ }
+
+ return ret;
+ }
+
+ protected void addStage1ErrorStategy(UriParserParser parser) {
+ // Throw exception at first syntax error
+ parser.setErrorHandler(new BailErrorStrategy());
+
+ }
+
+ protected void addStage2ErrorStategy(UriParserParser parser) {
+ // Throw exception at first syntax error
+ parser.setErrorHandler(new BailErrorStrategy());
+ }
+
+ protected void addStage1ErrorListener(UriParserParser parser) {
+ // No error logging to System.out or System.err, only exceptions used (depending on ErrorStrategy)
+ parser.removeErrorListeners();
+ }
+
+ protected void addStage2ErrorListener(UriParserParser parser) {
+ // No error logging to System.out or System.err, only exceptions used (depending on ErrorStrategy)
+ parser.removeErrorListeners();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/c49ff803/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/UriInfoImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/UriInfoImpl.java b/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/UriInfoImpl.java
new file mode 100644
index 0000000..e4797c4
--- /dev/null
+++ b/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/UriInfoImpl.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * 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.odata4.producer.core.uri;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.olingo.odata4.commons.api.edm.EdmEntityType;
+import org.apache.olingo.odata4.producer.api.uri.UriInfo;
+import org.apache.olingo.odata4.producer.api.uri.UriInfoAll;
+import org.apache.olingo.odata4.producer.api.uri.UriInfoBatch;
+import org.apache.olingo.odata4.producer.api.uri.UriInfoCrossjoin;
+import org.apache.olingo.odata4.producer.api.uri.UriInfoEntityId;
+import org.apache.olingo.odata4.producer.api.uri.UriInfoKind;
+import org.apache.olingo.odata4.producer.api.uri.UriInfoMetadata;
+import org.apache.olingo.odata4.producer.api.uri.UriInfoResource;
+import org.apache.olingo.odata4.producer.api.uri.UriInfoService;
+import org.apache.olingo.odata4.producer.api.uri.UriResource;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.CustomQueryOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.FilterOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.FormatOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.IdOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.InlineCountOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.OrderByOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.SearchOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.SelectOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.SkipOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.SkipTokenOption;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.SupportedQueryOptions;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.TopOption;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.CustomQueryOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.ExpandOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.FilterOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.FormatOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.IdOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.InlineCountOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.OrderByOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.QueryOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.SearchOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.SelectOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.SkipOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.SkipTokenOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.SystemQueryOptionImpl;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.TopOptionImpl;
+
+public class UriInfoImpl implements UriInfo {
+
+ private UriInfoKind kind;
+
+ private List<String> entitySetNames = new ArrayList<String>(); // for $entity
+ private EdmEntityType entityTypeCast; // for $entity
+
+ // Query options
+ private List<CustomQueryOptionImpl> customQueryOptions = new ArrayList<CustomQueryOptionImpl>();
+ private ExpandOptionImpl expandOption;
+ private FilterOptionImpl filterOption;
+ private FormatOptionImpl formatOption;
+ private IdOption idOption;
+ private InlineCountOptionImpl inlineCountOption;
+ private OrderByOptionImpl orderByOption;
+ private SearchOptionImpl searchOption;
+ private SelectOptionImpl selectOption;
+ private SkipOptionImpl skipOption;
+ private SkipTokenOptionImpl skipTokenOption;
+ private TopOptionImpl topOption;
+
+ private String fragment;
+
+ private UriResource lastResourcePart;
+ private List<UriResource> pathParts = new ArrayList<UriResource>();
+
+ @Override
+ public UriInfoAll asUriInfoAll() {
+ return this;
+ }
+
+ @Override
+ public UriInfoBatch asUriInfoBatch() {
+ return this;
+ }
+
+ @Override
+ public UriInfoCrossjoin asUriInfoCrossjoin() {
+ return this;
+ }
+
+ @Override
+ public UriInfoEntityId asUriInfoEntityId() {
+ return this;
+ }
+
+ @Override
+ public UriInfoMetadata asUriInfoMetadata() {
+ return this;
+ }
+
+ @Override
+ public UriInfoResource asUriInfoResource() {
+ return this;
+ }
+
+ @Override
+ public List<String> getEntitySetNames() {
+ return Collections.unmodifiableList(entitySetNames);
+ }
+
+ public void addEntitySetName(final String entitySet) {
+ entitySetNames.add(entitySet);
+ }
+
+ @Override
+ public List<UriResource> getUriResourceParts() {
+ List<UriResource> returnList = new ArrayList<UriResource>();
+ for (UriResource item : pathParts) {
+ returnList.add(item);
+ }
+ return Collections.unmodifiableList(returnList);
+ }
+
+ public UriInfoImpl addResourcePart(final UriResourceImpl uriPathInfo) {
+ pathParts.add(uriPathInfo);
+ lastResourcePart = uriPathInfo;
+ return this;
+ }
+
+ @Override
+ public List<CustomQueryOption> getCustomQueryOptions() {
+ List<CustomQueryOption> retList = new ArrayList<CustomQueryOption>();
+ for (CustomQueryOptionImpl item : customQueryOptions) {
+ retList.add(item);
+ }
+ return retList;
+ }
+
+ @Override
+ public EdmEntityType getEntityTypeCast() {
+ return entityTypeCast;
+ }
+
+ public UriInfoImpl setEntityTypeCast(final EdmEntityType type) {
+ entityTypeCast = type;
+ return this;
+ }
+
+ @Override
+ public ExpandOption getExpandOption() {
+ return expandOption;
+ }
+
+ @Override
+ public FilterOption getFilterOption() {
+ return filterOption;
+ }
+
+ @Override
+ public FormatOption getFormatOption() {
+ return formatOption;
+ }
+
+ @Override
+ public IdOption getIdOption() {
+ return idOption;
+ }
+
+ @Override
+ public InlineCountOption getInlineCountOption() {
+ return inlineCountOption;
+ }
+
+ @Override
+ public UriInfoKind getKind() {
+ return kind;
+ }
+
+ public UriInfoImpl setKind(final UriInfoKind kind) {
+ this.kind = kind;
+ return this;
+ }
+
+ public UriResource getLastResourcePart() {
+ return lastResourcePart;
+ }
+
+ @Override
+ public OrderByOption getOrderByOption() {
+ return orderByOption;
+ }
+
+ @Override
+ public SearchOption getSearchOption() {
+
+ return searchOption;
+ }
+
+ @Override
+ public SelectOption getSelectOption() {
+ return selectOption;
+ }
+
+ @Override
+ public SkipOption getSkipOption() {
+ return skipOption;
+ }
+
+ @Override
+ public SkipTokenOption getSkipTokenOption() {
+ return skipTokenOption;
+ }
+
+ @Override
+ public TopOption getTopOption() {
+ return topOption;
+ }
+
+
+ public UriInfoImpl setQueryOptions(final List<QueryOptionImpl> list) {
+
+ for (QueryOptionImpl item : list) {
+ if (item instanceof SystemQueryOptionImpl) {
+ setSystemQueryOption((SystemQueryOptionImpl)item);
+ } else if (item instanceof CustomQueryOptionImpl) {
+ customQueryOptions.add((CustomQueryOptionImpl) item);
+ }
+ }
+ return this;
+ }
+
+ public UriInfoImpl setSystemQueryOption(SystemQueryOptionImpl systemOption) {
+
+ if (systemOption.getKind() == SupportedQueryOptions.EXPAND) {
+ expandOption = (ExpandOptionImpl) systemOption;
+ } else if (systemOption.getKind() == SupportedQueryOptions.FILTER) {
+ filterOption = (FilterOptionImpl) systemOption;
+ } else if (systemOption.getKind() == SupportedQueryOptions.FORMAT) {
+ formatOption = (FormatOptionImpl) systemOption;
+ } else if (systemOption.getKind() == SupportedQueryOptions.ID) {
+ idOption = (IdOptionImpl) systemOption;
+ } else if (systemOption.getKind() == SupportedQueryOptions.INLINECOUNT) {
+ inlineCountOption = (InlineCountOptionImpl) systemOption;
+ } else if (systemOption.getKind() == SupportedQueryOptions.ORDERBY) {
+ orderByOption = (OrderByOptionImpl) systemOption;
+ } else if (systemOption.getKind() == SupportedQueryOptions.SEARCH) {
+ searchOption = (SearchOptionImpl) systemOption;
+ } else if (systemOption.getKind() == SupportedQueryOptions.SELECT) {
+ selectOption = (SelectOptionImpl) systemOption;
+ } else if (systemOption.getKind() == SupportedQueryOptions.SKIP) {
+ skipOption = (SkipOptionImpl) systemOption;
+ } else if (systemOption.getKind() == SupportedQueryOptions.SKIPTOKEN) {
+ skipTokenOption = (SkipTokenOptionImpl) systemOption;
+ } else if (systemOption.getKind() == SupportedQueryOptions.TOP) {
+ topOption = (TopOptionImpl) systemOption;
+ }
+ return this;
+ }
+
+ @Override
+ public UriInfoService asUriInfoService() {
+ return this;
+ }
+
+
+ public String getFragment() {
+ return fragment;
+ }
+
+ public UriInfoImpl setFragment(String fragment) {
+ this.fragment = fragment;
+ return this;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/c49ff803/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/UriParameterImpl.java
----------------------------------------------------------------------
diff --git a/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/UriParameterImpl.java b/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/UriParameterImpl.java
new file mode 100644
index 0000000..67034f4
--- /dev/null
+++ b/odata4-lib/odata4-server-core/src/main/java/org/apache/olingo/odata4/producer/core/uri/UriParameterImpl.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ *
+ * 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.odata4.producer.core.uri;
+
+import org.apache.olingo.odata4.producer.api.uri.UriParameter;
+import org.apache.olingo.odata4.producer.api.uri.queryoption.expression.Expression;
+import org.apache.olingo.odata4.producer.core.uri.queryoption.expression.ExpressionImpl;
+
+public class UriParameterImpl implements UriParameter {
+ private String name;
+ private String text;
+ private String alias;
+ private Expression expression;
+ private String referencedProperty;
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ public UriParameterImpl setName(final String name) {
+ this.name = name;
+ return this;
+ }
+
+ @Override
+ public String getAlias() {
+ return alias;
+ }
+
+ public UriParameterImpl setAlias(final String alias) {
+ this.alias = alias;
+ return this;
+ }
+
+ @Override
+ public String getText() {
+ return text;
+ }
+
+ public UriParameterImpl setText(final String text) {
+ this.text = text;
+ return this;
+ }
+
+ @Override
+ public Expression getExression() {
+ return expression;
+ }
+
+ public UriParameterImpl setExpression(final ExpressionImpl expression) {
+ this.expression = expression;
+ return this;
+ }
+
+ @Override
+ public String getRefencedProperty() {
+ return this.referencedProperty;
+ }
+
+ public UriParameterImpl setRefencedProperty(String referencedProperty) {
+ this.referencedProperty = referencedProperty;
+ return this;
+ }
+
+}