[OLINGO-1489]Support custom aggregates that have the same name a property

This commit is contained in:
ramya vasanth 2020-10-29 12:44:29 +05:30
parent 4baf2b695a
commit 4aba5b9f92
2 changed files with 80 additions and 17 deletions

View File

@ -237,18 +237,7 @@ public class ApplyParser {
UriInfoImpl uriInfo = new UriInfoImpl();
final String identifierLeft = parsePathPrefix(uriInfo, referencedType);
if (identifierLeft != null) {
final String customAggregate = tokenizer.getText();
// A custom aggregate (an OData identifier) is defined in the CustomAggregate
// EDM annotation (in namespace Org.OData.Aggregation.V1) of the structured type or of the entity container.
// Currently we don't look into annotations, so all custom aggregates are allowed and have no type.
uriInfo.addResourcePart(new UriResourcePrimitivePropertyImpl(createDynamicProperty(customAggregate, null)));
aggregateExpression.setPath(uriInfo);
final String alias = parseAsAlias(referencedType, false);
aggregateExpression.setAlias(alias);
if (alias != null) {
((DynamicStructuredType) referencedType).addProperty(createDynamicProperty(alias, null));
}
parseAggregateFrom(aggregateExpression, referencedType);
customAggregate(referencedType, aggregateExpression, uriInfo);
} else if (tokenizer.next(TokenKind.OPEN)) {
final UriResource lastResourcePart = uriInfo.getLastResourcePart();
if (lastResourcePart == null) {
@ -279,8 +268,13 @@ public class ApplyParser {
aggregateExpression.setExpression(expression);
parseAggregateWith(aggregateExpression);
if (aggregateExpression.getStandardMethod() == null && aggregateExpression.getCustomMethod() == null) {
throw new UriParserSyntaxException("Invalid 'aggregateExpr' syntax.",
UriParserSyntaxException.MessageKeys.SYNTAX);
if (tokenizer.next(TokenKind.AsOperator)) {
throw new UriParserSyntaxException("Invalid 'aggregateExpr' syntax.",
UriParserSyntaxException.MessageKeys.SYNTAX);
}
customAggregateNamedAsProperty(referencedType, aggregateExpression, uriInfo);
return aggregateExpression;
}
final String alias = parseAsAlias(referencedType, true);
aggregateExpression.setAlias(alias);
@ -302,6 +296,43 @@ public class ApplyParser {
return aggregateExpression;
}
private void customAggregate(EdmStructuredType referencedType, AggregateExpressionImpl aggregateExpression,
UriInfoImpl uriInfo) throws UriParserException {
final String customAggregate = tokenizer.getText();
// A custom aggregate (an OData identifier) is defined in the CustomAggregate
// EDM annotation (in namespace Org.OData.Aggregation.V1) of the structured type
// or of the entity container.
// Currently we don't look into annotations, so all custom aggregates are
// allowed and have no type.
uriInfo.addResourcePart(new UriResourcePrimitivePropertyImpl(createDynamicProperty(customAggregate, null)));
aggregateExpression.setPath(uriInfo);
final String alias = parseAsAlias(referencedType, false);
if (alias != null) {
aggregateExpression.setAlias(alias);
((DynamicStructuredType) referencedType).addProperty(createDynamicProperty(alias, null));
}
parseAggregateFrom(aggregateExpression, referencedType);
}
private void customAggregateNamedAsProperty(EdmStructuredType referencedType,
AggregateExpressionImpl aggregateExpression, UriInfoImpl uriInfo)
throws UriParserException {
/*
* The name of the custom aggregate is identical to the name of a declared
* property of the structured type. This is typically done when the custom
* aggregate is used as a default aggregate for that property. In this case, the
* name refers to the custom aggregate within an aggregate expression without a
* with clause, and to the property in all other cases.
*/
UriResource lastResourcePart = uriInfo.getLastResourcePart();
String alias = lastResourcePart.getSegmentValue();
EdmType edmType = ParserHelper.getTypeInformation((UriResourcePartTyped) lastResourcePart);
aggregateExpression.setPath(uriInfo);
aggregateExpression.setAlias(alias);
aggregateExpression.setExpression(null);
((DynamicStructuredType) referencedType).addProperty(createDynamicProperty(alias, edmType));
}
private void parseAggregateWith(AggregateExpressionImpl aggregateExpression) throws UriParserException {
if (tokenizer.next(TokenKind.WithOperator)) {
final TokenKind kind = ParserHelper.next(tokenizer,

View File

@ -21,6 +21,7 @@ package org.apache.olingo.server.core.uri.parser;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
@ -109,11 +110,9 @@ public class ApplyParserTest {
parse("ESTwoKeyNav", "aggregate(PropertyInt16 with min as min,PropertyInt16 with max as max)")
.goAggregate(0).isStandardMethod(StandardMethod.MIN).isAlias("min").goUp()
.goAggregate(1).isStandardMethod(StandardMethod.MAX).isAlias("max");
parseEx("ESTwoKeyNav", "aggregate()")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
parseEx("ESTwoKeyNav", "aggregate(PropertyInt16)")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
parseEx("ESTwoKeyNav", "aggregate(PropertyInt16 with sum)")
.isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
parseEx("ESTwoKeyNav", "aggregate(PropertyInt16 as s)")
@ -126,6 +125,26 @@ public class ApplyParserTest {
.isExSemantic(UriParserSemanticException.MessageKeys.IS_PROPERTY);
}
@Test
public void customAggregate() throws Exception {
parse("ESTwoKeyNav", "aggregate(customAggregate)")
.is(Aggregate.class)
.goAggregate(0)
.noExpression()
.noInlineAggregateExpression()
.goPath().first().isUriPathInfoKind(UriResourceKind.primitiveProperty);
}
@Test
public void customAggregateNamedAsProperty() throws Exception {
parse("ESTwoKeyNav", "aggregate(PropertyInt16)")
.is(Aggregate.class)
.goAggregate(0)
.noExpression()
.noInlineAggregateExpression()
.goPath().first().isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, false);
}
@Test
public void aggregateExpression() throws Exception {
parse("ESTwoKeyNav", "aggregate(PropertyInt16 mul PropertyComp/PropertyInt16 with sum as s)")
@ -670,6 +689,13 @@ public class ApplyParserTest {
return this;
}
public AggregateValidator noExpression() {
assertNotNull(aggregateExpression);
assertNull(aggregateExpression.getExpression());
return this;
}
public FilterValidator goExpression() {
assertNotNull(aggregateExpression);
assertNotNull(aggregateExpression.getExpression());
@ -687,6 +713,12 @@ public class ApplyParserTest {
return new ResourceValidator().setUpValidator(this).setEdm(edm).setUriInfoPath(resource);
}
public AggregateValidator noInlineAggregateExpression() {
assertNull(aggregateExpression.getInlineAggregateExpression());
return this;
}
public AggregateValidator goInlineAggregateExpression() {
return new AggregateValidator(aggregateExpression.getInlineAggregateExpression(), this);
}