http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlErrorDocumentTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlErrorDocumentTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlErrorDocumentTest.java new file mode 100644 index 0000000..2a255f1 --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlErrorDocumentTest.java @@ -0,0 +1,281 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * 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 + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ +package org.apache.olingo.odata2.client.core.ep.deserializer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.InputStream; +import java.util.Locale; + +import org.apache.olingo.odata2.api.ep.EntityProviderException; +import org.apache.olingo.odata2.api.processor.ODataErrorContext; +import org.apache.olingo.odata2.client.core.ep.deserializer.XmlErrorDocumentDeserializer; +import org.apache.olingo.odata2.testutil.helper.StringHelper; +import org.junit.Test; + +/** + * + */ +public class XmlErrorDocumentTest extends AbstractDeserializerTest { + + private static final String XML_ERROR_DOCUMENT_SIMPLE = + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</code>\n" + + "\t<message xml:lang=\"en-US\">Message</message>\n" + + "</error>"; + private static final String XML_ERROR_DOCUMENT_NULL_LOCALE = + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</code>\n" + + "\t<message xml:lang=\"\">Message</message>\n" + + "</error>"; + private static final String XML_ERROR_DOCUMENT_INNER_ERROR = + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</code>\n" + + "\t<message xml:lang=\"en-US\">Message</message>\n" + + "<innererror>Some InnerError</innererror>\n" + + "</error>"; + private static final String XML_ERROR_DOCUMENT_INNER_ERROR_COMPLEX = + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</code>\n" + + "\t<message xml:lang=\"en-US\">Message</message>\n" + + "<innererror>" + + "<moreInner>More Inner Error</moreInner>" + + "</innererror>\n" + + "</error>"; + private static final String XML_ERROR_DOCUMENT_INVALID_XML = + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</CODE>\n" + + "\t<message xml:lang=\"en-US\">Message</message>\n" + + "</error>"; + /* error document with name 'locale' instead of 'lang' for message object */ + private static final String XML_ERROR_DOCUMENT_UNKNOWN_CONTENT = + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</code>\n" + + "\t<message xml:locale=\"en-US\">Message</message>\n" + + "\t<privateMessage>Secret</privateMessage>\n" + + "</error>"; + /* error document without value for message object */ + private static final String XML_ERROR_DOCUMENT_EMPTY_MESSAGE = + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</code>\n" + + "\t<message xml:lang=\"en-US\" />\n" + + "</error>"; + private static final String XML_ERROR_DOCUMENT_MISSING_MESSAGE = + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</code>\n" + + "</error>"; + private static final String XML_ERROR_DOCUMENT_MISSING_CODE = + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<message xml:lang=\"en-US\">Message</message>\n" + + "</error>"; + private static final String XML_ERROR_DOCUMENT_MISSING_ERROR = + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<errorForMe xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</code>\n" + + "\t<message xml:lang=\"en-US\">Message</message>\n" + + "</errorForMe>"; + private XmlErrorDocumentDeserializer xedc = new XmlErrorDocumentDeserializer(); + + @Test + public void simpleErrorDocument() throws Exception { + InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_SIMPLE); + ODataErrorContext error = xedc.readError(in); + + assertEquals("Wrong content type", "application/xml", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong locale for lang", Locale.US, error.getLocale()); + } + + @Test + public void emptyMessage() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_EMPTY_MESSAGE); + + ODataErrorContext error = xedc.readError(in); + + assertEquals("Wrong content type", "application/xml", error.getContentType()); + assertEquals("Wrong message", "", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong locale for lang", Locale.US, error.getLocale()); + } + + @Test + public void localeNull() throws Exception { + InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_NULL_LOCALE); + ODataErrorContext error = xedc.readError(in); + + assertEquals("Wrong content type", "application/xml", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertNull("Expected NULL for locale", error.getLocale()); + } + + @Test + public void innerError() throws Exception { + InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_INNER_ERROR); + ODataErrorContext error = xedc.readError(in); + + assertEquals("Wrong content type", "application/xml", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong inner error", "Some InnerError", error.getInnerError()); + } + + @Test + public void innerErrorComplex() throws Exception { + InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_INNER_ERROR_COMPLEX); + ODataErrorContext error = xedc.readError(in); + + assertEquals("Wrong content type", "application/xml", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong inner error", "<moreInner>More Inner Error</moreInner>", error.getInnerError()); + } + + @Test + public void innerErrorComplexTwo() throws Exception { + String innerErrorText = "<firstTag>tagText</firstTag><secondTag>secondText</secondTag>"; + String innerError = "<innererror>" + innerErrorText + "</innererror>"; + String errorDocument = XML_ERROR_DOCUMENT_INNER_ERROR_COMPLEX.replaceAll( + "<innererror.*error>", innerError); + InputStream in = StringHelper.encapsulate(errorDocument); + ODataErrorContext error = xedc.readError(in); + + assertEquals("Wrong content type", "application/xml", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong inner error", innerErrorText, error.getInnerError()); + } + + @Test + public void innerErrorComplexMoreCharacters() throws Exception { + String innerErrorText = "\n\t<firstTag>tagText</firstTag>\n<secondTag>secondText</secondTag>\n"; + String innerError = "<innererror>" + innerErrorText + "</innererror>"; + String errorDocument = XML_ERROR_DOCUMENT_INNER_ERROR_COMPLEX.replaceAll( + "<innererror.*error>", innerError); + InputStream in = StringHelper.encapsulate(errorDocument); + ODataErrorContext error = xedc.readError(in); + + assertEquals("Wrong content type", "application/xml", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong inner error", innerErrorText, error.getInnerError()); + } + + @Test(expected = EntityProviderException.class) + public void invalidJson() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_INVALID_XML); + try { + xedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.INVALID_STATE, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidEmptyDocument() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(""); + try { + xedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals("Got wrong exception: " + e.getMessageReference().getKey(), + EntityProviderException.INVALID_STATE, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void nullParameter() throws EntityProviderException { + try { + xedc.readError(null); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.ILLEGAL_ARGUMENT, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidErrorDocumentUnknown() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_UNKNOWN_CONTENT); + try { + xedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.INVALID_CONTENT, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidErrorDocumentMissingError() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_MISSING_ERROR); + try { + xedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals("Got wrong exception: " + e.getMessageReference().getKey(), + EntityProviderException.INVALID_STATE, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidErrorDocumentMissingCode() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_MISSING_CODE); + try { + xedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals("Got wrong exception: " + e.getMessageReference().getKey(), + EntityProviderException.MISSING_PROPERTY, e.getMessageReference()); + assertTrue(e.getMessage().contains("code")); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidErrorDocumentMissingMessage() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_MISSING_MESSAGE); + try { + xedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals("Got wrong exception: " + e.getMessageReference().getKey(), + EntityProviderException.MISSING_PROPERTY, e.getMessageReference()); + assertTrue(e.getMessage().contains("message")); + throw e; + } + } +}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlFeedDeserializerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlFeedDeserializerTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlFeedDeserializerTest.java new file mode 100644 index 0000000..94dfde4 --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlFeedDeserializerTest.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * 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 + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ******************************************************************************/ +package org.apache.olingo.odata2.client.core.ep.deserializer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.List; + +import javax.xml.stream.XMLStreamException; + +import org.apache.olingo.odata2.api.edm.EdmEntitySet; +import org.apache.olingo.odata2.api.ep.EntityProviderException; +import org.apache.olingo.odata2.api.ep.entry.ODataEntry; +import org.apache.olingo.odata2.api.ep.feed.FeedMetadata; +import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed; +import org.apache.olingo.odata2.api.ep.feed.ODataFeed; +import org.apache.olingo.odata2.client.api.edm.ClientEdm; +import org.apache.olingo.odata2.client.api.edm.EdmDataServices; +import org.apache.olingo.odata2.client.api.ep.ContentTypeBasedDeserializer; +import org.apache.olingo.odata2.client.api.ep.DeserializerProperties; +import org.apache.olingo.odata2.client.api.ep.EntityStream; +import org.apache.olingo.odata2.client.core.ODataClientImpl; +import org.apache.olingo.odata2.testutil.mock.MockFacade; +import org.junit.Test; + +import junit.framework.Assert; + +public class XmlFeedDeserializerTest extends AbstractXmlDeserializerTest { + + public XmlFeedDeserializerTest(final StreamWriterImplType type) { + super(type); + } + + + + @Test + public void readLargeEmployeesFeed() throws Exception { + InputStream file = getFileAsStream("LargeEmployeeFeed.xml"); + assertNotNull(file); + EntityStream es = new EntityStream(); + es.setContent(file); + es.setReadProperties(DEFAULT_PROPERTIES); + ODataClientImpl client = new ODataClientImpl(); + ContentTypeBasedDeserializer deserializer = client.createDeserializer("application/atom+xml"); + ODataFeed feed = + deserializer.readFeed( MockFacade.getMockEdm().getDefaultEntityContainer() + .getEntitySet( + "Employees"), es); + assertNotNull(feed); + + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + } + + private InputStream createStreamReader(final String xml) throws + XMLStreamException, UnsupportedEncodingException { + return new ByteArrayInputStream(xml.getBytes("UTF-8")); + } + + @Test + public void readProductsFeedEndToEnd() throws Exception { + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + String xml = readFile("metadataProducts.xml"); + InputStream reader = createStreamReader(xml); + EdmDataServices result = parser.readMetadata(reader, true); + assertEquals(1, result.getEdm().getSchemas().size()); + ClientEdm edm = result.getEdm(); + InputStream file = getFileAsStream("ProductsFeed.xml"); + assertNotNull(file); + EntityStream es = new EntityStream(); + es.setContent(file); + es.setReadProperties(DEFAULT_PROPERTIES); + ODataClientImpl client = new ODataClientImpl(); + ContentTypeBasedDeserializer deserializer = client.createDeserializer("application/atom+xml"); + ODataFeed feed = + deserializer.readFeed( edm.getEntitySets().get(0), es); + assertNotNull(feed); + + List<ODataEntry> oDataEntries = feed.getEntries(); + + for (ODataEntry entry : oDataEntries) { + assertEquals(6, entry.getProperties().size()); + assertEquals(4, ((ODataEntry)entry.getProperties().get("Supplier")).getProperties().size()); + } + } + + /** + * Rooms navigate to Employees and has inline entry Teams + * E.g: Rooms('1')/nr_Employees?$expand=ne_Team + * @throws Exception + */ + @Test + public void roomsFeedWithRoomsToEmployeesInlineTeams() throws Exception { + InputStream stream = getFileAsStream("RoomsToEmployeesWithInlineTeams.xml"); + assertNotNull(stream); + EntityStream es = new EntityStream(); + es.setContent(stream); + es.setReadProperties(DEFAULT_PROPERTIES); + ODataClientImpl client = new ODataClientImpl(); + ContentTypeBasedDeserializer deserializer = client.createDeserializer("application/atom+xml"); + ODataFeed feed = + deserializer.readFeed( MockFacade.getMockEdm().getDefaultEntityContainer() + .getEntitySet( + "Employees"), es); + assertNotNull(feed); + assertEquals(2, feed.getEntries().size()); + + for (ODataEntry entry : feed.getEntries()) { + assertEquals(10, entry.getProperties().size()); + assertEquals(3, ((ODataEntry)entry.getProperties().get("ne_Team")).getProperties().size()); + } + } + + @Test + public void readEmployeesFeedWithInlineCountValid() throws Exception { + // prepare + String content = readFile("feed_employees_full.xml"); + assertNotNull(content); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"); + InputStream reqContent = createContentAsStream(content); + + // execute + XmlEntityDeserializer xec = new XmlEntityDeserializer(); + DeserializerProperties consumerProperties = DeserializerProperties.init() + .build(); + + EntityStream es = new EntityStream(); + es.setContent(reqContent); + es.setReadProperties(consumerProperties); + + ODataFeed feed = xec.readFeed(entitySet, es); + assertNotNull(feed); + + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + + int inlineCount = feedMetadata.getInlineCount(); + // Null means no inlineCount found + assertNotNull(inlineCount); + + assertEquals(6, inlineCount); + } + + @Test(expected = EntityProviderException.class) + public void readEmployeesFeedWithInlineCountNegative() throws Exception { + // prepare + String content = readFile("feed_employees_full.xml").replace("<m:count>6</m:count>", "<m:count>-1</m:count>"); + assertNotNull(content); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"); + InputStream reqContent = createContentAsStream(content); + + // execute + XmlEntityDeserializer xec = new XmlEntityDeserializer(); + DeserializerProperties consumerProperties = DeserializerProperties.init() + .build(); + + EntityStream es = new EntityStream(); + es.setContent(reqContent); + es.setReadProperties(consumerProperties); + try { + xec.readFeed(entitySet, es); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.INLINECOUNT_INVALID, e.getMessageReference()); + throw e; + } + + Assert.fail("Exception expected"); + } + + @Test(expected = EntityProviderException.class) + public void readEmployeesFeedWithInlineCountLetters() throws Exception { + // prepare + String content = readFile("feed_employees_full.xml").replace("<m:count>6</m:count>", "<m:count>AAA</m:count>"); + assertNotNull(content); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"); + InputStream reqContent = createContentAsStream(content); + + // execute + XmlEntityDeserializer xec = new XmlEntityDeserializer(); + DeserializerProperties consumerProperties = DeserializerProperties.init() + .build(); + + EntityStream es = new EntityStream(); + es.setContent(reqContent); + es.setReadProperties(consumerProperties); + try { + xec.readFeed(entitySet, es); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.INLINECOUNT_INVALID, e.getMessageReference()); + throw e; + } + + Assert.fail("Exception expected"); + } + @Test + public void readDeltaFeed() throws Exception { + // prepare + String content = readFile("feed_with_deleted_entries.xml"); + assertNotNull(content); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); + InputStream reqContent = createContentAsStream(content); + EntityStream stream = new EntityStream(); + XmlEntityDeserializer xec = new XmlEntityDeserializer(); + DeserializerProperties consumerProperties = DeserializerProperties.init().build(); + stream.setContent(reqContent); + stream.setReadProperties(consumerProperties); + ODataDeltaFeed deltaFeed = xec.readFeed(entitySet, stream); + + assertNotNull(deltaFeed); + + assertNotNull(deltaFeed.getDeletedEntries()); + assertNotNull(deltaFeed.getEntries()); + + assertEquals(1, deltaFeed.getEntries().size()); + assertEquals(1, deltaFeed.getDeletedEntries().size()); + } +} http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataAssociationTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataAssociationTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataAssociationTest.java new file mode 100644 index 0000000..84a843f --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlMetadataAssociationTest.java @@ -0,0 +1,504 @@ +package org.apache.olingo.odata2.client.core.ep.deserializer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.stream.XMLStreamException; + +import org.apache.olingo.odata2.api.edm.Edm; +import org.apache.olingo.odata2.api.edm.EdmAnnotationAttribute; +import org.apache.olingo.odata2.api.edm.EdmAssociation; +import org.apache.olingo.odata2.api.edm.EdmAssociationEnd; +import org.apache.olingo.odata2.api.edm.EdmAssociationSet; +import org.apache.olingo.odata2.api.edm.EdmAssociationSetEnd; +import org.apache.olingo.odata2.api.edm.EdmEntityContainer; +import org.apache.olingo.odata2.api.edm.EdmEntitySet; +import org.apache.olingo.odata2.api.edm.EdmEntityType; +import org.apache.olingo.odata2.api.edm.EdmException; +import org.apache.olingo.odata2.api.edm.EdmMultiplicity; +import org.apache.olingo.odata2.api.edm.EdmNavigationProperty; +import org.apache.olingo.odata2.api.ep.EntityProviderException; +import org.apache.olingo.odata2.client.api.edm.EdmDataServices; +import org.apache.olingo.odata2.client.api.edm.EdmSchema; +import org.junit.Test; + +public class XmlMetadataAssociationTest { + private static final String NAMESPACE = "RefScenario"; + private static final String NAMESPACE2 = "RefScenario2"; + private static final String ASSOCIATION = "ManagerEmployees"; + + private final String[] propertyNames = { "EmployeeId", "EmployeeName", "Location" }; + + private final String xmlWithAssociation = + "<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\">" + + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + + "<Property Name=\"" + + propertyNames[0] + + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<NavigationProperty Name=\"ne_Manager\" Relationship=\"RefScenario.ManagerEmployees\" " + + "FromRole=\"r_Employees\" ToRole=\"r_Manager\" />" + + "</EntityType>" + + "<EntityType Name=\"Manager\" BaseType=\"RefScenario.Employee\" m:HasStream=\"true\">" + + "<NavigationProperty Name=\"nm_Employees\" Relationship=\"RefScenario.ManagerEmployees\" " + + "FromRole=\"r_Manager\" ToRole=\"r_Employees\" />" + + "</EntityType>" + "<Association Name=\"" + ASSOCIATION + "\">" + + "<End Type=\"RefScenario.Employee\" Multiplicity=\"*\" Role=\"r_Employees\">" + + "<OnDelete Action=\"Cascade\"/>" + "</End>" + + "<End Type=\"RefScenario.Manager\" Multiplicity=\"1\" Role=\"r_Manager\"/>" + "</Association>" + + "</Schema>" + "<Schema Namespace=\"" + NAMESPACE2 + "\" xmlns=\"" + Edm.NAMESPACE_EDM_2008_09 + "\">" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + + "<EntitySet Name=\"Managers\" EntityType=\"RefScenario.Manager\"/>" + "<AssociationSet Name=\"" + + ASSOCIATION + "\" Association=\"RefScenario." + ASSOCIATION + "\">" + + "<End EntitySet=\"Managers\" Role=\"r_Manager\"/>" + "<End EntitySet=\"Employees\" Role=\"r_Employees\"/>" + + "</AssociationSet>" + "</EntityContainer>" + "</Schema>" + "</edmx:DataServices>" + "</edmx:Edmx>"; + private final String xmlWithAssociationWithRC = + "<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\">" + + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + + "<Property Name=\"" + + propertyNames[0] + + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<NavigationProperty Name=\"ne_Manager\" Relationship=\"RefScenario.ManagerEmployees\" " + + "FromRole=\"r_Employees\" ToRole=\"r_Manager\" />" + + "</EntityType>" + + "<EntityType Name=\"Manager\" BaseType=\"RefScenario.Employee\" m:HasStream=\"true\">" + + "<NavigationProperty Name=\"nm_Employees\" Relationship=\"RefScenario.ManagerEmployees\" " + + "FromRole=\"r_Manager\" ToRole=\"r_Employees\" />" + + "</EntityType>" + "<Association Name=\"" + ASSOCIATION + "\">" + + "<End Type=\"RefScenario.Employee\" Multiplicity=\"*\" Role=\"r_Employees\">" + + "<OnDelete Action=\"Cascade\"/>" + "</End>" + + "<End Type=\"RefScenario.Manager\" Multiplicity=\"1\" Role=\"r_Manager\"/>" + + "<ReferentialConstraint><Principal Role=\"r_Employees\">" + + "<PropertyRef Name=\"EmployeeId\"/></Principal><Dependent Role=\"r_Manager\">" + + "<PropertyRef Name=\"EmployeeId\"/></Dependent></ReferentialConstraint>" + + "</Association>" + + "</Schema>" + "<Schema Namespace=\"" + NAMESPACE2 + "\" xmlns=\"" + Edm.NAMESPACE_EDM_2008_09 + "\">" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + + "<EntitySet Name=\"Managers\" EntityType=\"RefScenario.Manager\"/>" + "<AssociationSet Name=\"" + + ASSOCIATION + "\" Association=\"RefScenario." + ASSOCIATION + "\">" + + "<End EntitySet=\"Managers\" Role=\"r_Manager\"/>" + "<End EntitySet=\"Employees\" Role=\"r_Employees\"/>" + + "</AssociationSet>" + "</EntityContainer>" + "</Schema>" + "</edmx:DataServices>" + "</edmx:Edmx>"; + + @Test + public void testAssociationSet() throws XMLStreamException, EntityProviderException, + EdmException, UnsupportedEncodingException { + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream content = createStreamReader(xmlWithAssociation); + EdmDataServices result = parser.readMetadata(content, true); + for (EdmSchema schema : result.getEdm().getSchemas()) { + for (EdmEntityContainer container : schema.getEntityContainers()) { + assertEquals(NAMESPACE2, schema.getNamespace()); + assertEquals("Container1", container.getName()); + assertEquals(Boolean.TRUE, container.isDefaultEntityContainer()); + for (EdmAssociationSet assocSet : container.getAssociationSets()) { + assertNotNull(assocSet.getEntityContainer()); + assertEquals(ASSOCIATION, assocSet.getName()); + assertEquals(ASSOCIATION, assocSet.getAssociation().getName()); + assertEquals(NAMESPACE, assocSet.getAssociation().getNamespace()); + EdmAssociationSetEnd end; + if ("Employees".equals(assocSet.getEnd("r_Employees").getEntitySet().getName())) { + end = assocSet.getEnd("r_Employees"); + } else { + end = assocSet.getEnd("r_Manager"); + } + assertEquals("r_Employees", end.getRole()); + assertEquals("Employees", end.getEntitySet().getName()); + } + } + } + } + + @Test + public void testAssociationSetWithRC() throws XMLStreamException, EntityProviderException, + EdmException, UnsupportedEncodingException { + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream content = createStreamReader(xmlWithAssociationWithRC); + EdmDataServices result = parser.readMetadata(content, true); + EdmAssociation associations = (EdmAssociation) result.getEdm().getSchemas().get(0).getAssociations().get(0); + assertEquals(1, associations.getReferentialConstraint().getPrincipal().getPropertyRefNames().size()); + assertEquals(1, associations.getReferentialConstraint().getDependent().getPropertyRefNames().size()); + assertEquals("EmployeeId", associations.getReferentialConstraint().getPrincipal().getPropertyRefNames().get(0)); + assertEquals("EmployeeId", associations.getReferentialConstraint().getDependent().getPropertyRefNames().get(0)); + + } + + @Test + public void testRelatedEntitySet() throws XMLStreamException, EntityProviderException, + EdmException, UnsupportedEncodingException { + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream content = createStreamReader(xmlWithAssociation); + EdmDataServices result = parser.readMetadata(content, true); + for (EdmSchema schema : result.getEdm().getSchemas()) { + for (EdmEntityContainer container : schema.getEntityContainers()) { + assertEquals(NAMESPACE2, schema.getNamespace()); + assertEquals("Container1", container.getName()); + assertEquals(Boolean.TRUE, container.isDefaultEntityContainer()); + for (EdmEntitySet entitySet : container.getEntitySets()) { + assertNotNull(entitySet.getEntityContainer()); + for (EdmEntityType entityType : result.getEdm().getSchemas().get(0).getEntityTypes()) { + for (String navigationPropertyName : entityType.getNavigationPropertyNames()) { + EdmNavigationProperty navigationProperty = (EdmNavigationProperty) entityType + .getProperty(navigationPropertyName); + if(entitySet.getName().equals("Managers") && navigationProperty.getName().equals("nm_Employees")){ + assertNotNull(entitySet.getRelatedEntitySet(navigationProperty)); + } + } + } + } + } + } + } + + @Test + public void testAssociation() throws XMLStreamException, EntityProviderException, + EdmException, UnsupportedEncodingException { + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmlWithAssociation); + EdmDataServices result = parser.readMetadata(reader, true); + assertEquals("2.0", result.getDataServiceVersion()); + for (EdmSchema schema : result.getEdm().getSchemas()) { + for (EdmAssociation association : schema.getAssociations()) { + EdmAssociationEnd end; + assertEquals(ASSOCIATION, association.getName()); + if ("Employee".equals(association.getEnd1().getEntityType().getName())) { + end = association.getEnd1(); + } else { + end = association.getEnd2(); + } + assertEquals(EdmMultiplicity.MANY, end.getMultiplicity()); + assertEquals("r_Employees", end.getRole()); + } + } + } + + private InputStream createStreamReader(final String xml) throws XMLStreamException, + UnsupportedEncodingException { + return new ByteArrayInputStream(xml.getBytes("UTF-8")); + } + @Test(expected = EntityProviderException.class) + public void testMissingTypeAtAssociation() throws Exception { + final String xmlWithInvalidAssociation = + "<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\">" + + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + + "<Property Name=\"" + + propertyNames[0] + + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<NavigationProperty Name=\"ne_Manager\" Relationship=\"RefScenario.ManagerEmployees\" " + + "FromRole=\"r_Employees\" ToRole=\"r_Manager\" />" + + "</EntityType>" + "<EntityType Name=\"Manager\" BaseType=\"RefScenario.Employee\" m:HasStream=\"true\">" + + "</EntityType>" + "<Association Name=\"ManagerEmployees\">" + + "<End Multiplicity=\"*\" Role=\"r_Employees\"/>" + + "<End Type=\"RefScenario.Manager\" Multiplicity=\"1\" Role=\"r_Manager\"/>" + + "</Association></Schema></edmx:DataServices></edmx:Edmx>"; + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmlWithInvalidAssociation); + try { + parser.readMetadata(reader, true); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.MISSING_ATTRIBUTE.getKey(), e.getMessageReference().getKey()); + assertEquals(2, e.getMessageReference().getContent().size()); + assertEquals("Type", e.getMessageReference().getContent().get(0)); + assertEquals("End", e.getMessageReference().getContent().get(1)); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void testMissingAssociation() throws Exception { + final String xmlWithAssociation = + "<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\">" + + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + + "<Property Name=\"" + + propertyNames[0] + + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<NavigationProperty Name=\"ne_Manager\" Relationship=\"RefScenario.ManagerEmployees\" " + + "FromRole=\"r_Employees\" ToRole=\"r_Manager\" />" + + "</EntityType>" + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + "<AssociationSet Name=\"" + + ASSOCIATION + // + "\" Association=\"RefScenario." + ASSOCIATION + + "\">" + "<End EntitySet=\"Employees\" Role=\"r_Employees\"/>" + "</AssociationSet>" + + "</EntityContainer>" + "</Schema>" + "</edmx:DataServices></edmx:Edmx>"; + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmlWithAssociation); + try { + parser.readMetadata(reader, true); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.MISSING_ATTRIBUTE.getKey(), e.getMessageReference().getKey()); + assertEquals(2, e.getMessageReference().getContent().size()); + assertEquals("Association", e.getMessageReference().getContent().get(0)); + assertEquals("AssociationSet", e.getMessageReference().getContent().get(1)); + throw e; + } + } + + @Test(expected = EdmException.class) + public void testInvalidAssociation() throws XMLStreamException, + EntityProviderException, EdmException, UnsupportedEncodingException { + final String xmlWithInvalidAssociationSet = + "<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\">" + + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + + "<Property Name=\"" + + propertyNames[0] + + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<NavigationProperty Name=\"ne_Manager\" Relationship=\"RefScenario.ManagerEmployees\" " + + "FromRole=\"r_Employees\" ToRole=\"r_Manager\" />" + + "</EntityType>" + + "<EntityType Name=\"Manager\" BaseType=\"RefScenario.Employee\" m:HasStream=\"true\">" + + "<NavigationProperty Name=\"nm_Employees\" Relationship=\"RefScenario.ManagerEmployees\" " + + "FromRole=\"r_Manager\" ToRole=\"r_Employees\" />" + + "</EntityType>" + "<Association Name=\"" + ASSOCIATION + "\">" + + "<End Type=\"RefScenario.Employee\" Multiplicity=\"*\" Role=\"r_Employees\">" + + "<OnDelete Action=\"Cascade\"/>" + "</End>" + + "<End Type=\"RefScenario.Manager\" Multiplicity=\"1\" Role=\"r_Manager\"/>" + "</Association>" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + + "<EntitySet Name=\"Managers\" EntityType=\"RefScenario.Manager\"/>" + "<AssociationSet Name=\"" + + ASSOCIATION + "\" Association=\"RefScenario2." + ASSOCIATION + "\">" + + "<End EntitySet=\"Managers\" Role=\"r_Manager\"/>" + + "<End EntitySet=\"Employees\" Role=\"r_Employees\"/>" + "</AssociationSet>" + "</EntityContainer>" + + "</Schema>" + "</edmx:DataServices>" + "</edmx:Edmx>"; + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmlWithInvalidAssociationSet); + parser.readMetadata(reader, true); + + } + @Test(expected = EdmException.class) + public void testInvalidAssociationEnd() throws XMLStreamException, + EntityProviderException, EdmException, UnsupportedEncodingException { + final String employees = "r_Employees"; + final String manager = "r_Manager"; + final String xmlWithInvalidAssociationSetEnd = + "<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\">" + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + "<Property Name=\"" + + propertyNames[0] + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<NavigationProperty Name=\"ne_Manager\" Relationship=\"RefScenario.ManagerEmployees\" FromRole=\"" + + employees + "\" ToRole=\"" + manager + "\" />" + "</EntityType>" + + "<EntityType Name=\"Manager\" BaseType=\"RefScenario.Employee\" m:HasStream=\"true\">" + + "<NavigationProperty Name=\"nm_Employees\" Relationship=\"RefScenario.ManagerEmployees\" FromRole=\"" + + manager + "\" ToRole=\"" + employees + "\" />" + "</EntityType>" + "<Association Name=\"" + ASSOCIATION + + "\">" + + "<End Type=\"RefScenario.Employee\" Multiplicity=\"*\" Role=\"" + employees + "1" + "\"/>" + + "<End Type=\"RefScenario.Manager\" Multiplicity=\"1\" Role=\"" + manager + "\"/>" + "</Association>" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + + "<EntitySet Name=\"Managers\" EntityType=\"RefScenario.Manager\"/>" + "<AssociationSet Name=\"" + + ASSOCIATION + "\" Association=\"RefScenario2." + ASSOCIATION + "\">" + + "<End EntitySet=\"Managers\" Role=\"" + manager + "\"/>" + "<End EntitySet=\"Employees\" Role=\"" + + employees + "\"/>" + "</AssociationSet>" + "</EntityContainer>" + "</Schema>" + "</edmx:DataServices>" + + "</edmx:Edmx>"; + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmlWithInvalidAssociationSetEnd); + parser.readMetadata(reader, true); + + } + + @Test(expected = EdmException.class) + public void testInvalidAssociationEnd2() throws XMLStreamException, + EntityProviderException, EdmException, UnsupportedEncodingException { + final String employees = "r_Employees"; + final String manager = "r_Manager"; + final String xmlWithInvalidAssociationSetEnd = + "<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\">" + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + "<Property Name=\"" + + propertyNames[0] + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<NavigationProperty Name=\"ne_Manager\" Relationship=\"RefScenario.ManagerEmployees\" FromRole=\"" + + employees + "\" ToRole=\"" + manager + "\" />" + "</EntityType>" + + "<EntityType Name=\"Manager\" BaseType=\"RefScenario.Employee\" m:HasStream=\"true\">" + + "<NavigationProperty Name=\"nm_Employees\" Relationship=\"RefScenario.ManagerEmployees\" FromRole=\"" + + manager + "\" ToRole=\"" + employees + "\" />" + "</EntityType>" + "<Association Name=\"" + ASSOCIATION + + "\">" + + "<End Type=\"RefScenario.Employee\" Multiplicity=\"*\" Role=\"" + employees + "\"/>" + + "<End Type=\"RefScenario.Manager\" Multiplicity=\"1\" Role=\"" + manager + "\"/>" + "</Association>" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + + "<EntitySet Name=\"Managers\" EntityType=\"RefScenario.Manager\"/>" + "<AssociationSet Name=\"" + + ASSOCIATION + "\" Association=\"RefScenario2." + ASSOCIATION + "\">" + + "<End EntitySet=\"Managers\" Role=\"" + manager + "\"/>" + "<End EntitySet=\"Managers\" Role=\"" + + manager + "\"/>" + "</AssociationSet>" + "</EntityContainer>" + "</Schema>" + "</edmx:DataServices>" + + "</edmx:Edmx>"; + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmlWithInvalidAssociationSetEnd); + parser.readMetadata(reader, true); + + } + + @Test + public void testAnnoationsOnAssociationSet() throws Exception { + final String employees = "r_Employees"; + final String manager = "r_Manager"; + final String xmlWithInvalidAssociationSetEnd = + "<edmx:Edmx Version=\"1.0\" xmlns:edmx=\"" + Edm.NAMESPACE_EDMX_2007_06 + "\" " + + "xmlns:sap=\"http://www.sap.com/Protocols/SAPData\">" + + "<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\">" + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + "<Property Name=\"" + + propertyNames[0] + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<NavigationProperty Name=\"ne_Manager\" Relationship=\"RefScenario.ManagerEmployees\" FromRole=\"" + + employees + "\" ToRole=\"" + manager + "\" />" + "</EntityType>" + + "<EntityType Name=\"Manager\" BaseType=\"RefScenario.Employee\" m:HasStream=\"true\">" + + "<NavigationProperty Name=\"nm_Employees\" Relationship=\"RefScenario.ManagerEmployees\" FromRole=\"" + + manager + "\" ToRole=\"" + employees + "\" />" + "</EntityType>" + "<Association Name=\"" + ASSOCIATION + + "\">" + + "<End Type=\"RefScenario.Employee\" Multiplicity=\"*\" Role=\"" + employees + "\"/>" + + "<End Type=\"RefScenario.Manager\" Multiplicity=\"1\" Role=\"" + manager + "\"/>" + "</Association>" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + + "<EntitySet Name=\"Managers\" EntityType=\"RefScenario.Manager\"/>" + "<AssociationSet Name=\"" + + ASSOCIATION + "\" Association=\"RefScenario." + ASSOCIATION + "\" " + + "sap:creatable=\"true\" sap:updatable=\"true\" " + + "sap:deletable=\"false\">" + + "<End EntitySet=\"Managers\" Role=\"" + manager + "\"/>" + "<End EntitySet=\"Employees\" Role=\"" + + employees + "\"/>" + "</AssociationSet>" + "</EntityContainer>" + "</Schema>" + "</edmx:DataServices>" + + "</edmx:Edmx>"; + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmlWithInvalidAssociationSetEnd); + EdmDataServices result = parser.readMetadata(reader, true); + List<String> annotationList = new ArrayList<String>(); + annotationList.add("creatable"); + annotationList.add("updatable"); + annotationList.add("deletable"); + for (EdmSchema schema : result.getEdm().getSchemas()) { + for (EdmEntityContainer container : schema.getEntityContainers()) { + for (EdmAssociationSet associationSet : container.getAssociationSets()) { + assertEquals("ManagerEmployees", associationSet.getName()); + int i = 0; + for (EdmAnnotationAttribute annotationAttr : associationSet.getAnnotations().getAnnotationAttributes()) { + assertEquals(annotationList.get(i), annotationAttr.getName()); + assertEquals("sap", annotationAttr.getPrefix()); + assertEquals("http://www.sap.com/Protocols/SAPData", annotationAttr.getNamespace()); + i++; + } + } + } + } + + } + + @Test + public void testRelatedEntitySetWithCyclicAssociation() throws Exception { + final String employees = "r_Employees"; + final String manager = "r_Manager"; + final String xmlWithInvalidAssociationSetEnd = + "<edmx:Edmx Version=\"1.0\" xmlns:edmx=\"" + Edm.NAMESPACE_EDMX_2007_06 + "\" " + + "xmlns:sap=\"http://www.sap.com/Protocols/SAPData\">" + + "<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\">" + "<Key><PropertyRef Name=\"EmployeeId\"/></Key>" + "<Property Name=\"" + + propertyNames[0] + "\" Type=\"Edm.String\" Nullable=\"false\"/>" + + "<NavigationProperty Name=\"ne_Manager\" Relationship=\"RefScenario.ManagerEmployees\" FromRole=\"" + + employees + "\" ToRole=\"" + manager + "\" />" + "</EntityType>" + + "<EntityType Name=\"Manager\" BaseType=\"RefScenario.Employee\" m:HasStream=\"true\">" + + "<NavigationProperty Name=\"nm_Employees\" Relationship=\"RefScenario.ManagerEmployees\" FromRole=\"" + + manager + "\" ToRole=\"" + employees + "\" />" + "</EntityType>" + "<Association Name=\"" + ASSOCIATION + + "\">" + + "<End Type=\"RefScenario.Employee\" Multiplicity=\"*\" Role=\"" + employees + "\"/>" + + "<End Type=\"RefScenario.Manager\" Multiplicity=\"1\" Role=\"" + manager + "\"/>" + "</Association>" + + "<EntityContainer Name=\"Container1\" m:IsDefaultEntityContainer=\"true\">" + + "<EntitySet Name=\"Employees\" EntityType=\"RefScenario.Employee\"/>" + + "<EntitySet Name=\"Managers\" EntityType=\"RefScenario.Manager\"/>" + "<AssociationSet Name=\"" + + ASSOCIATION + "\" Association=\"RefScenario." + ASSOCIATION + "\" " + + "sap:creatable=\"true\" sap:updatable=\"true\" " + + "sap:deletable=\"false\">" + + "<End EntitySet=\"Managers\" Role=\"" + manager + "\"/>" + "<End EntitySet=\"Employees\" Role=\"" + + employees + "\"/>" + "</AssociationSet>" + "</EntityContainer>" + "</Schema>" + "</edmx:DataServices>" + + "</edmx:Edmx>"; + XmlMetadataDeserializer parser = new XmlMetadataDeserializer(); + InputStream reader = createStreamReader(xmlWithInvalidAssociationSetEnd); + EdmDataServices result = parser.readMetadata(reader, true); + List<String> annotationList = new ArrayList<String>(); + annotationList.add("creatable"); + annotationList.add("updatable"); + annotationList.add("deletable"); + for (EdmSchema schema : result.getEdm().getSchemas()) { + for (EdmEntityContainer container : schema.getEntityContainers()) { + for (EdmEntitySet entitySet : container.getEntitySets()) { + for(EdmEntityType entityType:schema.getEntityTypes()){ + List<String> navigationPropertyNames = entityType.getNavigationPropertyNames(); + for (String navigationPropertyName : navigationPropertyNames) { + EdmNavigationProperty navigationProperty = (EdmNavigationProperty) entityType + .getProperty(navigationPropertyName); + if((entitySet.getName().equals("Managers") && navigationProperty.getName().equals("nm_Employees")) || + entitySet.getName().equals("Employees") && navigationProperty.getName().equals("ne_Manager") ){ + assertNotNull(entitySet.getRelatedEntitySet(navigationProperty)); + }else{ + assertNull(entitySet.getRelatedEntitySet(navigationProperty)); + } + } + } + } + } + } + + } + + + +}
