You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2016/03/21 10:18:04 UTC
[2/3] olingo-odata4 git commit: [OLINGO-904] Allow expand on
crossjoin with entity set level
[OLINGO-904] Allow expand on crossjoin with entity set level
Future changes still needed to support navigation/options afterwards
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/e5d1e823
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/e5d1e823
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/e5d1e823
Branch: refs/heads/master
Commit: e5d1e823c5c8a8113c17db5dfcfd3073b9d82da4
Parents: 8406c58
Author: Christian Amend <ch...@sap.com>
Authored: Fri Mar 18 14:35:06 2016 +0100
Committer: Christian Amend <ch...@sap.com>
Committed: Mon Mar 21 10:09:17 2016 +0100
----------------------------------------------------------------------
.../server/core/uri/parser/ExpandParser.java | 49 +++++++++++++++++---
.../olingo/server/core/uri/parser/Parser.java | 34 +++++++-------
.../core/uri/parser/TestFullResourcePath.java | 21 +++++++++
3 files changed, 82 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5d1e823/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
index 03750a5..2fc0faf 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ExpandParser.java
@@ -6,9 +6,9 @@
* 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
@@ -18,6 +18,7 @@
*/
package org.apache.olingo.server.core.uri.parser;
+import java.util.Collection;
import java.util.Map;
import org.apache.olingo.commons.api.edm.Edm;
@@ -41,6 +42,7 @@ import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
import org.apache.olingo.server.core.uri.UriInfoImpl;
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.UriResourceNavigationPropertyImpl;
import org.apache.olingo.server.core.uri.UriResourceRefImpl;
import org.apache.olingo.server.core.uri.parser.UriTokenizer.TokenKind;
@@ -57,24 +59,58 @@ public class ExpandParser {
private final Edm edm;
private final OData odata;
private final Map<String, AliasQueryOption> aliases;
+ private final Collection<String> crossjoinEntitySetNames;
- public ExpandParser(final Edm edm, final OData odata, final Map<String, AliasQueryOption> aliases) {
+ public ExpandParser(final Edm edm, final OData odata, final Map<String, AliasQueryOption> aliases,
+ final Collection<String> crossjoinEntitySetNames) {
this.edm = edm;
this.odata = odata;
this.aliases = aliases;
+ this.crossjoinEntitySetNames = crossjoinEntitySetNames;
}
public ExpandOption parse(UriTokenizer tokenizer, final EdmStructuredType referencedType)
throws UriParserException, UriValidationException {
ExpandOptionImpl expandOption = new ExpandOptionImpl();
do {
- final ExpandItem item = parseItem(tokenizer, referencedType);
- expandOption.addExpandItem(item);
+ // In the crossjoin case the start has to be an EntitySet name which will dictate the reference type
+ if (crossjoinEntitySetNames != null && !crossjoinEntitySetNames.isEmpty()) {
+ final ExpandItem item = parseCrossJoinItem(tokenizer);
+ expandOption.addExpandItem(item);
+ } else {
+ final ExpandItem item = parseItem(tokenizer, referencedType);
+ expandOption.addExpandItem(item);
+ }
} while (tokenizer.next(TokenKind.COMMA));
return expandOption;
}
+ private ExpandItem parseCrossJoinItem(UriTokenizer tokenizer) throws UriParserSemanticException {
+ ExpandItemImpl item = new ExpandItemImpl();
+ if (tokenizer.next(TokenKind.STAR)) {
+ item.setIsStar(true);
+ } else if (tokenizer.next(TokenKind.ODataIdentifier)) {
+ String entitySetName = tokenizer.getText();
+ if (crossjoinEntitySetNames.contains(entitySetName)) {
+ UriInfoImpl resource = new UriInfoImpl().setKind(UriInfoKind.resource);
+ final UriResourceEntitySetImpl entitySetResourceSegment =
+ new UriResourceEntitySetImpl(edm.getEntityContainer().getEntitySet(entitySetName));
+ resource.addResourcePart(entitySetResourceSegment);
+
+ item.setResourcePath(resource);
+ } else {
+ throw new UriParserSemanticException("Unknown crossjoin entity set.",
+ UriParserSemanticException.MessageKeys.UNKNOWN_PART, entitySetName);
+ }
+ } else {
+ throw new UriParserSemanticException("If the target resource is a crossjoin an entity set is "
+ + "needed as the starting point.",
+ UriParserSemanticException.MessageKeys.UNKNOWN_PART);
+ }
+ return item;
+ }
+
private ExpandItem parseItem(UriTokenizer tokenizer, final EdmStructuredType referencedType)
throws UriParserException, UriValidationException {
ExpandItemImpl item = new ExpandItemImpl();
@@ -167,6 +203,7 @@ public class ExpandParser {
EdmStructuredType type = referencedType;
String name = null;
+
while (tokenizer.next(TokenKind.ODataIdentifier)) {
name = tokenizer.getText();
final EdmProperty property = referencedType.getStructuralProperty(name);
@@ -217,7 +254,7 @@ public class ExpandParser {
} else if (!forRef && !forCount && tokenizer.next(TokenKind.EXPAND)) {
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
- systemQueryOption = new ExpandParser(edm, odata, aliases).parse(tokenizer, referencedType);
+ systemQueryOption = new ExpandParser(edm, odata, aliases, null).parse(tokenizer, referencedType);
} else if (tokenizer.next(TokenKind.FILTER)) {
ParserHelper.requireNext(tokenizer, TokenKind.EQ);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5d1e823/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
index e1313c1..b4469d8 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/Parser.java
@@ -6,9 +6,9 @@
* 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
@@ -98,15 +98,15 @@ public class Parser {
try {
contextUriInfo.setQueryOption(parsedOption == null ? option : parsedOption);
} catch (final ODataRuntimeException e) {
- throw new UriParserSyntaxException(
- parsedOption instanceof SystemQueryOption ?
- "Double system query option!" :
- "Alias already specified! Name: " + optionName,
- e,
- parsedOption instanceof SystemQueryOption ?
- UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION :
- UriParserSyntaxException.MessageKeys.DUPLICATED_ALIAS,
- optionName);
+ throw new UriParserSyntaxException(
+ parsedOption instanceof SystemQueryOption ?
+ "Double system query option!" :
+ "Alias already specified! Name: " + optionName,
+ e,
+ parsedOption instanceof SystemQueryOption ?
+ UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION :
+ UriParserSyntaxException.MessageKeys.DUPLICATED_ALIAS,
+ optionName);
}
}
@@ -209,7 +209,7 @@ public class Parser {
parseOrderByOption(contextUriInfo.getOrderByOption(), contextType,
contextUriInfo.getEntitySetNames(), contextUriInfo.getAliasMap());
parseExpandOption(contextUriInfo.getExpandOption(), contextType,
- !contextUriInfo.getEntitySetNames().isEmpty() || contextUriInfo.getKind() == UriInfoKind.all,
+ contextUriInfo.getKind() == UriInfoKind.all, contextUriInfo.getEntitySetNames(),
contextUriInfo.getAliasMap());
parseSelectOption(contextUriInfo.getSelectOption(), contextType, contextIsCollection);
@@ -335,16 +335,18 @@ public class Parser {
}
}
- private void parseExpandOption(ExpandOption expandOption, final EdmType contextType, final boolean isCrossjoinOrAll,
- final Map<String, AliasQueryOption> aliases) throws UriParserException, UriValidationException {
+ private void parseExpandOption(ExpandOption expandOption, final EdmType contextType, final boolean isAll,
+ final List<String> entitySetNames, final Map<String, AliasQueryOption> aliases) throws UriParserException,
+ UriValidationException {
if (expandOption != null) {
- if (!(contextType instanceof EdmStructuredType || isCrossjoinOrAll)) {
+ if (!(contextType instanceof EdmStructuredType || isAll
+ || (entitySetNames != null && !entitySetNames.isEmpty()))) {
throw new UriValidationException("Expand is only allowed on structured types!",
UriValidationException.MessageKeys.SYSTEM_QUERY_OPTION_NOT_ALLOWED, expandOption.getName());
}
final String optionValue = expandOption.getText();
UriTokenizer expandTokenizer = new UriTokenizer(optionValue);
- final ExpandOption option = new ExpandParser(edm, odata, aliases).parse(expandTokenizer,
+ final ExpandOption option = new ExpandParser(edm, odata, aliases, entitySetNames).parse(expandTokenizer,
contextType instanceof EdmStructuredType ? (EdmStructuredType) contextType : null);
checkOptionEOF(expandTokenizer, expandOption.getName(), optionValue);
for (final ExpandItem item : option.getExpandItems()) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5d1e823/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
index 32c56b4..64cf757 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/TestFullResourcePath.java
@@ -947,6 +947,27 @@ public class TestFullResourcePath {
}
@Test
+ public void crossjoinExpand() throws Exception {
+ testUri.run("$crossjoin(ESTwoPrim,ESAllPrim)",
+ "$expand=ESTwoPrim")
+ .goExpand()
+ .first().goPath().first().isEntitySet("ESTwoPrim");
+
+ testUri.run("$crossjoin(ESTwoPrim,ESAllPrim)",
+ "$expand=ESTwoPrim,ESAllPrim")
+ .goExpand()
+ .first().goPath().first().isEntitySet("ESTwoPrim")
+ .goUpExpandValidator().next().goPath().first().isEntitySet("ESAllPrim");
+
+ //TODO: Once crossjoin is implemented these tests should no longer result in errors
+// testUri.run("$crossjoin(ESTwoPrim,ESAllPrim)",
+// "$expand=ESAllPrim/NavPropertyETTwoPrimOne")
+// .goExpand()
+// .first().goPath().at(0).isEntitySet("ESAllPrim")
+// .at(1).isNavProperty("NavPropertyETTwoPrimOne", new FullQualifiedName("Namespace1_Alias.ETTwoPrim"), false);
+ }
+
+ @Test
public void crossjoinError() throws Exception {
testUri.runEx("$crossjoin").isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
testUri.runEx("$crossjoin/error").isExSyntax(UriParserSyntaxException.MessageKeys.MUST_BE_LAST_SEGMENT);