Repository: olingo-odata4 Updated Branches: refs/heads/master 29d374740 -> bf4e34d87
ContextURLParser enhancement for deep contained URIs Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/bf4e34d8 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/bf4e34d8 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/bf4e34d8 Branch: refs/heads/master Commit: bf4e34d879ff1c2ee91d321c3a1197335438b5dc Parents: 29d3747 Author: Francesco Chicchiriccò <--global> Authored: Thu Jul 31 17:40:58 2014 +0200 Committer: Francesco Chicchiriccò <--global> Committed: Thu Jul 31 17:40:58 2014 +0200 ---------------------------------------------------------------------- .../AbstractStructuredInvocationHandler.java | 2 +- .../core/serialization/AbstractODataBinder.java | 59 +++++++++++--------- .../core/serialization/ContextURLParser.java | 14 ++++- .../serialization/ContextURLParserTest.java | 32 +++++++---- 4 files changed, 64 insertions(+), 43 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bf4e34d8/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java ---------------------------------------------------------------------- diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java index 168bece..6b54f02 100644 --- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java +++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java @@ -286,7 +286,7 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca protected Object getPropertyValue(final String name, final Type type) { try { Object res; - Class<?> ref = ClassUtils.getTypeClass(type); + final Class<?> ref = ClassUtils.getTypeClass(type); if (ref == EdmStreamValue.class) { if (streamedPropertyCache.containsKey(name)) { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bf4e34d8/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataBinder.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataBinder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataBinder.java index d3e0277..46aead4 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataBinder.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AbstractODataBinder.java @@ -362,42 +362,47 @@ public abstract class AbstractODataBinder implements CommonODataBinder { /** * Infer type name from various sources of information including Edm and context URL, if available. * + * @param candidateTypeName type name as provided by the service * @param contextURL context URL * @param metadataETag metadata ETag * @return Edm type information */ - private EdmType findType(final ContextURL contextURL, final String metadataETag) { + private EdmType findType(final String candidateTypeName, final ContextURL contextURL, final String metadataETag) { EdmType type = null; - if (client instanceof EdmEnabledODataClient && contextURL != null) { + if (client instanceof EdmEnabledODataClient) { final Edm edm = ((EdmEnabledODataClient) client).getEdm(metadataETag); - - if (contextURL.getDerivedEntity() == null) { - for (EdmSchema schema : edm.getSchemas()) { - final EdmEntityContainer container = schema.getEntityContainer(); - if (container != null) { - final EdmEntityType entityType = findEntityType(contextURL.getEntitySetOrSingletonOrType(), container); - - if (entityType != null) { - if (contextURL.getNavOrPropertyPath() == null) { - type = entityType; - } else { - final EdmNavigationProperty navProp = - entityType.getNavigationProperty(contextURL.getNavOrPropertyPath()); - - type = navProp == null - ? entityType - : navProp.getType(); + if (StringUtils.isNotBlank(candidateTypeName)) { + type = edm.getEntityType(new FullQualifiedName(candidateTypeName)); + } + if (type == null && contextURL != null) { + if (contextURL.getDerivedEntity() == null) { + for (EdmSchema schema : edm.getSchemas()) { + final EdmEntityContainer container = schema.getEntityContainer(); + if (container != null) { + final EdmEntityType entityType = findEntityType(contextURL.getEntitySetOrSingletonOrType(), container); + + if (entityType != null) { + if (contextURL.getNavOrPropertyPath() == null) { + type = entityType; + } else { + final EdmNavigationProperty navProp = + entityType.getNavigationProperty(contextURL.getNavOrPropertyPath()); + + type = navProp == null + ? entityType + : navProp.getType(); + } } } } + if (type == null) { + type = new EdmTypeInfo.Builder().setEdm(edm). + setTypeExpression(contextURL.getEntitySetOrSingletonOrType()).build().getType(); + } + } else { + type = edm.getEntityType(new FullQualifiedName(contextURL.getDerivedEntity())); } - if (type == null) { - type = new EdmTypeInfo.Builder().setEdm(edm). - setTypeExpression(contextURL.getEntitySetOrSingletonOrType()).build().getType(); - } - } else { - type = edm.getEntityType(new FullQualifiedName(contextURL.getDerivedEntity())); } } @@ -420,7 +425,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder { final URI base = resource.getContextURL() == null ? resource.getPayload().getBaseURI() : contextURL.getServiceRoot(); - final EdmType edmType = findType(contextURL, resource.getMetadataETag()); + final EdmType edmType = findType(resource.getPayload().getType(), contextURL, resource.getMetadataETag()); FullQualifiedName typeName = null; if (resource.getPayload().getType() == null) { if (edmType != null) { @@ -485,7 +490,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder { final String propertyName, final String propertyType) { FullQualifiedName typeName = null; - final EdmType type = findType(contextURL, metadataETag); + final EdmType type = findType(null, contextURL, metadataETag); if (type instanceof EdmStructuredType) { final EdmProperty edmProperty = ((EdmStructuredType) type).getStructuralProperty(propertyName); if (edmProperty != null) { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bf4e34d8/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java index baba109..c7f5ca5 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/ContextURLParser.java @@ -19,6 +19,8 @@ package org.apache.olingo.commons.core.serialization; import java.net.URI; +import java.util.ArrayList; +import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.olingo.commons.api.Constants; @@ -36,7 +38,9 @@ public class ContextURLParser { String contextURLasString = contextURL.toASCIIString(); + boolean isEntity = false; if (contextURLasString.endsWith("/$entity") || contextURLasString.endsWith("/@Element")) { + isEntity = true; builder.suffix(Suffix.ENTITY); contextURLasString = contextURLasString.replace("/$entity", StringUtils.EMPTY). replace("/@Element", StringUtils.EMPTY); @@ -69,13 +73,17 @@ public class ContextURLParser { } else { final int openParIdx = rest.indexOf('('); if (openParIdx == -1) { - firstToken = StringUtils.substringBefore(rest, "/"); + firstToken = StringUtils.substringBeforeLast(rest, "/"); entitySetOrSingletonOrType = firstToken; } else { - firstToken = StringUtils.substringBeforeLast(rest, ")") + ")"; + firstToken = isEntity ? rest : StringUtils.substringBeforeLast(rest, ")") + ")"; - entitySetOrSingletonOrType = firstToken.substring(0, openParIdx); + final List<String> parts = new ArrayList<String>(); + for (String split : firstToken.split("\\)/")) { + parts.add(split.replaceAll("\\(.*", "")); + } + entitySetOrSingletonOrType = StringUtils.join(parts, '/'); final int commaIdx = firstToken.indexOf(','); if (commaIdx != -1) { builder.selectList(firstToken.substring(openParIdx + 1, firstToken.length() - 1)); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/bf4e34d8/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java index 5a16da2..1375ab2 100644 --- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java +++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/serialization/ContextURLParserTest.java @@ -19,7 +19,6 @@ package org.apache.olingo.commons.core.serialization; import org.apache.olingo.commons.api.data.ContextURL; -import org.apache.olingo.commons.core.serialization.ContextURLParser; import org.junit.Test; import java.net.URI; @@ -68,10 +67,19 @@ public class ContextURLParserTest { contextURL = ContextURLParser.parse(URI.create("http://host/service/$metadata#Orders(4711)/Items/$entity")); - assertEquals("Orders", contextURL.getEntitySetOrSingletonOrType()); + assertEquals("Orders/Items", contextURL.getEntitySetOrSingletonOrType()); assertNull(contextURL.getDerivedEntity()); assertNull(contextURL.getSelectList()); - assertEquals("Items", contextURL.getNavOrPropertyPath()); + assertNull(contextURL.getNavOrPropertyPath()); + assertTrue(contextURL.isEntity()); + + contextURL = ContextURLParser.parse( + URI.create("http://host/service/$metadata#Users('user')/Messages('message')/Attachments/$entity")); + + assertEquals("Users/Messages/Attachments", contextURL.getEntitySetOrSingletonOrType()); + assertNull(contextURL.getDerivedEntity()); + assertNull(contextURL.getSelectList()); + assertNull(contextURL.getNavOrPropertyPath()); assertTrue(contextURL.isEntity()); // v3 @@ -98,7 +106,7 @@ public class ContextURLParserTest { @Test public void collectionOfDerivedEntities() { final ContextURL contextURL = ContextURLParser.parse( - URI.create("http://host/service/$metadata#Customers/Model.VipCustomer")); + URI.create("http://host/service/$metadata#Customers/Model.VipCustomer")); assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); assertEquals("Model.VipCustomer", contextURL.getDerivedEntity()); @@ -110,7 +118,7 @@ public class ContextURLParserTest { @Test public void derivedEntity() { final ContextURL contextURL = ContextURLParser.parse( - URI.create("http://host/service/$metadata#Customers/Model.VipCustomer/$entity")); + URI.create("http://host/service/$metadata#Customers/Model.VipCustomer/$entity")); assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); assertEquals("Model.VipCustomer", contextURL.getDerivedEntity()); @@ -122,7 +130,7 @@ public class ContextURLParserTest { @Test public void collectionOfProjectedEntities() { final ContextURL contextURL = ContextURLParser.parse( - URI.create("http://host/service/$metadata#Customers(Address,Orders)")); + URI.create("http://host/service/$metadata#Customers(Address,Orders)")); assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); assertNull(contextURL.getDerivedEntity()); @@ -134,7 +142,7 @@ public class ContextURLParserTest { @Test public void projectedEntity() { ContextURL contextURL = ContextURLParser.parse( - URI.create("http://host/service/$metadata#Customers(Name,Rating)/$entity")); + URI.create("http://host/service/$metadata#Customers(Name,Rating)/$entity")); assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); assertNull(contextURL.getDerivedEntity()); @@ -143,7 +151,7 @@ public class ContextURLParserTest { assertTrue(contextURL.isEntity()); contextURL = ContextURLParser.parse( - URI.create("http://host/service/$metadata#Customers(Name,Address/Country)")); + URI.create("http://host/service/$metadata#Customers(Name,Address/Country)")); assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); assertNull(contextURL.getDerivedEntity()); @@ -155,8 +163,8 @@ public class ContextURLParserTest { @Test public void collectionOfProjectedExpandedEntities() { final ContextURL contextURL = ContextURLParser.parse( - URI.create("http://host/service/$metadata#Employees/" - + "Sales.Manager(DirectReports,DirectReports+(FirstName,LastName))")); + URI.create("http://host/service/$metadata#Employees/" + + "Sales.Manager(DirectReports,DirectReports+(FirstName,LastName))")); assertEquals("Employees", contextURL.getEntitySetOrSingletonOrType()); assertEquals("Sales.Manager", contextURL.getDerivedEntity()); @@ -168,7 +176,7 @@ public class ContextURLParserTest { @Test public void propertyValue() { final ContextURL contextURL = ContextURLParser.parse( - URI.create("http://host/service/$metadata#Customers(1)/Addresses")); + URI.create("http://host/service/$metadata#Customers(1)/Addresses")); assertEquals("Customers", contextURL.getEntitySetOrSingletonOrType()); assertNull(contextURL.getDerivedEntity()); @@ -180,7 +188,7 @@ public class ContextURLParserTest { @Test public void CollectionOfComplexOrPrimitiveTypes() { final ContextURL contextURL = ContextURLParser.parse( - URI.create("http://host/service/$metadata#Collection(Edm.String)")); + URI.create("http://host/service/$metadata#Collection(Edm.String)")); assertEquals("Collection(Edm.String)", contextURL.getEntitySetOrSingletonOrType()); assertNull(contextURL.getDerivedEntity());
