You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2016/01/25 21:31:01 UTC
[21/51] [abbrv] olingo-odata4 git commit: [OLINGO-834] $expand parser
in Java + clean-up
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8925274c/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
deleted file mode 100644
index 1bab218..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
+++ /dev/null
@@ -1,2313 +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.server.core.uri.parser;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.antlr.v4.runtime.misc.NotNull;
-import org.antlr.v4.runtime.misc.ParseCancellationException;
-import org.antlr.v4.runtime.tree.ParseTree;
-import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmAction;
-import org.apache.olingo.commons.api.edm.EdmActionImport;
-import org.apache.olingo.commons.api.edm.EdmComplexType;
-import org.apache.olingo.commons.api.edm.EdmElement;
-import org.apache.olingo.commons.api.edm.EdmEntityContainer;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
-import org.apache.olingo.commons.api.edm.EdmEnumType;
-import org.apache.olingo.commons.api.edm.EdmFunction;
-import org.apache.olingo.commons.api.edm.EdmFunctionImport;
-import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
-import org.apache.olingo.commons.api.edm.EdmProperty;
-import org.apache.olingo.commons.api.edm.EdmReturnType;
-import org.apache.olingo.commons.api.edm.EdmSingleton;
-import org.apache.olingo.commons.api.edm.EdmStructuredType;
-import org.apache.olingo.commons.api.edm.EdmType;
-import org.apache.olingo.commons.api.edm.FullQualifiedName;
-import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
-import org.apache.olingo.commons.api.ex.ODataRuntimeException;
-import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
-import org.apache.olingo.server.api.uri.UriInfoKind;
-import org.apache.olingo.server.api.uri.UriInfoResource;
-import org.apache.olingo.server.api.uri.UriParameter;
-import org.apache.olingo.server.api.uri.UriResource;
-import org.apache.olingo.server.api.uri.UriResourceEntitySet;
-import org.apache.olingo.server.api.uri.UriResourceFunction;
-import org.apache.olingo.server.api.uri.UriResourceNavigation;
-import org.apache.olingo.server.api.uri.UriResourcePartTyped;
-import org.apache.olingo.server.api.uri.UriResourceRoot;
-import org.apache.olingo.server.api.uri.queryoption.SelectItem;
-import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
-import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
-import org.apache.olingo.server.api.uri.queryoption.expression.MethodKind;
-import org.apache.olingo.server.api.uri.queryoption.expression.UnaryOperatorKind;
-import org.apache.olingo.server.core.uri.UriInfoImpl;
-import org.apache.olingo.server.core.uri.UriParameterImpl;
-import org.apache.olingo.server.core.uri.UriResourceActionImpl;
-import org.apache.olingo.server.core.uri.UriResourceComplexPropertyImpl;
-import org.apache.olingo.server.core.uri.UriResourceCountImpl;
-import org.apache.olingo.server.core.uri.UriResourceEntitySetImpl;
-import org.apache.olingo.server.core.uri.UriResourceFunctionImpl;
-import org.apache.olingo.server.core.uri.UriResourceImpl;
-import org.apache.olingo.server.core.uri.UriResourceItImpl;
-import org.apache.olingo.server.core.uri.UriResourceLambdaAllImpl;
-import org.apache.olingo.server.core.uri.UriResourceLambdaAnyImpl;
-import org.apache.olingo.server.core.uri.UriResourceLambdaVarImpl;
-import org.apache.olingo.server.core.uri.UriResourceNavigationPropertyImpl;
-import org.apache.olingo.server.core.uri.UriResourcePrimitivePropertyImpl;
-import org.apache.olingo.server.core.uri.UriResourceRefImpl;
-import org.apache.olingo.server.core.uri.UriResourceRootImpl;
-import org.apache.olingo.server.core.uri.UriResourceSingletonImpl;
-import org.apache.olingo.server.core.uri.UriResourceStartingTypeFilterImpl;
-import org.apache.olingo.server.core.uri.UriResourceTypedImpl;
-import org.apache.olingo.server.core.uri.UriResourceValueImpl;
-import org.apache.olingo.server.core.uri.UriResourceWithKeysImpl;
-import org.apache.olingo.server.core.uri.antlr.UriLexer;
-import org.apache.olingo.server.core.uri.antlr.UriParserBaseVisitor;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AllEOFContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AllExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltAddContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltAllContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltAndContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltAnyContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltComparismContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltEqualityContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltHasContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltMultContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltOrContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.AnyExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ArrayOrObjectContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.BinaryLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.BooleanNonCaseLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.CastExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.CeilingMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ConcatMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ConstSegmentContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ContainsMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.DateLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.DateMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.DatetimeoffsetLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.DayMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.DecimalLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.DurationLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.EndsWithMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.EntityEOFContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.EnumLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandCountOptionContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandItemContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandItemsContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandItemsEOFContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandOptionContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandPathContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandPathExtensionContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandRefOptionContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.FilterContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.FilterExpressionEOFContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.FloorMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.FractionalsecondsMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.GeoDistanceMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.GeoIntersectsMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.GeoLengthMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.GuidLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.HourMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.IndexOfMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.InlinecountContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.IntLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.IsofExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.LengthMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.LevelsContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.MaxDateTimeMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.MemberExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.MetadataEOFContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.MinDateTimeMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.MinuteMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.MonthMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.NameValueOptListContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.NameValuePairContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.NamespaceContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.NaninfinityLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.NowMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.NullruleLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.OrderByContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.OrderByEOFContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.OrderByItemContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.OrderListContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.PathSegmentContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.PathSegmentsContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.PrimitiveLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.QueryOptionContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.QueryOptionsContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.RootExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.RoundMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.SearchSpecialTokenContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.SecondMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.SelectContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.SelectEOFContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.SelectItemContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.SelectSegmentContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.SkipContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.SkiptokenContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.StartsWithMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.StringLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.SubstringMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.TimeMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.TimeofdayLiteralContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ToLowerMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.ToUpperMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.TopContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.TotalOffsetMinutesMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.TotalsecondsMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.TrimMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.YearMethodCallExprContext;
-import org.apache.olingo.server.core.uri.parser.UriParserSemanticException.MessageKeys;
-import org.apache.olingo.server.core.uri.queryoption.CountOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.ExpandItemImpl;
-import org.apache.olingo.server.core.uri.queryoption.ExpandOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.LevelsOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.OrderByItemImpl;
-import org.apache.olingo.server.core.uri.queryoption.OrderByOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.QueryOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.SelectItemImpl;
-import org.apache.olingo.server.core.uri.queryoption.SelectOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.SkipOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.SkipTokenOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.SystemQueryOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.TopOptionImpl;
-import org.apache.olingo.server.core.uri.queryoption.expression.AliasImpl;
-import org.apache.olingo.server.core.uri.queryoption.expression.BinaryImpl;
-import org.apache.olingo.server.core.uri.queryoption.expression.EnumerationImpl;
-import org.apache.olingo.server.core.uri.queryoption.expression.LiteralImpl;
-import org.apache.olingo.server.core.uri.queryoption.expression.MemberImpl;
-import org.apache.olingo.server.core.uri.queryoption.expression.MethodImpl;
-import org.apache.olingo.server.core.uri.queryoption.expression.TypeLiteralImpl;
-import org.apache.olingo.server.core.uri.queryoption.expression.UnaryImpl;
-
-/**
- * Converts the URI parse tree as generated by ANTLR into an internal representation
- * suitable to give to an application.
- * While converting the tree is only validated against the EDM if necessary.
- * <br>
- * Attention:
- * <ul>
- * <li>This UriVisitor is at somes point more lax than the original ABNF.</li>
- * <li>It is more tolerable against additional white spaces.</li>
- * </ul>
- * Currently not supported are
- * <ul>
- * <li>parsing the context of $metadata</li>
- * <li>parsing $search</li>
- * </ul>
- */
-public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
-
- public UriContext context = null;
-
- public Edm edm;
-
- public EdmEntityContainer edmEntityContainer;
-
- // --- class ---
- public UriParseTreeVisitor(final Edm edm, final UriContext context) {
- this.edm = edm;
- this.context = context;
- edmEntityContainer = edm.getEntityContainer();
- }
-
- @Override
- protected Object aggregateResult(final Object aggregate, final Object nextResult) {
- if (aggregate != null) {
- return aggregate;
- } else {
- return nextResult;
- }
- }
-
- private FullQualifiedName getFullNameFromContext(final NamespaceContext vNS, final String odi) {
- String namespace = vNS.getText();
- namespace = namespace.substring(0, namespace.length() - 1); // vNS contains a trailing point that has to be removed
- return new FullQualifiedName(namespace, odi);
- }
-
- private UriContext.LambdaVariable getLambdaVar(final String odi) {
- for (UriContext.LambdaVariable item : context.allowedLambdaVariables) {
- if (item.name.equals(odi)) {
- return item;
- }
- }
- return null;
- }
-
- public UriResourceTypedImpl readResourcePathSegment(final PathSegmentContext ctx) {
-
- final boolean checkFirst =
- context.contextUriInfo.getLastResourcePart() == null
- || context.contextUriInfo.getLastResourcePart() instanceof UriResourceRootImpl;
-
- String odi = ctx.vODI.getText();
-
- boolean searchInContainer = true;
- // validate if context type and according property is available
- // otherwise search in container for first element
- if (checkFirst && ctx.vNS == null && !context.contextTypes.isEmpty()) {
- EdmType sourceType = context.contextTypes.peek();
- if (sourceType instanceof EdmStructuredType) {
- EdmStructuredType str = (EdmStructuredType) sourceType;
- EdmElement property = str.getProperty(odi);
- if (property != null) {
- searchInContainer = false;
- }
- }
- }
-
- if (searchInContainer) {
- final List<UriResource> parts = context.contextUriInfo.getUriResourceParts();
- // check EntitySet
- EdmEntitySet edmEntitySet = edmEntityContainer.getEntitySet(odi);
- if (edmEntitySet != null
- && (parts.isEmpty() || !(parts.get(0) instanceof UriResourcePartTyped)
- || parts.get(0) instanceof UriResourceRoot)) {
- ensureNamespaceIsNull(ctx.vNS);
- context.contextUriInfo.addResourcePart(
- new UriResourceEntitySetImpl(edmEntitySet));
- return null;
- }
-
- // check Singleton
- EdmSingleton edmSingleton = edmEntityContainer.getSingleton(odi);
- if (edmSingleton != null
- && (parts.isEmpty() || !(parts.get(0) instanceof UriResourcePartTyped)
- || parts.get(0) instanceof UriResourceRoot)) {
- ensureNamespaceIsNull(ctx.vNS);
- context.contextUriInfo.addResourcePart(
- new UriResourceSingletonImpl(edmSingleton));
- return null;
- }
-
- // check ActionImport
- EdmActionImport edmActionImport = edmEntityContainer.getActionImport(odi);
- if (edmActionImport != null
- && (parts.isEmpty() || !(parts.get(0) instanceof UriResourcePartTyped)
- || parts.get(0) instanceof UriResourceRoot)) {
- ensureNamespaceIsNull(ctx.vNS);
- context.contextUriInfo.addResourcePart(
- new UriResourceActionImpl(edmActionImport));
- return null;
- }
-
- // check FunctionImport
- EdmFunctionImport edmFunctionImport = edmEntityContainer.getFunctionImport(odi);
-
- if(edmFunctionImport != null && context.contextReadingQueryPart) {
- throw wrap(new UriParserSemanticException("Function Imports are not allowed in $filter or $orderby",
- UriParserSemanticException.MessageKeys.FUNCTION_IMPORT_NOT_ALLOWED, odi));
- }
-
- if (edmFunctionImport != null
- && (parts.isEmpty() || !(parts.get(0) instanceof UriResourcePartTyped)
- || parts.get(0) instanceof UriResourceRoot)) {
-
- // read the URI parameters
- if (ctx.vlNVO.isEmpty()) {
- throw wrap(new UriParserSyntaxException(
- "Function imports must have a (possibly empty) parameter list written in parentheses",
- UriParserSyntaxException.MessageKeys.SYNTAX));
- }
- context.contextReadingFunctionParameters = true;
- @SuppressWarnings("unchecked")
- List<UriParameter> parameters = (List<UriParameter>) ctx.vlNVO.get(0).accept(this);
- context.contextReadingFunctionParameters = false;
-
- // mark parameters as consumed
- ctx.vlNVO.remove(0);
-
- // collect parameter names
- List<String> names = new ArrayList<String>();
- for (UriParameter item : parameters) {
- names.add(item.getName());
- }
-
- // get function from function import
- EdmFunction function = edmFunctionImport.getUnboundFunction(names);
- if (function == null) {
- StringBuilder tmp = new StringBuilder();
- for (String name : names) {
- tmp.append((tmp.length() != 0 ? "," : "")).append(name);
- }
- throw wrap(new UriParserSemanticException("Function of functionimport '" + edmFunctionImport.getName()
- + "' with parameters [" + tmp.toString() + "] not found",
- UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND, edmFunctionImport.getName(), tmp.toString()));
- }
-
- ensureNamespaceIsNull(ctx.vNS);
- UriResourceFunctionImpl uriResource = new UriResourceFunctionImpl(edmFunctionImport,
- edmFunctionImport.getUnboundFunction(names),
- parameters);
- context.contextUriInfo.addResourcePart(uriResource);
- return null;
- }
- }
-
- EdmType sourceType;
- boolean sourceIsCollection = false;
- final UriResource lastResourcePart = context.contextUriInfo.getLastResourcePart();
-
- if (lastResourcePart == null) {
- if (context.contextTypes.isEmpty()) {
- if (checkFirst && ctx.vNS == null) {
- throw wrap(new UriParserSemanticException(
- "Cannot find EntitySet, Singleton, ActionImport or FunctionImport with name '" + odi + "'.",
- UriParserSemanticException.MessageKeys.RESOURCE_NOT_FOUND, odi));
- }
- throw wrap(new UriParserSemanticException(
- "Resource part '" + odi + "' can only applied on typed resource parts",
- UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS, odi));
- }
- sourceType = context.contextTypes.peek();
- sourceIsCollection = context.isCollection;
- } else if (lastResourcePart instanceof UriResourcePartTyped) {
- sourceType = ParserHelper.getTypeInformation((UriResourcePartTyped) lastResourcePart);
- sourceIsCollection = ((UriResourcePartTyped) lastResourcePart).isCollection();
- } else {
- throw wrap(new UriParserSemanticException(
- "Resource part '" + odi + "' can only be applied on typed resource parts.",
- UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS, odi));
- }
-
- if (ctx.vNS == null) { // without namespace
-
- // first check for lambda variable because a newly add property should not shadow a long used lambda variable
- UriContext.LambdaVariable lVar = getLambdaVar(odi);
- if (lVar != null) {
- UriResourceLambdaVarImpl lambdaResource = new UriResourceLambdaVarImpl(lVar.name, lVar.type);
- context.contextUriInfo.addResourcePart(lambdaResource);
- return null;
- }
-
- if (!(sourceType instanceof EdmStructuredType)) {
- throw wrap(new UriParserSemanticException(
- "Cannot parse '" + odi + "'; previous path segment is not a structural type.",
- UriParserSemanticException.MessageKeys.RESOURCE_PART_MUST_BE_PRECEDED_BY_STRUCTURAL_TYPE, odi));
- }
-
- if ((ctx.depth() <= 2 // path evaluation for the resource path
- || lastResourcePart instanceof UriResourceTypedImpl
- || lastResourcePart instanceof UriResourceNavigationPropertyImpl)
- && sourceIsCollection) {
- throw wrap(new UriParserSemanticException("Property '" + odi + "' is not allowed after collection.",
- UriParserSemanticException.MessageKeys.PROPERTY_AFTER_COLLECTION, odi));
- }
-
- EdmStructuredType structType = (EdmStructuredType) sourceType;
-
- EdmElement property = structType.getProperty(odi);
- if (property == null) {
- throw wrap(new UriParserSemanticException("Property '" + odi + "' not found in type '"
- + structType.getFullQualifiedName().getFullQualifiedNameAsString() + "'",
- ctx.depth() > 2 ? // path evaluation inside an expression or for the resource path?
- UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE
- : UriParserSemanticException.MessageKeys.PROPERTY_NOT_IN_TYPE,
- structType.getFullQualifiedName().getFullQualifiedNameAsString(), odi));
- }
-
- if (property instanceof EdmProperty) {
- if (((EdmProperty) property).isPrimitive()
- || property.getType().getKind() == EdmTypeKind.ENUM
- || property.getType().getKind() == EdmTypeKind.DEFINITION) {
- // create simple property
- UriResourcePrimitivePropertyImpl simpleResource =
- new UriResourcePrimitivePropertyImpl((EdmProperty) property);
- context.contextUriInfo.addResourcePart(simpleResource);
- return null;
- } else {
- // create complex property
- UriResourceComplexPropertyImpl complexResource = new UriResourceComplexPropertyImpl((EdmProperty) property);
- context.contextUriInfo.addResourcePart(complexResource);
- return null;
- }
- } else if (property instanceof EdmNavigationProperty) {
- // create navigation property
- if (context.contextVisitExpandResourcePath && ctx.vlNVO.size() > 0) {
- throw wrap(new UriParserSemanticException(
- "Navigation properties in expand system query options must not be followed by a key.",
- UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED));
- }
-
- UriResourceNavigationPropertyImpl navigationResource =
- new UriResourceNavigationPropertyImpl((EdmNavigationProperty) property);
- context.contextUriInfo.addResourcePart(navigationResource);
- return null;
- } else {
- throw wrap(new UriParserSemanticException("Unkown type for property '" + property + "'",
- UriParserSemanticException.MessageKeys.UNKNOWN_PROPERTY_TYPE, property.getName()));
- }
-
- } else { // with namespace
-
- FullQualifiedName fullFilterName = getFullNameFromContext(ctx.vNS, odi);
-
- // EdmType lastType = getLastType(lastTyped);
- if (sourceType instanceof EdmEntityType) {
-
- EdmEntityType filterEntityType = edm.getEntityType(fullFilterName);
- if (filterEntityType != null) {
- // is entity type cast
- if (!(filterEntityType.compatibleTo(sourceType))) {
- throw wrap(new UriParserSemanticException(
- "Entity typefilter not compatible to previous path segment: " + fullFilterName.toString(),
- UriParserSemanticException.MessageKeys.INCOMPATIBLE_TYPE_FILTER, fullFilterName.toString()));
- }
-
- if (lastResourcePart == null) {
- // this may be the case if a member expression within a filter starts with a typeCast
- UriResourceStartingTypeFilterImpl uriResource = new UriResourceStartingTypeFilterImpl(
- filterEntityType,
- sourceIsCollection);
- if (sourceIsCollection) {
- uriResource.setCollectionTypeFilter(filterEntityType);
- } else {
- uriResource.setEntryTypeFilter(filterEntityType);
- }
- context.contextUriInfo.addResourcePart(uriResource);
- return null;
- } else {
-
- // check if last segment may contain key properties
- if (lastResourcePart instanceof UriResourceWithKeysImpl) {
- UriResourceWithKeysImpl lastPartWithKeys = (UriResourceWithKeysImpl) lastResourcePart;
-
- if (!lastPartWithKeys.isCollection()) {
- if (lastPartWithKeys.getTypeFilterOnEntry() != null) {
- throw wrap(new UriParserSemanticException("Entry typefilters are not chainable, used '"
- + getName(filterEntityType) + "' behind '"
- + getName(lastPartWithKeys.getTypeFilterOnEntry()) + "'",
- UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE,
- getName(lastPartWithKeys.getTypeFilterOnEntry()), getName(filterEntityType)));
- }
- lastPartWithKeys.setEntryTypeFilter(filterEntityType);
- return null;
- } else {
- if (lastPartWithKeys.getTypeFilterOnCollection() != null) {
- throw wrap(new UriParserSemanticException("Collection typefilters are not chainable, used '"
- + getName(filterEntityType) + "' behind '"
- + getName(lastPartWithKeys.getTypeFilterOnCollection()) + "'",
- UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE,
- getName(lastPartWithKeys.getTypeFilterOnCollection()), getName(filterEntityType)));
- }
- lastPartWithKeys.setCollectionTypeFilter(filterEntityType);
- return null;
- }
- } else if (lastResourcePart instanceof UriResourceTypedImpl) {
- UriResourceTypedImpl lastPartTyped = (UriResourceTypedImpl) lastResourcePart;
- if (lastPartTyped.getTypeFilter() != null) {
- throw wrap(new UriParserSemanticException("Typefilters are not chainable, used '"
- + getName(filterEntityType) + "' behind '"
- + getName(lastPartTyped.getTypeFilter()) + "'",
- UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE,
- getName(lastPartTyped.getTypeFilter()), getName(filterEntityType)));
- }
-
- lastPartTyped.setTypeFilter(filterEntityType);
- return null;
- } else {
- throw wrap(new UriParserSemanticException("Path segment before '" + getName(filterEntityType)
- + "' not typed",
- UriParserSemanticException.MessageKeys.PREVIOUS_PART_NOT_TYPED, getName(filterEntityType)));
- }
- }
- }
-
- } else if (sourceType instanceof EdmComplexType) {
-
- EdmComplexType filterComplexType = edm.getComplexType(fullFilterName);
-
- if (filterComplexType != null) {
-
- // is complex type cast
- if (!(filterComplexType.compatibleTo(sourceType))) {
- throw wrap(new UriParserSemanticException(
- "Complex typefilter '" + getName(sourceType) + "'not compatible type of previous path segment '"
- + getName(filterComplexType) + "'",
- UriParserSemanticException.MessageKeys.INCOMPATIBLE_TYPE_FILTER, getName(sourceType)));
- }
-
- // is simple complex type cast
- if (lastResourcePart == null) {
- // this may be the case if a member expression within a filter starts with a typeCast
- UriResourceStartingTypeFilterImpl uriResource =
- new UriResourceStartingTypeFilterImpl(filterComplexType, sourceIsCollection);
-
- if (sourceIsCollection) {
- uriResource.setCollectionTypeFilter(filterComplexType);
- } else {
- uriResource.setEntryTypeFilter(filterComplexType);
- }
- context.contextUriInfo.addResourcePart(uriResource);
- return null;
- } else {
- if (lastResourcePart instanceof UriResourceWithKeysImpl) {
- // e.g. in case of function returning complex data or a list of complex data
- UriResourceWithKeysImpl lastPartWithKeys = (UriResourceWithKeysImpl) lastResourcePart;
-
- if (!lastPartWithKeys.isCollection()) {
- if (lastPartWithKeys.getTypeFilterOnEntry() != null) {
- throw wrap(new UriParserSemanticException("Entry typefilters are not chainable, used '"
- + getName(filterComplexType) + "' behind '"
- + getName(lastPartWithKeys.getTypeFilterOnEntry()) + "'",
- UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE,
- getName(lastPartWithKeys.getTypeFilterOnEntry()), getName(filterComplexType)));
- }
- lastPartWithKeys.setEntryTypeFilter(filterComplexType);
- return null;
- } else {
- if (lastPartWithKeys.getTypeFilterOnCollection() != null) {
- throw wrap(new UriParserSemanticException("Collection typefilters are not chainable, used '"
- + getName(filterComplexType) + "' behind '"
- + getName(lastPartWithKeys.getTypeFilterOnCollection()) + "'",
- UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE,
- getName(lastPartWithKeys.getTypeFilterOnCollection()), getName(filterComplexType)));
- }
- lastPartWithKeys.setCollectionTypeFilter(filterComplexType);
- return null;
- }
-
- } else if (lastResourcePart instanceof UriResourceTypedImpl) {
- UriResourceTypedImpl lastPartTyped = (UriResourceTypedImpl) lastResourcePart;
- if (lastPartTyped.getTypeFilter() != null) {
- throw wrap(new UriParserSemanticException("Typefilters are not chainable, used '"
- + getName(filterComplexType) + "' behind '"
- + getName(lastPartTyped.getTypeFilter()) + "'",
- UriParserSemanticException.MessageKeys.TYPE_FILTER_NOT_CHAINABLE,
- getName(lastPartTyped.getTypeFilter()), getName(filterComplexType)));
- }
-
- lastPartTyped.setTypeFilter(filterComplexType);
- return null;
- } else {
- throw wrap(new UriParserSemanticException("Path segment before '" + getName(filterComplexType)
- + "' not typed",
- UriParserSemanticException.MessageKeys.PREVIOUS_PART_NOT_TYPED, getName(filterComplexType)));
- }
- }
- }
- }
-
- FullQualifiedName fullBindingTypeName = sourceType.getFullQualifiedName();
-
- // check for action
- EdmAction action = edm.getBoundAction(fullFilterName, fullBindingTypeName, sourceIsCollection);
- if (action != null) {
- UriResourceActionImpl pathInfoAction = new UriResourceActionImpl(action);
- context.contextUriInfo.addResourcePart(pathInfoAction);
- return null;
- }
-
- // do a check for bound functions (which requires a parameter list)
- if (ctx.vlNVO.size() == 0) {
- throw wrap(new UriParserSemanticException("Unknown type for type cast " + fullFilterName.toString()
- + " not found", UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, fullFilterName.toString()));
- }
-
- context.contextReadingFunctionParameters = true;
- @SuppressWarnings("unchecked")
- List<UriParameter> parameters = (List<UriParameter>) ctx.vlNVO.get(0).accept(this);
- context.contextReadingFunctionParameters = false;
-
- // get names of function parameters
- List<String> names = new ArrayList<String>();
- for (UriParameter item : parameters) {
- names.add(item.getName());
- }
-
- EdmFunction function = edm.getBoundFunction(fullFilterName, fullBindingTypeName, sourceIsCollection, names);
-
- if (function != null) {
- UriResourceFunctionImpl pathInfoFunction = new UriResourceFunctionImpl(null, function, parameters);
- context.contextUriInfo.addResourcePart(pathInfoFunction);
-
- // mark parameters as consumed
- ctx.vlNVO.remove(0);
- return null;
- }
-
- // check for unbound function in the $filter case ( where the previous resource segment is a $it)
- function = edm.getUnboundFunction(fullFilterName, names);
-
- if (function != null) {
- UriResourceFunctionImpl pathInfoFunction = new UriResourceFunctionImpl(null, function, parameters);
- context.contextUriInfo.addResourcePart(pathInfoFunction);
-
- // mark parameters as consumed
- ctx.vlNVO.remove(0);
- return null;
- }
-
- throw wrap(new UriParserSemanticException("Unknown resource path segment:" + fullFilterName.toString(),
- UriParserSemanticException.MessageKeys.UNKNOWN_PART, fullFilterName.toString()));
- }
- }
-
- /**
- * Ensures that the namespace of the first resource parts is null
- * @param vNS namespace or null
- */
- private void ensureNamespaceIsNull(final NamespaceContext vNS) {
- if (vNS != null && context.contextUriInfo.getLastResourcePart() == null) {
- // First resource part and namespace is not null!
- throw wrap(new UriParserSemanticException("Namespace is not allowed for EntitySets, Singeltons, "
- + " Action Imports and Function Imports. Found " + vNS.getText(),
- UriParserSemanticException.MessageKeys.NAMESPACE_NOT_ALLOWED_AT_FIRST_ELEMENT, vNS.getText()));
- }
- }
-
- private String getName(final EdmType type) {
- return type.getFullQualifiedName().getFullQualifiedNameAsString();
- }
-
- @Override
- public Object visitAllEOF(final AllEOFContext ctx) {
- context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.all);
- return null;
- }
-
- @Override
- public Object visitAllExpr(final AllExprContext ctx) {
- UriResource obj = context.contextUriInfo.getLastResourcePart();
- if (!(obj instanceof UriResourcePartTyped)) {
- throw wrap(new UriParserSemanticException("all only allowed on typed path segments",
- UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "all"));
- } else if (obj instanceof UriResourceNavigation) {
- if (!((UriResourceNavigation) obj).getKeyPredicates().isEmpty()) {
- throw wrap(new UriParserSemanticException(
- "Any lamdba expression must not be following navigation properties with key predicates.",
- UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED));
- }
- }
-
- UriContext.LambdaVariable var = new UriContext.LambdaVariable();
- var.name = ctx.vLV.getText();
- var.type = ParserHelper.getTypeInformation((UriResourcePartTyped) obj);
-
- context.allowedLambdaVariables.push(var);
- Expression expression = (Expression) ctx.vLE.accept(this);
- context.allowedLambdaVariables.pop();
- return new UriResourceLambdaAllImpl(var.name, expression);
- }
-
- @Override
- public Expression visitAltAdd(final AltAddContext ctx) {
- int tokenIndex = ctx.vO.getType();
- return new BinaryImpl(
- (Expression) ctx.vE1.accept(this),
- tokenIndex == UriLexer.ADD ? BinaryOperatorKind.ADD : BinaryOperatorKind.SUB,
- (Expression) ctx.vE2.accept(this),
- null);
- }
-
- @Override
- public Object visitAltAll(final AltAllContext ctx) {
-
- UriInfoImpl uriInfoImplpath = new UriInfoImpl().setKind(UriInfoKind.resource);
-
- uriInfoImplpath.addResourcePart((UriResourceImpl) super.visitAltAll(ctx));
-
- EdmType startType = removeUriResourceStartingTypeFilterImpl(uriInfoImplpath);
-
- return new MemberImpl(uriInfoImplpath, startType);
- }
-
- private EdmType removeUriResourceStartingTypeFilterImpl(final UriInfoImpl uriInfoImplpath) {
-
- List<UriResource> segments = uriInfoImplpath.getUriResourceParts();
- if (segments.size() == 0) {
- return null;
- }
-
- UriResource segment = segments.get(0);
- if (segment instanceof UriResourceStartingTypeFilterImpl) {
- UriResourceStartingTypeFilterImpl startingTypeFilter = (UriResourceStartingTypeFilterImpl) segment;
-
- EdmType type = null;
- if (startingTypeFilter.getTypeFilterOnEntry() != null) {
- type = startingTypeFilter.getTypeFilterOnEntry();
- } else if (startingTypeFilter.getTypeFilterOnCollection() != null) {
- type = startingTypeFilter.getTypeFilterOnCollection();
- } else {
- type = startingTypeFilter.getType();
- }
-
- uriInfoImplpath.removeResourcePart(0);
- return type;
- }
-
- return null;
- }
-
- @Override
- public Expression visitAltAnd(final AltAndContext ctx) {
- return new BinaryImpl(
- (Expression) ctx.vE1.accept(this),
- BinaryOperatorKind.AND,
- (Expression) ctx.vE2.accept(this),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean));
- }
-
- @Override
- public Object visitAltAny(final AltAnyContext ctx) {
- UriInfoImpl uriInfoImplpath = new UriInfoImpl().setKind(UriInfoKind.resource);
-
- uriInfoImplpath.addResourcePart((UriResourceImpl) super.visitAltAny(ctx));
-
- EdmType startType = removeUriResourceStartingTypeFilterImpl(uriInfoImplpath);
-
- return new MemberImpl(uriInfoImplpath, startType);
- }
-
- @Override
- public Expression visitAltComparism(final AltComparismContext ctx) {
- int tokenIndex = ctx.vO.getType();
- BinaryOperatorKind kind = null;
- if (tokenIndex == UriLexer.GT) {
- kind = BinaryOperatorKind.GT;
- } else if (tokenIndex == UriLexer.GE) {
- kind = BinaryOperatorKind.GE;
- } else if (tokenIndex == UriLexer.LT) {
- kind = BinaryOperatorKind.LT;
- } else if (tokenIndex == UriLexer.LE) {
- kind = BinaryOperatorKind.LE;
- }
- return new BinaryImpl(
- (Expression) ctx.vE1.accept(this),
- kind,
- (Expression) ctx.vE2.accept(this),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean));
- }
-
- @Override
- public Object visitEntityEOF(final EntityEOFContext ctx) {
- String odi = ctx.vODI.getText();
- FullQualifiedName fullName = getFullNameFromContext(ctx.vNS, odi);
-
- EdmEntityType type = edm.getEntityType(fullName);
- if (type == null) {
- throw wrap(new UriParserSemanticException("Expected EntityTypeName",
- UriParserSemanticException.MessageKeys.UNKNOWN_ENTITY_TYPE, fullName.toString()));
- }
- context.contextUriInfo.setEntityTypeCast(type);
-
- // contextUriInfo = uriInfo;
- context.contextTypes.push(context.contextUriInfo.getEntityTypeCast());
- context.isCollection = true; // TODO: check!
-
- return null;
- }
-
- @Override
- public Expression visitAltEquality(final AltEqualityContext ctx) {
- int tokenIndex = ctx.vO.getType();
- return new BinaryImpl(
- (Expression) ctx.vE1.accept(this),
- tokenIndex == UriLexer.EQ_ALPHA ? BinaryOperatorKind.EQ : BinaryOperatorKind.NE,
- (Expression) ctx.vE2.accept(this),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean));
- }
-
- @Override
- public Object visitAltHas(final AltHasContext ctx) {
- return new BinaryImpl(
- (Expression) ctx.vE1.accept(this),
- BinaryOperatorKind.HAS,
- (Expression) ctx.vE2.accept(this),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean));
- }
-
- @Override
- public Object visitMetadataEOF(final MetadataEOFContext ctx) {
-
- context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.metadata);
- return null;
- }
-
- @Override
- public Expression visitAltMult(final AltMultContext ctx) {
- int tokenIndex = ctx.vO.getType();
- BinaryOperatorKind kind;
- if (tokenIndex == UriLexer.MUL) {
- kind = BinaryOperatorKind.MUL;
- } else if (tokenIndex == UriLexer.DIV) {
- kind = BinaryOperatorKind.DIV;
- } else {
- kind = BinaryOperatorKind.MOD;
- }
- return new BinaryImpl(
- (Expression) ctx.vE1.accept(this),
- kind,
- (Expression) ctx.vE2.accept(this),
- null);
- }
-
- @Override
- public Expression visitAltOr(final AltOrContext ctx) {
- return new BinaryImpl(
- (Expression) ctx.vE1.accept(this),
- BinaryOperatorKind.OR,
- (Expression) ctx.vE2.accept(this),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean));
- }
-
- @Override
- public Object visitAnyExpr(final AnyExprContext ctx) {
- if (ctx.vLV != null) {
- UriResourceImpl lastResourcePart = (UriResourceImpl) context.contextUriInfo.getLastResourcePart();
- if (!(lastResourcePart instanceof UriResourcePartTyped)) {
- throw wrap(new UriParserSemanticException("any only allowed on typed path segments",
- UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "any"));
- } else if (lastResourcePart instanceof UriResourceNavigation) {
- if (!((UriResourceNavigation) lastResourcePart).getKeyPredicates().isEmpty()) {
- throw wrap(new UriParserSemanticException(
- "Any lamdba expression must not be following navigation properties with key predicates",
- UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED));
- }
- }
-
- UriContext.LambdaVariable var = new UriContext.LambdaVariable();
- var.name = ctx.vLV.getText();
- var.type = ParserHelper.getTypeInformation((UriResourcePartTyped) lastResourcePart);
-
- context.allowedLambdaVariables.push(var);
- Expression expression = (Expression) ctx.vLE.accept(this);
- context.allowedLambdaVariables.pop();
- return new UriResourceLambdaAnyImpl(var.name, expression);
- }
- return null;
- }
-
- @Override
- public Object visitBooleanNonCaseLiteral(final BooleanNonCaseLiteralContext ctx) {
- final String text = ctx.getText().toLowerCase();
- return new LiteralImpl(text.equals("false") ? "false" : "true",
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean));
- }
-
- @Override
- public Expression visitCastExpr(final CastExprContext ctx) {
- List<Expression> parameters = new ArrayList<Expression>();
- if (ctx.vE1 != null) {
- // is optional parameter
- parameters.add((Expression) ctx.vE1.accept(this));
- }
-
- String namespace = ctx.vNS.getText();
- namespace = namespace.substring(0, namespace.length() - 1);
-
- FullQualifiedName fullName = new FullQualifiedName(namespace, ctx.vODI.getText());
- EdmType type = getType(fullName);
- parameters.add(new TypeLiteralImpl(type));
- return new MethodImpl(MethodKind.CAST, parameters);
- }
-
- private EdmType getType(final FullQualifiedName fullName) {
- EdmType type = null;
-
- type = edm.getEntityType(fullName);
- if (type != null) {
- return type;
- }
-
- type = edm.getComplexType(fullName);
- if (type != null) {
- return type;
- }
-
- type = edm.getTypeDefinition(fullName);
- if (type != null) {
- return type;
- }
-
- type = edm.getEnumType(fullName);
- if (type != null) {
- return type;
- }
-
- if (fullName.getNamespace().equals(EdmPrimitiveType.EDM_NAMESPACE)) {
- final EdmPrimitiveTypeKind typeKind = EdmPrimitiveTypeKind.valueOf(fullName.getName());
- type = EdmPrimitiveTypeFactory.getInstance(typeKind);
- if (type != null) {
- return type;
- }
- }
-
- return null;
-
- }
-
- @Override
- public Expression visitCeilingMethodCallExpr(final CeilingMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.CEILING, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Expression visitConcatMethodCallExpr(final ConcatMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.CONCAT, Arrays.asList(
- (Expression) ctx.vE1.accept(this),
- (Expression) ctx.vE2.accept(this)));
- }
-
- @Override
- public Object visitConstSegment(final ConstSegmentContext ctx) {
- UriInfoImpl uriInfoResource = context.contextUriInfo;
- UriResource pathInfo = uriInfoResource.getLastResourcePart();
-
- if (ctx.vV != null) {
- if (pathInfo instanceof UriResourcePartTyped) {
- if (!((UriResourcePartTyped) pathInfo).isCollection()) {
- context.contextUriInfo.addResourcePart(new UriResourceValueImpl());
- } else {
- throw wrap(new UriParserSemanticException("$value only allowed on typed path segments",
- UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "$value"));
- }
- return null;
- } else {
- throw wrap(new UriParserSemanticException("$value only allowed on typed path segments",
- UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "$value"));
- }
-
- } else if (ctx.vC != null) {
- if (pathInfo instanceof UriResourcePartTyped) {
- if (((UriResourcePartTyped) pathInfo).isCollection()) {
- context.contextUriInfo.addResourcePart(new UriResourceCountImpl());
- } else {
- throw wrap(new UriParserSemanticException("$count only allowed on collection properties",
- UriParserSemanticException.MessageKeys.ONLY_FOR_COLLECTIONS, "$count"));
- }
- } else {
- throw wrap(new UriParserSemanticException("$count only allowed on typed properties",
- UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "$count"));
- }
- } else if (ctx.vR != null) {
- if (pathInfo instanceof UriResourcePartTyped) {
- EdmType type = ((UriResourcePartTyped) pathInfo).getType();
- if (type instanceof EdmEntityType) {
- context.contextUriInfo.addResourcePart(new UriResourceRefImpl());
- } else {
- throw wrap(new UriParserSemanticException("$ref only allowed on entity types",
- UriParserSemanticException.MessageKeys.ONLY_FOR_ENTITY_TYPES, "$ref"));
- }
- } else {
- throw wrap(new UriParserSemanticException("$ref only allowed on typed properties",
- UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PROPERTIES, "$ref"));
- }
-
- } else if (ctx.vAll != null) {
- context.contextUriInfo.addResourcePart((UriResourceLambdaAllImpl) ctx.vAll.accept(this));
- } else if (ctx.vAny != null) {
- context.contextUriInfo.addResourcePart((UriResourceLambdaAnyImpl) ctx.vAny.accept(this));
- }
- return null;
- }
-
- @Override
- public Expression visitContainsMethodCallExpr(final ContainsMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.CONTAINS, Arrays.asList(
- (Expression) ctx.vE1.accept(this),
- (Expression) ctx.vE2.accept(this)));
- }
-
- @Override
- public Object visitDateMethodCallExpr(final DateMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.DATE, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Expression visitDayMethodCallExpr(final DayMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.DAY, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Expression visitGeoDistanceMethodCallExpr(final GeoDistanceMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.GEODISTANCE, Arrays.asList(
- (Expression) ctx.vE1.accept(this),
- (Expression) ctx.vE2.accept(this)));
- }
-
- @Override
- public Object visitEndsWithMethodCallExpr(final EndsWithMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.ENDSWITH, Arrays.asList(
- (Expression) ctx.vE1.accept(this),
- (Expression) ctx.vE2.accept(this)));
- }
-
- @Override
- public Object visitEnumLiteral(final EnumLiteralContext ctx) {
- // get type
- final String odi = ctx.vODI.getText();
-
- final FullQualifiedName fullName = getFullNameFromContext(ctx.vNS, odi);
- final EdmEnumType edmEnumType = edm.getEnumType(fullName);
- if (edmEnumType == null) {
- throw wrap(new UriParserSemanticException(
- "Enum type '" + fullName.getFullQualifiedNameAsString() + "' not found!",
- UriParserSemanticException.MessageKeys.UNKNOWN_TYPE, fullName.getFullQualifiedNameAsString()));
- }
-
- String valueString = ctx.vValues.getText();
- valueString = valueString.substring(1, valueString.length() - 1);
- String[] values = valueString.split(",");
- return new EnumerationImpl(edmEnumType, Arrays.asList(values));
- }
-
- @Override
- public Object visitExpandItems(final ExpandItemsContext ctx) {
- ExpandOptionImpl expand = new ExpandOptionImpl();
- expand.setText(ctx.getText());
- for (ExpandItemContext eI : ctx.vlEI) {
- expand.addExpandItem((ExpandItemImpl) eI.accept(this));
- }
-
- return expand;
- }
-
- @Override
- public Object visitExpandItem(final ExpandItemContext ctx) {
-
- ExpandItemImpl expandItem = null;
- if (ctx.vS != null) {
- expandItem = new ExpandItemImpl().setIsStar(true);
- if (ctx.vR != null) {
- expandItem.setIsRef(true);
- } else if (ctx.vM != null) {
- LevelsOptionImpl levels = new LevelsOptionImpl().setMax();
- levels.setText(ctx.vM.getText());
- try {
- expandItem.setSystemQueryOption(levels);
- } catch (ODataRuntimeException e) {
- // Thrown if duplicated system query options are detected
- throw wrap(new UriParserSyntaxException("Double system query option!", e,
- UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION, e.getMessage()));
- }
- } else if (ctx.vL != null) {
- LevelsOptionImpl levels = new LevelsOptionImpl();
- String text = ctx.vL.getText();
- levels.setText(text);
- levels.setValue(Integer.parseInt(text));
- try {
- expandItem.setSystemQueryOption(levels);
- } catch (ODataRuntimeException e) {
- // Thrown if duplicated system query options are detected
- throw wrap(new UriParserSyntaxException("Double system query option!", e,
- UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION, e.getMessage()));
- }
- }
-
- } else if (ctx.vEP != null) {
- expandItem = (ExpandItemImpl) ctx.vEP.accept(this);
-
- if (ctx.vEPE != null) {
- ExpandItemImpl contextExpandItemPathBU = context.contextExpandItemPath;
- context.contextExpandItemPath = expandItem;
-
- @SuppressWarnings("unchecked")
- List<SystemQueryOptionImpl> list = (List<SystemQueryOptionImpl>) ctx.vEPE.accept(this);
- try {
- for (SystemQueryOptionImpl option : list) {
- expandItem.setSystemQueryOption(option);
- }
- } catch (ODataRuntimeException e) {
- // Thrown if duplicated system query options are detected
- throw wrap(new UriParserSyntaxException("Double system query option!", e,
- UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION, e.getMessage()));
- }
- context.contextExpandItemPath = contextExpandItemPathBU;
- }
- }
-
- return expandItem;
-
- }
-
- @Override
- public Object visitExpandPath(final ExpandPathContext ctx) {
- ExpandItemImpl expandItem = new ExpandItemImpl();
-
- // save context
- ExpandItemImpl contextExpandItemPathBU = context.contextExpandItemPath;
- UriInfoImpl uriInfoResourceBU = context.contextUriInfo;
-
- // set tmp context
- context.contextExpandItemPath = expandItem;
- context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.resource);
-
- context.contextVisitExpandResourcePath = true;
- super.visitExpandPath(ctx);
- context.contextVisitExpandResourcePath = false;
-
- EdmType startType = removeUriResourceStartingTypeFilterImpl(context.contextUriInfo);
- expandItem.setResourcePath(context.contextUriInfo);
- if (startType != null) {
- expandItem.setTypeFilter(startType);
- }
-
- // reset context
- context.contextUriInfo = uriInfoResourceBU;
- context.contextExpandItemPath = contextExpandItemPathBU;
-
- // test
- validate(uriInfoResourceBU.asUriInfoResource(), expandItem);
- //
-
- return expandItem;
- }
-
- private void validate(UriInfoResource uriInfoResource, ExpandItemImpl expandItem) {
- if (uriInfoResource != null) {
- EdmEntityType type = getEntityType(uriInfoResource);
- EdmEntityType name = getEntityType(expandItem.getResourcePath());
-
- if (name != null && type != null) {
- EdmElement property = type.getProperty(name.getName());
- if (!(property instanceof EdmNavigationProperty)) {
- throw wrap(new UriParserSemanticException(
- "NavigationProperty '" + name.getName() + "' not found in type '"
- + type.getFullQualifiedName().getFullQualifiedNameAsString() + "'",
- UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE,
- name.getFullQualifiedName().getFullQualifiedNameAsString(),
- type.getFullQualifiedName().getFullQualifiedNameAsString()));
- }
- }
- }
- }
-
- private EdmEntityType getEntityType(UriInfoResource test) {
- List<UriResource> parts = test.getUriResourceParts();
- if (!parts.isEmpty()) {
- UriResource lastPart = parts.get(parts.size() - 1);
- if (lastPart instanceof UriResourceEntitySet) {
- UriResourceEntitySet entitySet = (UriResourceEntitySet) lastPart;
- return entitySet.getEntityType();
- }
- }
- return null;
- }
-
- @Override
- public Object visitExpandPathExtension(final ExpandPathExtensionContext ctx) {
- List<SystemQueryOptionImpl> list = new ArrayList<SystemQueryOptionImpl>();
-
- EdmType targetType = null;
- boolean isColl = false;
- if (context.contextExpandItemPath == null) {
- // use the type of the last resource path segement
- UriResourceTypedImpl lastSegment = (UriResourceTypedImpl) context.contextUriInfo.getLastResourcePart();
- targetType = ParserHelper.getTypeInformation(lastSegment);
- isColl = lastSegment.isCollection();
- } else {
- if (context.contextExpandItemPath.getResourcePath() == null) {
- // use the type of the last resource path segement
- UriResourceTypedImpl lastSegment = (UriResourceTypedImpl) context.contextUriInfo.getLastResourcePart();
- targetType = ParserHelper.getTypeInformation(lastSegment);
- isColl = lastSegment.isCollection();
- } else {
- // use the type of the last ''expand'' path segement
- UriInfoImpl info = (UriInfoImpl) context.contextExpandItemPath.getResourcePath();
- targetType = ParserHelper.getTypeInformation((UriResourcePartTyped) info.getLastResourcePart());
- isColl = ((UriResourcePartTyped) info.getLastResourcePart()).isCollection();
- }
- }
-
- context.contextTypes.push(targetType);
- context.isCollection = isColl;
-
- if (ctx.vC != null) {
- UriInfoImpl resourcePath = (UriInfoImpl) context.contextExpandItemPath.getResourcePath();
- resourcePath.addResourcePart(new UriResourceCountImpl());
-
- for (ExpandCountOptionContext s : ctx.vlEOC) {
- list.add((SystemQueryOptionImpl) s.accept(this));
- }
- } else if (ctx.vR != null) {
- UriInfoImpl resourcePath = (UriInfoImpl) context.contextExpandItemPath.getResourcePath();
- resourcePath.addResourcePart(new UriResourceRefImpl());
-
- for (ExpandRefOptionContext s : ctx.vlEOR) {
- list.add((SystemQueryOptionImpl) s.accept(this));
- }
- } else {
- for (ExpandOptionContext s : ctx.vlEO) {
- list.add((SystemQueryOptionImpl) s.accept(this));
- }
- }
-
- context.contextTypes.pop();
- return list;
-
- }
-
- @Override
- public Object visitFilter(final FilterContext ctx) {
- context.contextReadingQueryPart = true;
- final FilterOptionImpl result = new FilterOptionImpl().setExpression((Expression) ctx.children.get(2)
- .accept(this));
- context.contextReadingQueryPart = false;
-
- return result;
- }
-
- @Override
- public Object visitFilterExpressionEOF(final FilterExpressionEOFContext ctx) {
- context.contextReadingQueryPart = true;
- final FilterOptionImpl result = new FilterOptionImpl().setExpression((Expression) ctx.children.get(0)
- .accept(this));
- context.contextReadingQueryPart = false;
-
- return result;
- }
-
- @Override
- public Expression visitFloorMethodCallExpr(final FloorMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.FLOOR, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Expression visitFractionalsecondsMethodCallExpr(final FractionalsecondsMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.FRACTIONALSECONDS, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Expression visitGeoLengthMethodCallExpr(final GeoLengthMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.GEOLENGTH, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Expression visitHourMethodCallExpr(final HourMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.HOUR, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Expression visitIndexOfMethodCallExpr(final IndexOfMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.INDEXOF, Arrays.asList(
- (Expression) ctx.vE1.accept(this),
- (Expression) ctx.vE2.accept(this)));
- }
-
- @Override
- public Object visitInlinecount(final InlinecountContext ctx) {
- final String text = ctx.children.get(2).getText();
- return new CountOptionImpl()
- .setValue(text.equalsIgnoreCase("true") ? true : false)
- .setText(text);
- }
-
- @Override
- public Expression visitGeoIntersectsMethodCallExpr(final GeoIntersectsMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.GEOINTERSECTS, Arrays.asList(
- (Expression) ctx.vE1.accept(this),
- (Expression) ctx.vE2.accept(this)));
- }
-
- @Override
- public Expression visitIsofExpr(final IsofExprContext ctx) {
- List<Expression> parameters = new ArrayList<Expression>();
- if (ctx.vE1 != null) {
- parameters.add((Expression) ctx.vE1.accept(this));
- }
-
- String namespace = ctx.vNS.getText();
- namespace = namespace.substring(0, namespace.length() - 1);
-
- FullQualifiedName fullName = new FullQualifiedName(namespace, ctx.vODI.getText());
- EdmType type = getType(fullName);
- parameters.add(new TypeLiteralImpl(type));
-
- return new MethodImpl(MethodKind.ISOF, parameters);
- }
-
- @Override
- public Expression visitLengthMethodCallExpr(final LengthMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.LENGTH, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Object visitLevels(final LevelsContext ctx) {
-
- LevelsOptionImpl levels = new LevelsOptionImpl();
-
- String text = ctx.children.get(2).getText();
-
- if (text.equals("max")) {
- levels.setMax();
- } else {
- levels.setValue(Integer.parseInt(text));
- }
- levels.setText(text);
-
- return levels;
-
- }
-
- @Override
- public Expression visitMaxDateTimeMethodCallExpr(final MaxDateTimeMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.MAXDATETIME, null);
- }
-
- @Override
- public Object visitMemberExpr(final MemberExprContext ctx) {
-
- UriInfoImpl uriInfoImplpath = new UriInfoImpl().setKind(UriInfoKind.resource);
-
- if (context.contextTypes.isEmpty()) {
- throw wrap(new UriParserSemanticException("Expression '" + ctx.getText() + "' is not allowed as key value.",
- UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, ctx.getText()));
- }
-
- if (ctx.vIt != null || ctx.vIts != null) {
- uriInfoImplpath.addResourcePart(new UriResourceItImpl(context.contextTypes.peek(), context.isCollection));
- }
-
- if (ctx.vPs != null) {
- // save the context
- UriInfoImpl backupUriInfoPath = context.contextUriInfo;
-
- // set temporary uriInfoPath
- context.contextUriInfo = uriInfoImplpath;
-
- ctx.vPs.accept(this);
-
- // reset context
- context.contextUriInfo = backupUriInfoPath;
- }
-
- if (ctx.vALL != null) {
- uriInfoImplpath.addResourcePart((UriResourceImpl) ctx.vALL.accept(this));
- }
- if (ctx.vANY != null) {
- uriInfoImplpath.addResourcePart((UriResourceImpl) ctx.vANY.accept(this));
- }
-
- EdmType startType = removeUriResourceStartingTypeFilterImpl(uriInfoImplpath);
-
- return new MemberImpl(uriInfoImplpath, startType);
- }
-
- @Override
- public Expression visitMinDateTimeMethodCallExpr(final MinDateTimeMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.MINDATETIME, null);
- }
-
- @Override
- public Expression visitMinuteMethodCallExpr(final MinuteMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.MINUTE, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Expression visitMonthMethodCallExpr(final MonthMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.MONTH, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Object visitNameValueOptList(final NameValueOptListContext ctx) {
- if (ctx.vVO != null) {
- // This branch is chosen if the key predicate is a common expression e.g. EntitySet(0)
-
- // is single key predicate without a name
- String valueText = ctx.vVO.getText();
- Expression expression = null;
- try {
- expression = (Expression) ctx.vVO.accept(this);
- } catch (final RuntimeException e) {
- throw wrap(new UriParserSemanticException("Invalid key value: " + valueText, e,
- UriParserSemanticException.MessageKeys.INVALID_KEY_VALUE, valueText));
- }
-
- // get type of last resource part
- UriResource last = context.contextUriInfo.getLastResourcePart();
- if (!(last instanceof UriResourcePartTyped)) {
- throw wrap(new UriParserSemanticException("Parameters list on untyped resource path segment not allowed",
- UriParserSemanticException.MessageKeys.PARAMETERS_LIST_ONLY_FOR_TYPED_PARTS));
-
- } else if (last instanceof UriResourceFunction) {
- // Handle functions
- final UriResourceFunction uriResourceFunction =
- (UriResourceFunction) context.contextUriInfo.getLastResourcePart();
- final EdmReturnType returnType = uriResourceFunction.getFunction().getReturnType();
-
- if (returnType.getType().getKind() != EdmTypeKind.ENTITY || !returnType.isCollection()) {
- throw wrap(new UriParserSemanticException("No keys allowed",
- UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED));
- } else {
- // The functions returns a collection of entities
- // Get the EDM Type and determine how many key predicates are needed. In this case only one
- // key predicate is allowed. If the entity type needs more than one key predicate, the client
- // has to use the key value syntax e.g. EntitySet(ID=1,Order=2)
- final EdmEntityType entityType = (EdmEntityType) uriResourceFunction.getFunction().getReturnType().getType();
- final List<String> lastKeyPredicates = entityType.getKeyPredicateNames();
-
- if (lastKeyPredicates.size() == 1) {
- return Collections.singletonList(new UriParameterImpl()
- .setName(lastKeyPredicates.get(0))
- .setText(valueText)
- .setExpression(expression));
- } else {
- throw wrap(new UriParserSemanticException("Wrong number of key properties.",
- UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
- Integer.toString(lastKeyPredicates.size()), "1"));
- }
- }
- } else {
- // Handle EntitySets
- EdmEntityType lastType = (EdmEntityType) ((UriResourcePartTyped) last).getType();
-
- // get list of keys for lastType
- List<String> lastKeyPredicates = lastType.getKeyPredicateNames();
-
- // If there is exactly one key defined in the EDM, then this key is the key written in the URI,
- // so fill the keylist with this key and return.
- if (lastKeyPredicates.size() == 1) {
- return Collections.singletonList(new UriParameterImpl()
- .setName(lastKeyPredicates.get(0))
- .setText(valueText)
- .setExpression(expression));
- }
-
- // There are more keys defined in the EDM, but only one is written in the URI. This is allowed only if
- // referential constraints are defined on this navigation property which can be used to fill up all
- // required keys.
- // For using referential constraints the last resource part must be a navigation property.
- if (!(context.contextUriInfo.getLastResourcePart() instanceof UriResourceNavigationPropertyImpl)) {
- throw wrap(new UriParserSemanticException("Wrong number of key properties.",
- UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
- Integer.toString(lastKeyPredicates.size()), "1"));
- }
- UriResourceNavigationPropertyImpl lastNav = (UriResourceNavigationPropertyImpl) last;
-
- // get the partner of the navigation property
- EdmNavigationProperty partner = lastNav.getProperty().getPartner();
- if (partner == null) {
- throw wrap(new UriParserSemanticException("Wrong number of key properties.",
- UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
- Integer.toString(lastKeyPredicates.size()), "1"));
- }
-
- // create the keylist
- List<UriParameterImpl> list = new ArrayList<UriParameterImpl>();
-
- // Find the keys not filled by referential constraints
- // and collect the other keys filled by referential constraints.
- String missedKey = null;
- for (String item : lastKeyPredicates) {
- String property = partner.getReferencingPropertyName(item);
- if (property != null) {
- list.add(new UriParameterImpl().setName(item).setReferencedProperty(property));
- } else {
- if (missedKey == null) {
- missedKey = item;
- } else {
- // two of more keys are missing
- throw wrap(new UriParserSemanticException("Not enough referential constraints defined",
- UriParserSemanticException.MessageKeys.NOT_ENOUGH_REFERENTIAL_CONSTRAINTS));
- }
- }
- }
-
- // the missing key is the one which is defined in the URI
- list.add(new UriParameterImpl().setName(missedKey).setText(valueText).setExpression(expression));
-
- return list;
- }
- } else if (ctx.vNVL != null) {
- // The client provided a list of key values pairs e.g. EntitySet(ID=1,Order=2)
- List<UriParameterImpl> list = new ArrayList<UriParameterImpl>();
-
- for (ParseTree c : ctx.vNVL.vlNVP) {
- list.add((UriParameterImpl) c.accept(this));
- }
-
- if (context.contextReadingFunctionParameters) {
- return list;
- }
-
- UriResource last = context.contextUriInfo.getLastResourcePart();
-
- // get type of last resource part
- if (!(last instanceof UriResourcePartTyped)) {
- throw wrap(new UriParserSemanticException("Parameters list on untyped resource path segment not allowed",
- UriParserSemanticException.MessageKeys.PARAMETERS_LIST_ONLY_FOR_TYPED_PARTS));
- }
- if (last instanceof UriResourceFunction) {
- final UriResourceFunction uriResourceFunction = (UriResourceFunction) context.contextUriInfo
- .getLastResourcePart();
- final EdmReturnType returnType = uriResourceFunction.getFunction().getReturnType();
-
- if (returnType.getType().getKind() != EdmTypeKind.ENTITY || !returnType.isCollection()) {
- throw wrap(new UriParserSemanticException("No keys allowed",
- UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED));
- } else {
- // The functions returns a collection of entities
- // Get the EDM Type and determine how many key predicates are needed.
- // In case of functions all key predicates must be provided by the client.
- final EdmEntityType entityType = (EdmEntityType) uriResourceFunction.getFunction().getReturnType().getType();
- final List<String> lastKeyPredicates = entityType.getKeyPredicateNames();
-
- if (lastKeyPredicates.size() == list.size()) {
- return list;
- } else {
- throw wrap(new UriParserSemanticException("Wrong number of key properties.",
- UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
- Integer.toString(lastKeyPredicates.size()), "1"));
- }
- }
- } else {
- // Handle entity sets
- EdmEntityType lastType = (EdmEntityType) ((UriResourcePartTyped) last).getType();
-
- // get list of keys for lastType
- List<String> lastKeyPredicates = lastType.getKeyPredicateNames();
-
- // check if all key are filled from the URI
- if (list.size() == lastKeyPredicates.size()) {
- return list;
- }
-
- // if not, check if the missing key predicates can be satisfied with help of the defined
- // referential constraints
- // for using referential constraints the last resource part must be a navigation property
- if (!(context.contextUriInfo.getLastResourcePart() instanceof UriResourceNavigationPropertyImpl)) {
- throw wrap(new UriParserSemanticException("Wrong number of key properties.",
- UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
- Integer.toString(lastKeyPredicates.size()), Integer.toString(list.size())));
- }
- UriResourceNavigationPropertyImpl lastNav = (UriResourceNavigationPropertyImpl) last;
-
- // get the partner of the navigation property
- EdmNavigationProperty partner = lastNav.getProperty().getPartner();
- if (partner == null) {
- throw wrap(new UriParserSemanticException("Wrong number of key properties.",
- UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
- Integer.toString(lastKeyPredicates.size()), Integer.toString(list.size())));
- }
-
- // fill missing keys from referential constraints
- for (String key : lastKeyPredicates) {
- boolean found = false;
- for (UriParameterImpl item : list) {
- if (item.getName().equals(key)) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- String property = partner.getReferencingPropertyName(key);
- if (property != null) {
- // store the key name as referenced property
- list.add(0, new UriParameterImpl().setName(key).setReferencedProperty(property));
- }
- }
- }
-
- // check again if all key predicates are filled from the URI
- if (list.size() == lastKeyPredicates.size()) {
- return list;
- } else {
- throw wrap(new UriParserSemanticException("Wrong number of key properties.",
- UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES,
- Integer.toString(lastKeyPredicates.size()), Integer.toString(list.size())));
- }
- }
- } else {
- // No key predicates are provided by the client
-
- if (context.contextReadingFunctionParameters) {
- return Collections.emptyList();
- } else {
- final UriResource last = context.contextUriInfo.getLastResourcePart();
- final int number = last instanceof UriResourcePartTyped ? ((EdmEntityType) ((UriResourcePartTyped) last)
- .getType()).getKeyPredicateNames().size() : 0;
- throw wrap(new UriParserSemanticException("Wrong number of key properties.",
- UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES, Integer.toString(number), "0"));
- }
- }
- }
-
- @Override
- public UriParameterImpl visitNameValuePair(final NameValuePairContext ctx) {
- UriParameterImpl uriParameter = new UriParameterImpl();
- uriParameter.setName(ctx.vODI.getText());
-
- if (ctx.vCOM != null) {
- final String text = ctx.vCOM.getText();
- uriParameter.setText("null".equals(text) ? null : text);
- uriParameter.setExpression((Expression) ctx.vCOM.accept(this));
- } else {
- uriParameter.setAlias("@" + ctx.vALI.getText());
- }
-
- return uriParameter;
- }
-
- @Override
- public Object visitNaninfinityLiteral(final NaninfinityLiteralContext ctx) {
- return new LiteralImpl(ctx.getText(),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal));
- }
-
- @Override
- public Expression visitNowMethodCallExpr(final NowMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.NOW, null);
- }
-
- @Override
- public Object visitNullruleLiteral(final NullruleLiteralContext ctx) {
- return new LiteralImpl("null", null);
- }
-
- @Override
- public Object visitOrderBy(final OrderByContext ctx) {
-
- OrderByOptionImpl orderBy = new OrderByOptionImpl();
-
- for (OrderByItemContext item : ((OrderListContext) ctx.getChild(2)).vlOI) {
- OrderByItemImpl oItem = (OrderByItemImpl) item.accept(this);
- orderBy.addOrder(oItem);
- }
-
- return orderBy;
- }
-
- @Override
- public Object visitOrderByEOF(final OrderByEOFContext ctx) {
- context.contextReadingQueryPart = true;
-
- OrderByOptionImpl orderBy = new OrderByOptionImpl();
-
- for (OrderByItemContext item : ((OrderListContext) ctx.getChild(0)).vlOI) {
- OrderByItemImpl oItem = (OrderByItemImpl) item.accept(this);
- orderBy.addOrder(oItem);
- }
-
- context.contextReadingFunctionParameters = false;
- return orderBy;
- }
-
- @Override
- public Object visitOrderByItem(final OrderByItemContext ctx) {
- OrderByItemImpl oItem = new OrderByItemImpl();
- if (ctx.vD != null) {
- oItem.setDescending(true);
- }
-
- oItem.setExpression((Expression) ctx.vC.accept(this));
- return oItem;
- }
-
- @Override
- public Object visitPathSegment(final PathSegmentContext ctx) {
- readResourcePathSegment(ctx);
- /*
- * if (contextUriInfo.getLastResourcePart() == null ||
- * contextUriInfo.getLastResourcePart() instanceof UriResourceRootImpl) {
- *
- * } else {
- * readNextPathInfoSegment(ctx);
- * }
- */
- UriResourceImpl pathInfoSegment = (UriResourceImpl) context.contextUriInfo.getLastResourcePart();
-
- if (ctx.vlNVO.size() > 0) {
- // check for keyPredicates
- if (pathInfoSegment instanceof UriResourceWithKeysImpl) {
- if (ctx.vlNVO.size() > 1) {
- throw wrap(new UriParserSemanticException("More than one key predicates found",
- UriParserSemanticException.MessageKeys.WRONG_NUMBER_OF_KEY_PROPERTIES, "1",
- Integer.toString(ctx.vlNVO.size())));
- }
-
- @SuppressWarnings("unchecked")
- List<UriParameter> list = (List<UriParameter>) ctx.vlNVO.get(0).accept(this);
- ((UriResourceWithKeysImpl) pathInfoSegment)
- .setKeyPredicates(list);
- } else {
- throw wrap(new UriParserSemanticException("Key properties not allowed",
- UriParserSemanticException.MessageKeys.KEY_NOT_ALLOWED));
- }
- }
-
- return pathInfoSegment;
- }
-
- @Override
- public Object visitPathSegments(final PathSegmentsContext ctx) {
- // path segment
- for (PathSegmentContext it : ctx.vlPS) {
- it.accept(this);
- }
-
- // const segment
- if (ctx.vCS != null) {
- ctx.vCS.accept(this);
- }
- return null;
- }
-
- @Override
- public Object visitPrimitiveLiteral(final PrimitiveLiteralContext ctx) {
- ParseTree child1 = ctx.children.get(0);
-
- if (child1 instanceof EnumLiteralContext
- || child1 instanceof BooleanNonCaseLiteralContext
- || child1 instanceof NullruleLiteralContext
- || child1 instanceof NaninfinityLiteralContext
- || child1 instanceof StringLiteralContext
- || child1 instanceof IntLiteralContext
- || child1 instanceof BinaryLiteralContext
- || child1 instanceof DateLiteralContext
- || child1 instanceof DatetimeoffsetLiteralContext
- || child1 instanceof DurationLiteralContext
- || child1 instanceof GuidLiteralContext
- || child1 instanceof TimeofdayLiteralContext
- || child1 instanceof DecimalLiteralContext
- || child1 instanceof BinaryLiteralContext) {
- return child1.accept(this);
- }
-
- // TODO Implement geography types and set a proper type
- return new LiteralImpl(ctx.getText(), null);
- }
-
- @Override
- public Object visitBinaryLiteral(BinaryLiteralContext ctx) {
- return new LiteralImpl(ctx.getText(),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary));
- }
-
- @Override
- public Object visitStringLiteral(final StringLiteralContext ctx) {
- return new LiteralImpl(ctx.getText(),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.String));
- }
-
- @Override
- public Object visitDecimalLiteral(final DecimalLiteralContext ctx) {
- final EdmType type = EdmPrimitiveTypeFactory.getInstance(
- ctx.getText().contains("e") || ctx.getText().contains("E") ?
- EdmPrimitiveTypeKind.Double :
- EdmPrimitiveTypeKind.Decimal);
-
- return new LiteralImpl(ctx.getText(), type);
- }
-
- @Override
- public Object visitIntLiteral(final IntLiteralContext ctx) {
- EdmPrimitiveTypeKind typeKind = null;
- try {
- final long value = Long.parseLong(ctx.getText());
- if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
- typeKind = EdmPrimitiveTypeKind.SByte;
- } else if (value >= 0 && value <= 255) {
- typeKind = EdmPrimitiveTypeKind.Byte;
- } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
- typeKind = EdmPrimitiveTypeKind.Int16;
- } else if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) {
- typeKind = EdmPrimitiveTypeKind.Int32;
- } else {
- typeKind = EdmPrimitiveTypeKind.Int64;
- }
- } catch (NumberFormatException e) {
- return new LiteralImpl(ctx.getText(),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal));
- }
- return new LiteralImpl(ctx.getText(),
- EdmPrimitiveTypeFactory.getInstance(typeKind));
- }
-
- @Override
- public Object visitDateLiteral(final DateLiteralContext ctx) {
- return new LiteralImpl(ctx.getText(),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Date));
- }
-
- @Override
- public Object visitDatetimeoffsetLiteral(final DatetimeoffsetLiteralContext ctx) {
- return new LiteralImpl(ctx.getText(),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.DateTimeOffset));
- }
-
- @Override
- public Object visitDurationLiteral(final DurationLiteralContext ctx) {
- return new LiteralImpl(ctx.getText(),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Duration));
- }
-
- @Override
- public Object visitGuidLiteral(final GuidLiteralContext ctx) {
- return new LiteralImpl(ctx.getText(),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Guid));
- }
-
- @Override
- public Object visitTimeofdayLiteral(final TimeofdayLiteralContext ctx) {
- return new LiteralImpl(ctx.getText(),
- EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.TimeOfDay));
- }
-
- @Override
- public Object visitQueryOptions(final QueryOptionsContext ctx) {
-
- List<QueryOptionImpl> qpList = new ArrayList<QueryOptionImpl>();
- for (QueryOptionContext entityOption : ctx.vlQO) {
- qpList.add((QueryOptionImpl) entityOption.accept(this));
- }
-
- return qpList;
- }
-
- @Override
- public Object visitRootExpr(final RootExprContext ctx) {
-
- UriResource lastResource = context.contextUriInfo.getLastResourcePart();
-
- if (!(lastResource instanceof UriResourcePartTyped)) {
- throw wrap(new UriParserSemanticException("Resource path not typed",
- UriParserSemanticException.MessageKeys.RESOURCE_PATH_NOT_TYPED));
- }
-
- UriResourcePartTyped lastType = (UriResourcePartTyped) lastResource;
-
- UriResourceRootImpl pathInfoRoot = new UriResourceRootImpl(
- ParserHelper.getTypeInformation(lastType),
- lastType.isCollection());
-
- UriInfoImpl uriInfoImplpath = new UriInfoImpl().setKind(UriInfoKind.resource);
- uriInfoImplpath.addResourcePart(pathInfoRoot);
-
- if (ctx.vPs != null) {
- // store the context uriInfoPath
- UriInfoImpl backupUriInfoPath = context.contextUriInfo;
-
- // set temporary uriInfoPath to collect the path information of the memberExpression
- context.contextUriInfo = uriInfoImplpath;
-
- ctx.vPs.accept(this);
-
- context.contextUriInfo = backupUriInfoPath;
-
- }
- return new MemberImpl(uriInfoImplpath, null);
-
- }
-
- @Override
- public Expression visitRoundMethodCallExpr(final RoundMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.ROUND, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Expression visitSecondMethodCallExpr(final SecondMethodCallExprContext ctx) {
- return new MethodImpl(MethodKind.SECOND, Collections.singletonList((Expression) ctx.vE1.accept(this)));
- }
-
- @Override
- public Object visitSelect(final SelectContext ctx) {
- List<SelectItem> selectItems = new ArrayList<SelectItem>();
- for (SelectItemContext si : ctx.vlSI) {
- selectItems.add((SelectItem) si.accept(this));
- }
-
- return new SelectOptionImpl().setSelectItems(selectItems).setText(ctx.children.get(2).getText());
- }
-
- @Override
- public Object visitSelectEOF(final SelectEOFContext ctx) {
- context.contextReadingQueryPart = true;
- List<SelectItem> selectItems = new ArrayList<SelectItem>();
- for (SelectItemContext si : ctx.vlSI) {
- selectItems.add((SelectItem) si.accept(this));
- }
-
- final QueryOptionImpl result = new SelectOptionImpl().setSelectItems(selectItems).setText(ctx.getText());
- context.contextReadingQueryPart = false;
-
- return result;
- }
-
- @Override
- public Object visitSelectItem(final SelectItemContext ctx) {
- SelectItemImpl selectItem = new SelectItemImpl();
-
- context.contextSelectItem = selectItem;
- for (SelectSegmentContext si : ctx.vlSS) {
- si.accept(this);
- }
- context.contextSelectItem = null;
-
- return selectItem;
- }
-
- @Override
- public Object visitSelectSegment(final SelectSegmentContext ctx) {
-
- if (ctx.vS != null) {
- if (ctx.vNS != null) {
- String namespace = ctx.vNS.getText();
- namespace = namespace.substring(0, namespace.length() - 1);
- FullQualifiedName fullName = new FullQualifiedName(namespace, "*");
- context.contextSelectItem.addAllOperationsInSchema(fullName);
- } else {
- context.contextSelectItem.setStar(true);
- }
- return null;
- }
-
- String odi = ctx.vODI.getText();
- if (ctx.vNS == null) {
-
- EdmType prevType = null;
- if (context.contextSelectItem.getResourcePath() == null) {
- prevType = context.contextTypes.peek();
- } else {
- UriInfoImpl uriInfo = (UriInfoImpl) context.contextSelectItem.getResourcePath();
- UriResource last = uriInfo.getLastResourcePart();
-
- prevType = ParserHelper.getTypeInformation((UriResourcePartTyped) last);
- if (prevType == null) {
- throw wrap(new UriParserSemanticException("prev segment not typed",
- UriParserSemanticException.MessageKeys.ONLY_FOR_TYPED_PARTS, "select"));
- }
- }
-
- if (!(prevType instanceof EdmStructuredType)) {
- throw wrap(new UriParserSemanticException("Previous select item is not a structural type",
- UriParserSemanticException.MessageKeys.ONLY_FOR_STRUCTURAL_TYPES, "select"));
<TRUNCATED>