Repository: olingo-odata2 Updated Branches: refs/heads/master 53b631bff -> 8d1b23f90
[Olingo-1259]Function Import enhancements Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/8d1b23f9 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/8d1b23f9 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/8d1b23f9 Branch: refs/heads/master Commit: 8d1b23f902bf3771a2c23ee0c31cd6bdf0b0a203 Parents: 53b631b Author: Archana Rai <archana....@sap.com> Authored: Mon Jun 4 18:04:13 2018 +0530 Committer: Archana Rai <archana....@sap.com> Committed: Mon Jun 4 18:04:13 2018 +0530 ---------------------------------------------------------------------- .../core/edm/Impl/EdmEntityContainerImpl.java | 3 +- .../core/edm/Impl/EdmFunctionImportImpl.java | 4 ++ .../deserializer/XmlMetadataDeserializer.java | 37 ++++++++---- ...LMetadataFunctionImportDeserializerTest.java | 57 ++++++++++++++++++- .../core/ep/consumer/XmlMetadataConsumer.java | 35 ++++++++---- .../ep/consumer/XmlMetadataConsumerTest.java | 59 ++++++++++++++++++++ 6 files changed, 167 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8d1b23f9/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/edm/Impl/EdmEntityContainerImpl.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/edm/Impl/EdmEntityContainerImpl.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/edm/Impl/EdmEntityContainerImpl.java index 2a95ef9..1511a21 100644 --- a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/edm/Impl/EdmEntityContainerImpl.java +++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/edm/Impl/EdmEntityContainerImpl.java @@ -32,7 +32,6 @@ import org.apache.olingo.odata2.api.edm.EdmEntitySet; import org.apache.olingo.odata2.api.edm.EdmException; import org.apache.olingo.odata2.api.edm.EdmFunctionImport; import org.apache.olingo.odata2.api.edm.EdmNavigationProperty; -import org.apache.olingo.odata2.api.exception.ODataException; import org.apache.olingo.odata2.client.api.edm.ClientEdm; import org.apache.olingo.odata2.client.api.edm.EdmDocumentation; @@ -131,7 +130,7 @@ public class EdmEntityContainerImpl implements EdmEntityContainer, EdmAnnotatabl for(EdmEntitySet entity:edmEntitySets){ if(entity.getName().equals(name)){ edmEntitySet = entity; - + break; } } return edmEntitySet; http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8d1b23f9/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/edm/Impl/EdmFunctionImportImpl.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/edm/Impl/EdmFunctionImportImpl.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/edm/Impl/EdmFunctionImportImpl.java index 99f2f15..ff6cbca 100644 --- a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/edm/Impl/EdmFunctionImportImpl.java +++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/edm/Impl/EdmFunctionImportImpl.java @@ -99,6 +99,10 @@ public class EdmFunctionImportImpl extends EdmNamedImpl implements EdmFunctionIm this.edmEntityContainer = edmEntityContainer; } + public String getEntitySetName() { + return entitySet; + } + public Map<String, EdmParameter> getEdmParameters() { return edmParameters; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8d1b23f9/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataDeserializer.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataDeserializer.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataDeserializer.java index 3b470a6..f2d85b2 100644 --- a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataDeserializer.java +++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataDeserializer.java @@ -60,6 +60,7 @@ import org.apache.olingo.odata2.api.edm.EdmReferentialConstraintRole; import org.apache.olingo.odata2.api.edm.EdmSimpleType; import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind; import org.apache.olingo.odata2.api.edm.EdmTypeKind; +import org.apache.olingo.odata2.api.edm.EdmTyped; import org.apache.olingo.odata2.api.edm.FullQualifiedName; import org.apache.olingo.odata2.api.edm.provider.Facets; import org.apache.olingo.odata2.api.ep.EntityProviderException; @@ -125,7 +126,7 @@ public class XmlMetadataDeserializer { new HashMap<FullQualifiedName, FullQualifiedName>(); private Map<FullQualifiedName, FullQualifiedName> complexBaseTypeMap = new HashMap<FullQualifiedName, FullQualifiedName>(); - private List<EdmFunctionImport> edmFunctionImportList = new ArrayList<EdmFunctionImport>(); + private List<EdmFunctionImport> edmFunctionImportList = new ArrayList<EdmFunctionImport>(); private List<EdmEntitySet> edmEntitySetList = new ArrayList<EdmEntitySet>(); private List<EdmNavigationProperty> navProperties = new ArrayList<EdmNavigationProperty>(); private String currentHandledStartTagName; @@ -556,21 +557,11 @@ public class XmlMetadataDeserializer { if (returnTypeString != null) { if (returnTypeString.startsWith("Collection") || returnTypeString.startsWith("collection")) { returnTypeString = returnTypeString.substring(returnTypeString.indexOf("(") + 1, returnTypeString.length() - 1); - fqName = extractFQName(returnTypeString); - if(entitySet == null && entityTypesMap.get(fqName) != null){ - throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent - ("EntitySet = "+entitySet, XmlMetadataConstants.EDM_FUNCTION_IMPORT +" = "+ function.getName())); - } returnType.setMultiplicity(EdmMultiplicity.MANY); } else { - fqName = extractFQName(returnTypeString); - if(entitySet != null && entityTypesMap.get(fqName) == null) { - throw new EntityProviderException(EntityProviderException.INVALID_ATTRIBUTE.addContent - ("EntitySet = "+entitySet, XmlMetadataConstants.EDM_FUNCTION_IMPORT - + " = "+ function.getName())); - } returnType.setMultiplicity(EdmMultiplicity.ONE); } + fqName = extractFQName(returnTypeString); returnType.setTypeName(fqName); ((EdmNamedImpl) returnType).setName(fqName.getName()); ((EdmNamedImpl) returnType).setEdm(edm); @@ -1557,6 +1548,27 @@ public class XmlMetadataDeserializer { } } + private void validateFunctionImport() throws EntityProviderException, EdmException { + for (EdmFunctionImport functionImport : edmFunctionImportList) { + EdmTyped returnType = functionImport.getReturnType(); + if (returnType != null) { + FullQualifiedName fqn = extractFQName(returnType.toString()); + String entitySet = ((EdmFunctionImportImpl)functionImport).getEntitySetName(); + if (returnType.getMultiplicity() == EdmMultiplicity.MANY && entitySet == null && entityTypesMap.get( + fqn) != null) { + throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent("EntitySet = " + + entitySet, XmlMetadataConstants.EDM_FUNCTION_IMPORT + " = " + functionImport.getName())); + } else if (returnType.getMultiplicity() != EdmMultiplicity.MANY && entitySet != null && entityTypesMap.get( + fqn) == null) { + throw new EntityProviderException(EntityProviderException.INVALID_ATTRIBUTE.addContent("EntitySet = " + + entitySet, XmlMetadataConstants.EDM_FUNCTION_IMPORT + + " = " + functionImport.getName())); + } + } + } + } + + private void validate() throws EntityProviderException, EdmException { checkMandatoryNamespacesAvailable(); validateEntityTypes(); @@ -1564,6 +1576,7 @@ public class XmlMetadataDeserializer { validateRelationship(); validateEntitySet(); validateAssociation(); + validateFunctionImport(); } private void initialize() { http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8d1b23f9/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XMLMetadataFunctionImportDeserializerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XMLMetadataFunctionImportDeserializerTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XMLMetadataFunctionImportDeserializerTest.java index 50788e2..10d3db4 100644 --- a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XMLMetadataFunctionImportDeserializerTest.java +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XMLMetadataFunctionImportDeserializerTest.java @@ -374,6 +374,14 @@ public class XMLMetadataFunctionImportDeserializerTest { + "\" xmlns=\"" + Edm.NAMESPACE_EDM_2008_09 + "\">" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + + "<FunctionImport Name=\"EmployeeSearch\" ReturnType=\"RefScenario.Employee\" " + + "EntitySet=\"Employees\" m:HttpMethod=\"GET\">" + + "<Parameter Name=\"q1\" Type=\"Edm.String\" Nullable=\"true\" />" + + "<Parameter Name=\"q2\" Type=\"Edm.Int32\" Nullable=\"false\" />" + + "</FunctionImport>" + + "</EntityContainer>" + "<EntityType Name= \"Employee\" m:HasStream=\"true\">" + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + "<Property Name=\"" @@ -383,14 +391,58 @@ public class XMLMetadataFunctionImportDeserializerTest { + propertyNames[1] + "\" Type=\"Edm.String\" m:FC_TargetPath=\"SyndicationTitle\"/>" + "</EntityType>" - + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "</Schema>" + "</edmx:DataServices>" + "</edmx:Edmx>"; + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmWithEntityContainer); + EdmDataServices result = parser.readMetadata(reader, true); + for (EdmSchema schema : result.getEdm().getSchemas()) { + for (EdmEntityContainer container : schema.getEntityContainers()) { + assertEquals("Container1", container.getName()); + assertEquals(Boolean.TRUE, container.isDefaultEntityContainer()); + + EdmFunctionImport functionImport1 = container.getFunctionImport("EmployeeSearch"); + + assertEquals("EmployeeSearch", functionImport1.getName()); + assertEquals("Employees", functionImport1.getEntitySet().getName()); + assertEquals(EdmMultiplicity.ONE, functionImport1.getReturnType().getMultiplicity()); + assertEquals("GET", functionImport1.getHttpMethod()); + } + } + } + +//Function Import with return type as entity type and entityset attribute set + @Test + public void testFunctionImportEntityOrderChange() throws Exception { + final String xmWithEntityContainer = + "<edmx:Edmx Version=\"1.0\" xmlns:edmx=\"" + + Edm.NAMESPACE_EDMX_2007_06 + + "\">" + + "<edmx:DataServices m:DataServiceVersion=\"2.0\" xmlns:m=\"" + + Edm.NAMESPACE_M_2007_08 + + "\">" + + "<Schema Namespace=\"" + + NAMESPACE + + "\" xmlns=\"" + + Edm.NAMESPACE_EDM_2008_09 + + "\">" + + "<EntityType Name= \"Employee\" m:HasStream=\"true\">" + + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + + "<Property Name=\"" + + propertyNames[0] + + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<Property Name=\"" + + propertyNames[1] + + "\" Type=\"Edm.String\" m:FC_TargetPath=\"SyndicationTitle\"/>" + + "</EntityType>" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + "<FunctionImport Name=\"EmployeeSearch\" ReturnType=\"RefScenario.Employee\" " + "EntitySet=\"Employees\" m:HttpMethod=\"GET\">" + "<Parameter Name=\"q1\" Type=\"Edm.String\" Nullable=\"true\" />" + "<Parameter Name=\"q2\" Type=\"Edm.Int32\" Nullable=\"false\" />" + "</FunctionImport>" - + "</EntityContainer>" + "</Schema>" + "</edmx:DataServices>" + "</edmx:Edmx>"; + + "</EntityContainer>" + + "</Schema>" + "</edmx:DataServices>" + "</edmx:Edmx>"; XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); InputStream reader = createStreamReader(xmWithEntityContainer); EdmDataServices result = parser.readMetadata(reader, true); @@ -409,6 +461,7 @@ public class XMLMetadataFunctionImportDeserializerTest { } } + //Function Import with return type as entity type and entityset attribute not set @Test public void testFunctionImportEntityWithoutEntitySet() throws Exception { http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8d1b23f9/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlMetadataConsumer.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlMetadataConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlMetadataConsumer.java index 92f57c7..e6dea17 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlMetadataConsumer.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlMetadataConsumer.java @@ -78,6 +78,7 @@ public class XmlMetadataConsumer { private Map<FullQualifiedName, Association> associationsMap = new HashMap<FullQualifiedName, Association>(); private Map<FullQualifiedName, EntityContainer> containerMap = new HashMap<FullQualifiedName, EntityContainer>(); private List<NavigationProperty> navProperties = new ArrayList<NavigationProperty>(); + private List<FunctionImport> edmFunctionImportList = new ArrayList<FunctionImport>(); private String currentHandledStartTagName; private String currentNamespace; private String edmNamespace = Edm.NAMESPACE_EDM_2008_09; @@ -246,7 +247,7 @@ public class XmlMetadataConsumer { container.setAnnotationElements(annotationElements); } container.setEntitySets(entitySets).setAssociationSets(associationSets).setFunctionImports(functionImports); - + edmFunctionImportList.addAll(functionImports); containerMap.put(new FullQualifiedName(currentNamespace, container.getName()), container); return container; } @@ -268,19 +269,8 @@ public class XmlMetadataConsumer { ReturnType returnType = new ReturnType(); if (returnTypeString.startsWith("Collection") || returnTypeString.startsWith("collection")) { returnTypeString = returnTypeString.substring(returnTypeString.indexOf("(") + 1, returnTypeString.length() - 1); - fqName = extractFQName(returnTypeString); - if(function.getEntitySet() == null && entityTypesMap.get(fqName) != null){ - throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent - ("EntitySet = "+function.getEntitySet(), XmlMetadataConstants.EDM_FUNCTION_IMPORT + function.getName())); - } returnType.setMultiplicity(EdmMultiplicity.MANY); } else { - fqName = extractFQName(returnTypeString); - if(function.getEntitySet() != null && entityTypesMap.get(fqName) == null) { - throw new EntityProviderException(EntityProviderException.INVALID_ATTRIBUTE.addContent - ("EntitySet = "+function.getEntitySet(), XmlMetadataConstants.EDM_FUNCTION_IMPORT - + " : "+ function.getName())); - } returnType.setMultiplicity(EdmMultiplicity.ONE); } fqName = extractFQName(returnTypeString); @@ -1088,6 +1078,26 @@ public class XmlMetadataConsumer { } } + + private void validateFunctionImport() throws EntityProviderException { + for (FunctionImport functionImport : edmFunctionImportList) { + ReturnType returnType = functionImport.getReturnType(); + if (returnType != null) { + String entitySet = functionImport.getEntitySet(); + FullQualifiedName fqn = returnType.getTypeName(); + if (returnType.getMultiplicity() == EdmMultiplicity.MANY && entitySet == null && entityTypesMap.get( + fqn) != null) { + throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent("EntitySet = " + + entitySet, XmlMetadataConstants.EDM_FUNCTION_IMPORT + " = " + functionImport.getName())); + } else if (returnType.getMultiplicity() != EdmMultiplicity.MANY && entitySet != null && entityTypesMap.get( + fqn) == null) { + throw new EntityProviderException(EntityProviderException.INVALID_ATTRIBUTE.addContent("EntitySet = " + + entitySet, XmlMetadataConstants.EDM_FUNCTION_IMPORT + + " = " + functionImport.getName())); + } + } + } + } private void validateAssociation() throws EntityProviderException { for (Map.Entry<FullQualifiedName, EntityContainer> container : containerMap.entrySet()) { @@ -1145,6 +1155,7 @@ public class XmlMetadataConsumer { validateRelationship(); validateEntitySet(); validateAssociation(); + validateFunctionImport(); } private void initialize() { http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/8d1b23f9/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlMetadataConsumerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlMetadataConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlMetadataConsumerTest.java index 54f7d4b..6b2ad73 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlMetadataConsumerTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlMetadataConsumerTest.java @@ -1004,6 +1004,65 @@ public class XmlMetadataConsumerTest extends AbstractXmlConsumerTest { } } + @Test + public void testFunctionImportEntityOrderChange() throws XMLStreamException, EntityProviderException { + final String xmWithEntityContainer = + "<edmx:Edmx Version=\"1.0\" xmlns:edmx=\"" + + Edm.NAMESPACE_EDMX_2007_06 + + "\">" + + "<edmx:DataServices m:DataServiceVersion=\"2.0\" xmlns:m=\"" + + Edm.NAMESPACE_M_2007_08 + + "\">" + + "<Schema Namespace=\"" + + NAMESPACE + + "\" xmlns=\"" + + Edm.NAMESPACE_EDM_2008_09 + + "\">" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + + "<FunctionImport Name=\"EmployeeSearch\" ReturnType=\"RefScenario.Employee\" " + + "EntitySet=\"Employees\" m:HttpMethod=\"GET\">" + + "<Parameter Name=\"q1\" Type=\"Edm.String\" Nullable=\"true\" />" + + "<Parameter Name=\"q2\" Type=\"Edm.Int32\" Nullable=\"false\" />" + + "</FunctionImport>" + + "</EntityContainer>" + + "<EntityType Name= \"Employee\" m:HasStream=\"true\">" + + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + + "<Property Name=\"" + + propertyNames[0] + + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<Property Name=\"" + + propertyNames[1] + + "\" Type=\"Edm.String\" m:FC_TargetPath=\"SyndicationTitle\"/>" + + "</EntityType>" + + "</Schema>" + "</edmx:DataServices>" + "</edmx:Edmx>"; + XmlMetadataConsumer parser = new XmlMetadataConsumer(); + XMLStreamReader reader = createStreamReader(xmWithEntityContainer); + DataServices result = parser.readMetadata(reader, true); + for (Schema schema : result.getSchemas()) { + for (EntityContainer container : schema.getEntityContainers()) { + assertEquals("Container1", container.getName()); + assertEquals(Boolean.TRUE, container.isDefaultEntityContainer()); + + FunctionImport functionImport1 = container.getFunctionImports().get(0); + + assertEquals("EmployeeSearch", functionImport1.getName()); + assertEquals("Employees", functionImport1.getEntitySet()); + assertEquals(NAMESPACE, functionImport1.getReturnType().getTypeName().getNamespace()); + assertEquals("Employee", functionImport1.getReturnType().getTypeName().getName()); + assertEquals(EdmMultiplicity.ONE, functionImport1.getReturnType().getMultiplicity()); + assertEquals("GET", functionImport1.getHttpMethod()); + assertEquals(2, functionImport1.getParameters().size()); + assertEquals("q1", functionImport1.getParameters().get(0).getName()); + assertEquals(EdmSimpleTypeKind.String, functionImport1.getParameters().get(0).getType()); + assertEquals(Boolean.TRUE, functionImport1.getParameters().get(0).getFacets().isNullable()); + assertEquals("q2", functionImport1.getParameters().get(1).getName()); + assertEquals(EdmSimpleTypeKind.Int32, functionImport1.getParameters().get(1).getType()); + assertEquals(Boolean.FALSE, functionImport1.getParameters().get(1).getFacets().isNullable()); + } + } + } + //Function Import with return type as entity type and entityset attribute not set @Test public void testFunctionImportEntityWithoutEntitySet() throws XMLStreamException, EntityProviderException {