[OLINGO-1489]Support custom aggregates that have the same name a property
This commit is contained in:
parent
4baf2b695a
commit
4aba5b9f92
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue