Repository: olingo-odata2 Updated Branches: refs/heads/master 48b8d3ee3 -> 2e18476aa
[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/2e18476a Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/2e18476a Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/2e18476a Branch: refs/heads/master Commit: 2e18476aa6d5f0c57ab50631b0389aa56426722f Parents: 48b8d3e Author: Archana Rai <archana....@sap.com> Authored: Mon Apr 23 11:58:34 2018 +0530 Committer: Archana Rai <archana....@sap.com> Committed: Mon Apr 23 11:58:34 2018 +0530 ---------------------------------------------------------------------- .../odata2/api/ep/EntityProviderException.java | 6 +- .../core/edm/Impl/EdmEntityContainerImpl.java | 2 +- .../core/edm/Impl/EdmFunctionImportImpl.java | 6 +- .../deserializer/XmlMetadataDeserializer.java | 19 +- ...LMetadataFunctionImportDeserializerTest.java | 260 ++++++++++++++++ .../core/ep/consumer/XmlMetadataConsumer.java | 17 +- .../olingo/odata2/core/uri/UriParserImpl.java | 73 +++-- .../src/main/resources/i18n.properties | 1 + .../ep/consumer/XmlMetadataConsumerTest.java | 312 +++++++++++++++++++ .../olingo/odata2/core/uri/UriParserTest.java | 4 + .../olingo/odata2/testutil/mock/EdmMock.java | 4 + 11 files changed, 660 insertions(+), 44 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderException.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderException.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderException.java index cc65e67..ed97771 100644 --- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderException.java +++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderException.java @@ -113,7 +113,11 @@ public class EntityProviderException extends ODataMessageException { public static final MessageReference INVALID_DELETED_ENTRY_METADATA = createMessageReference( EntityProviderException.class, "INVALID_DELETED_ENTRY_METADATA"); - + + /** INVALID_ATTRIBUTE found ('invalid attribute name') */ + public static final MessageReference INVALID_ATTRIBUTE = createMessageReference(EntityProviderException.class, + "INVALID_ATTRIBUTE"); + public EntityProviderException(final MessageReference messageReference) { super(messageReference); } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/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 bed4d44..2a95ef9 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 @@ -129,7 +129,7 @@ public class EdmEntityContainerImpl implements EdmEntityContainer, EdmAnnotatabl public EdmEntitySet getEntitySet(final String name) throws EdmException { EdmEntitySet edmEntitySet = null; for(EdmEntitySet entity:edmEntitySets){ - if(name.equals(entity.getName())){ + if(entity.getName().equals(name)){ edmEntitySet = entity; } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/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 8521ad7..99f2f15 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 @@ -144,7 +144,11 @@ public class EdmFunctionImportImpl extends EdmNamedImpl implements EdmFunctionIm @Override public EdmEntitySet getEntitySet() throws EdmException { - return edmEntityContainer.getEntitySet(entitySet); + if(edmEntityContainer != null){ + return edmEntityContainer.getEntitySet(entitySet); + }else{ + return null; + } } @Override http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/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 73d62c1..3b470a6 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 @@ -544,22 +544,33 @@ public class XmlMetadataDeserializer { EdmAnnotationsImpl annotations = new EdmAnnotationsImpl(); Map<String, EdmParameter> edmParamMap = new HashMap<String, EdmParameter>(); List<String> parametersList = new ArrayList<String>(); - + FullQualifiedName fqName ; function.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME)); function.setHttpMethod(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, XmlMetadataConstants.EDM_FUNCTION_IMPORT_HTTP_METHOD)); - function.setEntitySet(reader.getAttributeValue(null, XmlMetadataConstants.EDM_ENTITY_SET)); + String entitySet = reader.getAttributeValue(null, XmlMetadataConstants.EDM_ENTITY_SET); + function.setEntitySet(entitySet); String returnTypeString = reader.getAttributeValue(null, XmlMetadataConstants.EDM_FUNCTION_IMPORT_RETURN); EdmTypedImpl returnType = new EdmTypedImpl(); if (returnTypeString != null) { if (returnTypeString.startsWith("Collection") || returnTypeString.startsWith("collection")) { - returnType.setMultiplicity(EdmMultiplicity.MANY); 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); } - FullQualifiedName fqName = extractFQName(returnTypeString); returnType.setTypeName(fqName); ((EdmNamedImpl) returnType).setName(fqName.getName()); ((EdmNamedImpl) returnType).setEdm(edm); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/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 eb3d89f..50788e2 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 @@ -359,6 +359,266 @@ public class XMLMetadataFunctionImportDeserializerTest { } } +//Function Import with return type as entity type and entityset attribute set + @Test + public void testFunctionImportEntity() 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>"; + 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 not set + @Test + public void testFunctionImportEntityWithoutEntitySet() 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\" " + + " 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>"; + 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()); + EdmFunctionImport functionImport1 = container.getFunctionImport("EmployeeSearch"); + + assertEquals("EmployeeSearch", functionImport1.getName()); + assertNull(functionImport1.getEntitySet()); + assertEquals("GET", functionImport1.getHttpMethod()); + } + } + } + + //Function Import with return type collection of complex type and entityset attribute not set + @Test + public void testFunctionImportCollection() 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= \"Room\" >" + + "<Key><PropertyRef Name=\"RoomId\"/></Key>" + + "<Property Name=\"" + + "RoomId" + + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<Property Name=\"" + + propertyNames[2] + + "\" Type=\"Edm.String\" />" + + "</EntityType>" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Rooms\" EntityType=\"RefScenario.Room\"/>" + + "<FunctionImport Name=\"LocationSearch\" ReturnType=\"Collection(RefScenario.Location)\" " + + " m:HttpMethod=\"GET\">" + + "<Parameter Name=\"q1\" Type=\"Edm.String\" Nullable=\"true\" Mode=\"In\"/>" + + "<Parameter Name=\"q2\" Type=\"Edm.Int32\" Nullable=\"false\" />" + + "</FunctionImport>" + + "</EntityContainer>" + "</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 functionImport2 = container.getFunctionImport("LocationSearch"); + assertEquals("LocationSearch", functionImport2.getName()); + assertNull(functionImport2.getEntitySet()); + assertEquals(EdmMultiplicity.MANY, functionImport2.getReturnType().getMultiplicity()); + assertEquals("GET", functionImport2.getHttpMethod()); + assertEquals(EdmMultiplicity.MANY, functionImport2.getReturnType().getMultiplicity()); + } + } + } + //Function import returning collection of entitysets must have entityset attribute defined + @Test(expected = EntityProviderException.class) + public void testFunctionImportCollError() 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=\"Collection(RefScenario.Employee)\" " + + " 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>"; + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmWithEntityContainer); + parser.readMetadata(reader, true); + } + + //Function import returning complextype or edmsimpletype must not have entityset attribute + @Test(expected = EntityProviderException.class) + public void testFunctionImportError() 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=\"NoReturn\" " + + "EntitySet=\"Rooms\" m:HttpMethod=\"GET\"/>" + + "<FunctionImport Name=\"SingleRoomReturnType\" ReturnType=\"RefScenario.Room\" " + + "EntitySet=\"Rooms\" m:HttpMethod=\"GET\">" + + "</FunctionImport>" + + "</EntityContainer>" + "</Schema>" + "</edmx:DataServices>" + "</edmx:Edmx>"; + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmWithEntityContainer); + parser.readMetadata(reader, true); + } +//Function import returning complextype or edmsimpletype must not have entityset attribute positive flow + @Test + public void testFunctionImportProperty() 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=\"GetId\" ReturnType=\"Edm.String\"" + + " m:HttpMethod=\"GET\"/>" + + "</EntityContainer>" + "</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()) { + EdmFunctionImport functionImport4 = container.getFunctionImport("GetId"); + assertEquals("GetId", functionImport4.getName()); + assertNull(functionImport4.getEntitySet()); + } + } + } + /** * @param i * @param functionImport http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/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 160fdf6..92f57c7 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 @@ -257,7 +257,7 @@ public class XmlMetadataConsumer { FunctionImport function = new FunctionImport(); List<FunctionImportParameter> functionParameters = new ArrayList<FunctionImportParameter>(); List<AnnotationElement> annotationElements = new ArrayList<AnnotationElement>(); - + FullQualifiedName fqName; function.setName(reader.getAttributeValue(null, XmlMetadataConstants.EDM_NAME)); function.setHttpMethod(reader.getAttributeValue(Edm.NAMESPACE_M_2007_08, XmlMetadataConstants.EDM_FUNCTION_IMPORT_HTTP_METHOD)); @@ -267,12 +267,23 @@ public class XmlMetadataConsumer { if (returnTypeString != null) { ReturnType returnType = new ReturnType(); if (returnTypeString.startsWith("Collection") || returnTypeString.startsWith("collection")) { - returnType.setMultiplicity(EdmMultiplicity.MANY); 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); } - FullQualifiedName fqName = extractFQName(returnTypeString); + fqName = extractFQName(returnTypeString); returnType.setTypeName(fqName); function.setReturnType(returnType); } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java index b7e9c18..ac1927e 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/uri/UriParserImpl.java @@ -545,42 +545,47 @@ public class UriParserImpl extends UriParser { private void handleFunctionImport(final EdmFunctionImport functionImport, final String emptyParentheses, final String keyPredicate) throws UriSyntaxException, UriNotMatchingException, EdmException { final EdmTyped returnType = functionImport.getReturnType(); - final EdmType type = returnType.getType(); - final boolean isCollection = returnType.getMultiplicity() == EdmMultiplicity.MANY; - - if (type.getKind() == EdmTypeKind.ENTITY && isCollection) { - handleEntitySet(functionImport.getEntitySet(), keyPredicate); - return; - } - - if (emptyParentheses != null) { - throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(emptyParentheses)); - } - - uriResult.setTargetType(type); - switch (type.getKind()) { - case SIMPLE: - uriResult.setUriType(isCollection ? UriType.URI13 : UriType.URI14); - break; - case COMPLEX: - uriResult.setUriType(isCollection ? UriType.URI11 : UriType.URI12); - break; - case ENTITY: - uriResult.setUriType(UriType.URI10); - break; - default: - throw new UriSyntaxException(UriSyntaxException.INVALIDRETURNTYPE.addContent(type.getKind())); - } - - if (!pathSegments.isEmpty()) { - if (uriResult.getUriType() == UriType.URI14) { - currentPathSegment = pathSegments.remove(0); - if ("$value".equals(percentDecode(currentPathSegment))) { - uriResult.setValue(true); - } else { - throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(currentPathSegment)); + + if (returnType != null && returnType.getType() != null) { + final EdmType type = returnType.getType(); + final boolean isCollection = returnType.getMultiplicity() == EdmMultiplicity.MANY; + + if (type.getKind() == EdmTypeKind.ENTITY && isCollection) { + handleEntitySet(functionImport.getEntitySet(), keyPredicate); + return; + } + + if (emptyParentheses != null) { + throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(emptyParentheses)); + } + + uriResult.setTargetType(type); + switch (type.getKind()) { + case SIMPLE: + uriResult.setUriType(isCollection ? UriType.URI13 : UriType.URI14); + break; + case COMPLEX: + uriResult.setUriType(isCollection ? UriType.URI11 : UriType.URI12); + break; + case ENTITY: + uriResult.setUriType(UriType.URI10); + break; + default: + throw new UriSyntaxException(UriSyntaxException.INVALIDRETURNTYPE.addContent(type.getKind())); + } + + if (!pathSegments.isEmpty()) { + if (uriResult.getUriType() == UriType.URI14) { + currentPathSegment = pathSegments.remove(0); + if ("$value".equals(percentDecode(currentPathSegment))) { + uriResult.setValue(true); + } else { + throw new UriSyntaxException(UriSyntaxException.INVALIDSEGMENT.addContent(currentPathSegment)); + } } } + } else { + uriResult.setUriType(UriType.URI14); } ensureLastSegment(); } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/odata2-lib/odata-core/src/main/resources/i18n.properties ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/resources/i18n.properties b/odata2-lib/odata-core/src/main/resources/i18n.properties index 375b6b8..508925d 100644 --- a/odata2-lib/odata-core/src/main/resources/i18n.properties +++ b/odata2-lib/odata-core/src/main/resources/i18n.properties @@ -123,6 +123,7 @@ org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_DELETED_ENTRY_ME org.apache.olingo.odata2.api.ep.EntityProviderException.NULL_VALUE=Entity or expanded entity cannot have null value. org.apache.olingo.odata2.api.ep.EntityProviderException.INCORRECT_NAVIGATION_TYPE=Navigation has to be either an Entity or a Map. org.apache.olingo.odata2.api.ep.EntityProviderException.MANDATORY_WRITE_PROPERTY=Write properties are mandatory for XML. +org.apache.olingo.odata2.api.ep.EntityProviderException.INVALID_ATTRIBUTE=Invalid attribute '%1$s' found at tag '%2$s'. ################################## # BatchParserexceptions http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/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 9c4877c..54f7d4b 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 @@ -839,6 +839,15 @@ public class XmlMetadataConsumerTest extends AbstractXmlConsumerTest { + propertyNames[1] + "\" Type=\"Edm.String\" m:FC_TargetPath=\"SyndicationTitle\"/>" + "</EntityType>" + + "<EntityType Name= \"Room\" >" + + "<Key><PropertyRef Name=\"RoomId\"/></Key>" + + "<Property Name=\"" + + "RoomId" + + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<Property Name=\"" + + propertyNames[2] + + "\" Type=\"Edm.String\" />" + + "</EntityType>" + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + "<FunctionImport Name=\"EmployeeSearch\" ReturnType=\"Collection(RefScenario.Employee)\" " + @@ -936,6 +945,309 @@ public class XmlMetadataConsumerTest extends AbstractXmlConsumerTest { } } +//Function Import with return type as entity type and entityset attribute set + @Test + public void testFunctionImportEntity() 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 + + "\">" + + "<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>"; + 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 { + 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\" " + + " 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>"; + 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(null, 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 collection of complex type and entityset attribute not set + @Test + public void testFunctionImportCollection() 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 + + "\">" + + "<EntityType Name= \"Room\" >" + + "<Key><PropertyRef Name=\"RoomId\"/></Key>" + + "<Property Name=\"" + + "RoomId" + + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<Property Name=\"" + + propertyNames[2] + + "\" Type=\"Edm.String\" />" + + "</EntityType>" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Rooms\" EntityType=\"RefScenario.Room\"/>" + + "<FunctionImport Name=\"LocationSearch\" ReturnType=\"Collection(RefScenario.Location)\" " + + " m:HttpMethod=\"GET\">" + + "<Parameter Name=\"q1\" Type=\"Edm.String\" Nullable=\"true\" Mode=\"In\"/>" + + "<Parameter Name=\"q2\" Type=\"Edm.Int32\" Nullable=\"false\" />" + + "</FunctionImport>" + + "</EntityContainer>" + "</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 functionImport2 = container.getFunctionImports().get(0); + assertEquals("LocationSearch", functionImport2.getName()); + assertEquals(null, functionImport2.getEntitySet()); + assertEquals(NAMESPACE, functionImport2.getReturnType().getTypeName().getNamespace()); + assertEquals("Location", functionImport2.getReturnType().getTypeName().getName()); + assertEquals(EdmMultiplicity.MANY, functionImport2.getReturnType().getMultiplicity()); + assertEquals("GET", functionImport2.getHttpMethod()); + assertEquals(2, functionImport2.getParameters().size()); + assertEquals(new FullQualifiedName("RefScenario", "Location"), + functionImport2.getReturnType().getTypeName()); + assertEquals(EdmMultiplicity.MANY, functionImport2.getReturnType().getMultiplicity()); + + FunctionImportParameter functionImportParameter = functionImport2.getParameters().get(0); + assertEquals("q1", functionImportParameter.getName()); + assertEquals(EdmSimpleTypeKind.String, functionImport2.getParameters().get(0).getType()); + assertEquals(Boolean.TRUE, functionImport2.getParameters().get(0).getFacets().isNullable()); + assertEquals("In", functionImportParameter.getMode()); + + assertEquals("q2", functionImport2.getParameters().get(1).getName()); + assertEquals(EdmSimpleTypeKind.Int32, functionImport2.getParameters().get(1).getType()); + assertEquals(Boolean.FALSE, functionImport2.getParameters().get(1).getFacets().isNullable()); + assertEquals(null, functionImport2.getParameters().get(1).getMode()); + + + } + } + } + //Function import returning collection of entitysets must have entityset attribute defined + @Test(expected = EntityProviderException.class) + public void testFunctionImportCollError() 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 + + "\">" + + "<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=\"Collection(RefScenario.Employee)\" " + + " 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>"; + XmlMetadataConsumer parser = new XmlMetadataConsumer(); + XMLStreamReader reader = createStreamReader(xmWithEntityContainer); + parser.readMetadata(reader, true); + } + + //Function import returning complextype or edmsimpletype must not have entityset attribute + @Test(expected = EntityProviderException.class) + public void testFunctionImportError() 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 + + "\">" + + "<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=\"NoReturn\" " + + "EntitySet=\"Rooms\" m:HttpMethod=\"GET\"/>" + + "<FunctionImport Name=\"SingleRoomReturnType\" ReturnType=\"RefScenario.Room\" " + + "EntitySet=\"Rooms\" m:HttpMethod=\"GET\">" + + "</FunctionImport>" + + "</EntityContainer>" + "</Schema>" + "</edmx:DataServices>" + "</edmx:Edmx>"; + XmlMetadataConsumer parser = new XmlMetadataConsumer(); + XMLStreamReader reader = createStreamReader(xmWithEntityContainer); + parser.readMetadata(reader, true); + } +//Function import returning complextype or edmsimpletype must not have entityset attribute positive flow + @Test + public void testFunctionImportProperty() 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 + + "\">" + + "<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=\"GetId\" ReturnType=\"Edm.String\"" + + " m:HttpMethod=\"GET\"/>" + + "</EntityContainer>" + "</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()) { + FunctionImport functionImport4 = container.getFunctionImports().get(0); + assertEquals("GetId", functionImport4.getName()); + List<FunctionImportParameter> parameters4 = functionImport4.getParameters(); + assertNotNull(parameters4); + assertEquals(0, parameters4.size()); + assertEquals("String", functionImport4.getReturnType().getTypeName().getName()); + } + } + } + @Test() public void testAlias() throws XMLStreamException, EntityProviderException { final String xml = http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java index a4b095c..f08012a 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/uri/UriParserTest.java @@ -711,6 +711,10 @@ public class UriParserTest extends BaseTest { result = parse("OldestEmployee"); assertEquals("OldestEmployee", result.getFunctionImport().getName()); assertEquals(UriType.URI10, result.getUriType()); + + result = parse("SetEmployee"); + assertEquals("SetEmployee", result.getFunctionImport().getName()); + assertEquals(UriType.URI14, result.getUriType()); } @Test http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/2e18476a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/EdmMock.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/EdmMock.java b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/EdmMock.java index 20290c0..de1506e 100644 --- a/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/EdmMock.java +++ b/odata2-lib/odata-testutil/src/main/java/org/apache/olingo/odata2/testutil/mock/EdmMock.java @@ -242,6 +242,10 @@ class EdmMock { EdmFunctionImport oldestEmployeeFunctionImport = createFunctionImportMock(defaultContainer, "OldestEmployee", employeeType, EdmMultiplicity.ONE); when(oldestEmployeeFunctionImport.getEntitySet()).thenReturn(employeeEntitySet); + EdmFunctionImport employeeActionImport = + createFunctionImportMock(defaultContainer, "SetEmployee", null, EdmMultiplicity.ONE); + when(employeeActionImport.getEntitySet()).thenReturn(employeeEntitySet); + when(employeeActionImport.getHttpMethod()).thenReturn(ODataHttpMethod.POST.name()); // Issue with not explicitly nullable parameters and facets EdmFunctionImport functionImportNullableParameter =