You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/05/09 14:47:19 UTC
[6/6] git commit: [OLINGO-231] Several refactorings
[OLINGO-231] Several refactorings
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/cb1ba468
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/cb1ba468
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/cb1ba468
Branch: refs/heads/OLINGO-231_PocForAndroid
Commit: cb1ba46855a469d7fc81d5a7e2f9b1b15187fcfa
Parents: 696288d
Author: Michael Bolz <mi...@sap.com>
Authored: Thu May 8 08:35:19 2014 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Fri May 9 14:38:52 2014 +0200
----------------------------------------------------------------------
odata2-android/pom.xml | 9 +-
.../odata2/android/xml/AndroidXmlFactory.java | 17 +-
.../odata2/android/xml/AndroidXmlReader.java | 26 +-
.../odata2/android/xml/AndroidTestBase.java | 257 +
.../android/xml/AndroidXmlFactoryTest.java | 3 +-
.../android/xml/AndroidXmlReaderTest.java | 8 +-
.../android/xml/AtomEntryProducerTest.java | 849 ++
.../android/xml/AtomFeedProducerTest.java | 215 +
.../android/xml/XmlEntityConsumerTest.java | 2420 ++++
.../odata2/android/xml/XmlFeedConsumerTest.java | 155 +
.../src/test/resources/LargeEmployeeFeed.xml | 12556 +++++++++++++++++
.../src/test/resources/double_expanded_team.xml | 264 +
.../src/test/resources/expandedBuilding.xml | 61 +
.../src/test/resources/expanded_team.xml | 146 +
.../src/test/resources/feed_employees.xml | 247 +
.../src/test/resources/feed_employees_full.xml | 249 +
.../resources/feed_with_deleted_entries.xml | 40 +
.../src/test/resources/feed_with_delta_link.xml | 69 +
odata2-lib/odata-core/pom.xml | 5 -
.../olingo/odata2/core/commons/Base64.java | 589 +
.../olingo/odata2/core/commons/BaseNCodec.java | 350 +
.../apache/olingo/odata2/core/commons/Hex.java | 124 +
.../olingo/odata2/core/debug/DebugInfoBody.java | 2 +-
.../olingo/odata2/core/edm/EdmBinary.java | 9 +-
.../provider/EdmServiceMetadataImplProv.java | 25 +-
.../odata2/core/ep/BasicEntityProvider.java | 29 +-
.../odata2/core/debug/DebugInfoBodyTest.java | 2 +-
.../core/uri/expression/TestTokenizer.java | 9 +-
.../core/xml/JavaxStaxStreamFactoryTest.java | 13 +-
pom.xml | 1 -
30 files changed, 18668 insertions(+), 81 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb1ba468/odata2-android/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-android/pom.xml b/odata2-android/pom.xml
index 8a8e1c3..614f558 100644
--- a/odata2-android/pom.xml
+++ b/odata2-android/pom.xml
@@ -34,7 +34,7 @@
<properties>
<version.android>4.1.1.4</version.android>
- <version.robolectric>2.2</version.robolectric>
+ <version.robolectric>2.3-SNAPSHOT</version.robolectric>
</properties>
<build>
@@ -96,6 +96,7 @@
<artifactId>olingo-odata2-core</artifactId>
<version>${project.version}</version>
</dependency>
+ <!-- Test dependencies -->
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>olingo-odata2-testutil</artifactId>
@@ -112,6 +113,12 @@
<artifactId>robolectric</artifactId>
<version>${version.robolectric}</version>
<scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>com.android.support</groupId>
+ <artifactId>support-v4</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>xmlunit</groupId>
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb1ba468/odata2-android/src/main/java/org/apache/olingo/odata2/android/xml/AndroidXmlFactory.java
----------------------------------------------------------------------
diff --git a/odata2-android/src/main/java/org/apache/olingo/odata2/android/xml/AndroidXmlFactory.java b/odata2-android/src/main/java/org/apache/olingo/odata2/android/xml/AndroidXmlFactory.java
index f2888a9..85eb024 100644
--- a/odata2-android/src/main/java/org/apache/olingo/odata2/android/xml/AndroidXmlFactory.java
+++ b/odata2-android/src/main/java/org/apache/olingo/odata2/android/xml/AndroidXmlFactory.java
@@ -18,13 +18,26 @@
******************************************************************************/
package org.apache.olingo.odata2.android.xml;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
import org.apache.olingo.odata2.api.xml.*;
import org.apache.olingo.odata2.core.xml.AbstractXmlStreamFactory;
public class AndroidXmlFactory extends AbstractXmlStreamFactory {
+ private static final String DEFAULT_CHARSET = "UTF-8";
+
@Override
- public XMLStreamReader createXMLStreamReader(Object content) throws XMLStreamException {
- return new AndroidXmlReader(content).setProperties(readProperties);
+ public XMLStreamReader createXMLStreamReader(Object content) throws XMLStreamException, EntityProviderException {
+ AndroidXmlReader reader = new AndroidXmlReader(content).setProperties(readProperties);
+
+ // verify charset encoding set in content is supported (if not set UTF-8 is used as defined in
+ // 'http://www.w3.org/TR/2008/REC-xml-20081126/')
+ String characterEncodingInContent = reader.getCharacterEncodingScheme();
+ if (characterEncodingInContent != null && !DEFAULT_CHARSET.equalsIgnoreCase(characterEncodingInContent)) {
+ throw new EntityProviderException(EntityProviderException
+ .UNSUPPORTED_CHARACTER_ENCODING.addContent(characterEncodingInContent));
+ }
+
+ return reader;
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb1ba468/odata2-android/src/main/java/org/apache/olingo/odata2/android/xml/AndroidXmlReader.java
----------------------------------------------------------------------
diff --git a/odata2-android/src/main/java/org/apache/olingo/odata2/android/xml/AndroidXmlReader.java b/odata2-android/src/main/java/org/apache/olingo/odata2/android/xml/AndroidXmlReader.java
index d793fe6..0bc1881 100644
--- a/odata2-android/src/main/java/org/apache/olingo/odata2/android/xml/AndroidXmlReader.java
+++ b/odata2-android/src/main/java/org/apache/olingo/odata2/android/xml/AndroidXmlReader.java
@@ -20,6 +20,7 @@ package org.apache.olingo.odata2.android.xml;
import java.io.IOException;
import java.io.InputStream;
+import java.util.HashMap;
import java.util.Map;
import org.apache.olingo.odata2.api.xml.NamespaceContext;
@@ -69,6 +70,10 @@ public class AndroidXmlReader implements XMLStreamReader {
return this;
}
+ public String getCharacterEncodingScheme() {
+ return parser.getInputEncoding();
+ }
+
@Override
public void close() throws XMLStreamException {
}
@@ -114,7 +119,6 @@ public class AndroidXmlReader implements XMLStreamReader {
text = parser.getText();
parser.next();
} catch (Exception e) {
- e.printStackTrace();
throw new XMLStreamException("Failure during step forward after 'getText'.", e);
}
return text;
@@ -137,18 +141,24 @@ public class AndroidXmlReader implements XMLStreamReader {
}
@Override
- public NamespaceContext getNamespaceContext() {
- String tmp = null;
+ public NamespaceContext getNamespaceContext() throws XMLStreamException {
+ final Map<String, String> prefix2Namespace;
try {
int depth = parser.getDepth();
- tmp = parser.getNamespacePrefix(depth);
+ int nsStart = parser.getNamespaceCount(depth-1);
+ int nsEnd = parser.getNamespaceCount(depth);
+ prefix2Namespace = new HashMap<String, String>(nsEnd-nsStart+1);
+ for (int i = nsStart; i < nsEnd; i++) {
+ String prefix = parser.getNamespacePrefix(i);
+ String namespace = parser.getNamespaceUri(i);
+ prefix2Namespace.put(namespace, prefix);
+ }
} catch (XmlPullParserException e) {
- e.printStackTrace();
+ throw new XMLStreamException("Got XmlPullParserException with message: " + e.getMessage(), e);
}
- final String prefix = tmp;
return new NamespaceContext() {
- public String getPrefix(String index) {
- return prefix;
+ public String getPrefix(String namespaceUri) {
+ return prefix2Namespace.get(namespaceUri);
}
};
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb1ba468/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidTestBase.java
----------------------------------------------------------------------
diff --git a/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidTestBase.java b/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidTestBase.java
new file mode 100644
index 0000000..fad1c12
--- /dev/null
+++ b/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidTestBase.java
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * 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.android.xml;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.api.ep.callback.TombstoneCallback;
+import org.apache.olingo.odata2.core.ep.AtomEntityProvider;
+import org.custommonkey.xmlunit.SimpleNamespaceContext;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+
+import static org.apache.olingo.odata2.api.xml.XMLStreamReaderFactory.XML_STREAM_READER_FACTORY_CLASS;
+import static org.apache.olingo.odata2.api.xml.XMLStreamWriterFactory.XML_STREAM_WRITER_FACTORY_CLASS;
+
+/**
+ *
+*/
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest=Config.NONE)
+public abstract class AndroidTestBase {
+
+ protected static final URI BASE_URI;
+
+ static {
+ try {
+ BASE_URI = new URI("http://host:80/service/");
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ protected static final EntityProviderWriteProperties DEFAULT_PROPERTIES = EntityProviderWriteProperties.serviceRoot(
+ BASE_URI).build();
+
+ protected Map<String, Object> employeeData;
+
+ protected ArrayList<Map<String, Object>> employeesData;
+
+ protected Map<String, Object> photoData;
+
+ protected Map<String, Object> roomData;
+
+ protected Map<String, Object> buildingData;
+
+ protected ArrayList<Map<String, Object>> roomsData;
+
+ {
+ employeeData = new HashMap<String, Object>();
+
+ Calendar date = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ date.clear();
+ date.set(1999, 0, 1);
+
+ employeeData.put("EmployeeId", "1");
+ employeeData.put("ImmageUrl", null);
+ employeeData.put("ManagerId", "1");
+ employeeData.put("Age", new Integer(52));
+ employeeData.put("RoomId", "1");
+ employeeData.put("EntryDate", date);
+ employeeData.put("TeamId", "42");
+ employeeData.put("EmployeeName", "Walter Winter");
+
+ Map<String, Object> locationData = new HashMap<String, Object>();
+ Map<String, Object> cityData = new HashMap<String, Object>();
+ cityData.put("PostalCode", "33470");
+ cityData.put("CityName", "Duckburg");
+ locationData.put("City", cityData);
+ locationData.put("Country", "Calisota");
+
+ employeeData.put("Location", locationData);
+
+ Map<String, Object> employeeData2 = new HashMap<String, Object>();
+ employeeData2.put("EmployeeId", "1");
+ employeeData2.put("ImmageUrl", null);
+ employeeData2.put("ManagerId", "1");
+ employeeData2.put("Age", new Integer(52));
+ employeeData2.put("RoomId", "1");
+ employeeData2.put("EntryDate", date);
+ employeeData2.put("TeamId", "42");
+ employeeData2.put("EmployeeName", "Walter Winter");
+
+ Map<String, Object> locationData2 = new HashMap<String, Object>();
+ Map<String, Object> cityData2 = new HashMap<String, Object>();
+ cityData2.put("PostalCode", "33470");
+ cityData2.put("CityName", "Duckburg");
+ locationData2.put("City", cityData2);
+ locationData2.put("Country", "Calisota");
+
+ employeeData2.put("Location", locationData2);
+
+ employeesData = new ArrayList<Map<String, Object>>();
+ employeesData.add(employeeData);
+ employeesData.add(employeeData2);
+
+ photoData = new HashMap<String, Object>();
+ photoData.put("Id", Integer.valueOf(1));
+ photoData.put("Name", "Mona Lisa");
+ photoData.put("Type", "image/png");
+ photoData.put(
+ "ImageUrl",
+ "http://www.mopo.de/image/view/2012/6/4/16548086,13385561,medRes,maxh,234,maxw,234," +
+ "Parodia_Mona_Lisa_Lego_Hamburger_Morgenpost.jpg");
+ Map<String, Object> imageData = new HashMap<String, Object>();
+ imageData.put("Image", new byte[] { 1, 2, 3, 4 });
+ imageData.put("getImageType", "image/png");
+ photoData.put("Image", imageData);
+ photoData.put("BinaryData", new byte[] { -1, -2, -3, -4 });
+ photoData.put("Содержание", "В лесу шумит водопад. Если он не торопится просп воды");
+
+ roomData = new HashMap<String, Object>();
+ roomData.put("Id", "1");
+ roomData.put("Name", "Neu Schwanstein");
+ roomData.put("Seats", new Integer(20));
+ roomData.put("Version", new Integer(3));
+
+ buildingData = new HashMap<String, Object>();
+ buildingData.put("Id", "1");
+ buildingData.put("Name", "WDF03");
+ buildingData.put("Image", "image");
+ }
+
+ protected void initializeRoomData(final int count) {
+ roomsData = new ArrayList<Map<String, Object>>();
+ for (int i = 1; i <= count; i++) {
+ HashMap<String, Object> tmp = new HashMap<String, Object>();
+ tmp.put("Id", "" + i);
+ tmp.put("Name", "Neu Schwanstein" + i);
+ tmp.put("Seats", new Integer(20));
+ tmp.put("Version", new Integer(3));
+ roomsData.add(tmp);
+ }
+ }
+
+ // CHECKSTYLE:OFF
+ @Before
+ public void setXmlFactory() throws Exception {
+ //
+ System.setProperty(XML_STREAM_WRITER_FACTORY_CLASS, AndroidXmlFactory.class.getName()); // NOSONAR
+ System.setProperty(XML_STREAM_READER_FACTORY_CLASS, AndroidXmlFactory.class.getName()); // NOSONAR
+ }
+ // CHECKSTYLE:ON
+
+ @Before
+ public void setXmlNamespacePrefixes() throws Exception {
+ //
+ Map<String, String> prefixMap = new HashMap<String, String>();
+ prefixMap.put("a", Edm.NAMESPACE_ATOM_2005);
+ prefixMap.put("d", Edm.NAMESPACE_D_2007_08);
+ prefixMap.put("m", Edm.NAMESPACE_M_2007_08);
+ prefixMap.put("xml", Edm.NAMESPACE_XML_1998);
+ prefixMap.put("ру", "http://localhost");
+ prefixMap.put("custom", "http://localhost");
+ prefixMap.put("at", TombstoneCallback.NAMESPACE_TOMBSTONE);
+ XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(prefixMap));
+ }
+
+ protected AtomEntityProvider createAtomEntityProvider() throws EntityProviderException {
+ return new AtomEntityProvider();
+ }
+
+ protected String readFile(final String filename) throws IOException {
+ InputStream in = getFileAsStream(filename);
+
+ byte[] tmp = new byte[8192];
+ int count = in.read(tmp);
+ StringBuilder b = new StringBuilder();
+ while (count >= 0) {
+ b.append(new String(tmp, 0, count));
+ count = in.read(tmp);
+ }
+
+ return b.toString();
+ }
+
+ protected InputStream getFileAsStream(final String filename) throws IOException {
+ InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);
+ if (in == null) {
+ throw new IOException("Requested file '" + filename + "' was not found.");
+ }
+ return in;
+ }
+
+ protected InputStream createContentAsStream(final String content) throws UnsupportedEncodingException {
+ return new ByteArrayInputStream(content.getBytes("UTF-8"));
+ }
+
+ /**
+ *
+ * @param content
+ * @param replaceWhitespaces if <code>true</code> all XML not necessary whitespaces between tags are
+ * @return
+ * @throws UnsupportedEncodingException
+ */
+ protected InputStream createContentAsStream(final String content, final boolean replaceWhitespaces)
+ throws UnsupportedEncodingException {
+ String contentForStream = content;
+ if (replaceWhitespaces) {
+ contentForStream = content.replaceAll(">\\s.<", "><");
+ }
+
+ return new ByteArrayInputStream(contentForStream.getBytes("UTF-8"));
+ }
+
+ /**
+ * Create a map with a 'String' to 'Class<?>' mapping based on given parameters.
+ * Therefore parameters MUST be a set of such pairs.
+ * As example an correct method call would be:
+ * <p>
+ * <code>
+ * createTypeMappings("someKey", Integer.class, "anotherKey", Long.class);
+ * </code>
+ * </p>
+ *
+ * @param firstKeyThenMappingClass
+ * @return
+ */
+ protected Map<String, Object> createTypeMappings(final Object... firstKeyThenMappingClass) {
+ Map<String, Object> typeMappings = new HashMap<String, Object>();
+ if (firstKeyThenMappingClass.length % 2 != 0) {
+ throw new IllegalArgumentException("Got odd number of parameters. Please read javadoc.");
+ }
+ for (int i = 0; i < firstKeyThenMappingClass.length; i += 2) {
+ String key = (String) firstKeyThenMappingClass[i];
+ Class<?> mappingClass = (Class<?>) firstKeyThenMappingClass[i + 1];
+ typeMappings.put(key, mappingClass);
+ }
+ return typeMappings;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb1ba468/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidXmlFactoryTest.java
----------------------------------------------------------------------
diff --git a/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidXmlFactoryTest.java b/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidXmlFactoryTest.java
index e51c345..17364cd 100644
--- a/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidXmlFactoryTest.java
+++ b/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidXmlFactoryTest.java
@@ -24,7 +24,6 @@ import org.apache.olingo.odata2.api.xml.XMLStreamReader;
import org.apache.olingo.odata2.api.xml.XMLStreamWriter;
import org.apache.olingo.odata2.testutil.helper.StringHelper;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -62,7 +61,7 @@ public class AndroidXmlFactoryTest {
@Test
- @Ignore("Will work with robolectric version 2.3")
+// @Ignore("Will work with robolectric version 2.3")
public void createReader() throws Exception {
InputStream stream = StringHelper.encapsulate(BASIC_CONTENT);
XMLStreamReader xmlReader = streamFactory.createXMLStreamReader(stream);
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb1ba468/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidXmlReaderTest.java
----------------------------------------------------------------------
diff --git a/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidXmlReaderTest.java b/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidXmlReaderTest.java
index 51cebbb..af0d6a0 100644
--- a/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidXmlReaderTest.java
+++ b/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AndroidXmlReaderTest.java
@@ -30,7 +30,6 @@ import org.apache.olingo.odata2.testutil.mock.MockFacade;
import org.custommonkey.xmlunit.SimpleNamespaceContext;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -47,7 +46,7 @@ import static org.apache.olingo.odata2.api.xml.XMLStreamReaderFactory.XML_STREAM
*/
@RunWith(RobolectricTestRunner.class)
@Config(manifest=Config.NONE)
-@Ignore("Will work with robolectric version 2.3")
+// @Ignore("Will work with robolectric version 2.3")
public class AndroidXmlReaderTest {
private static final String BASIC_RESULT =
@@ -117,7 +116,6 @@ public class AndroidXmlReaderTest {
AndroidXmlReader xmlReader = new AndroidXmlReader(stream.asStream());
int[] expected = new int[]{
- XMLStreamConstants.START_DOCUMENT,
XMLStreamConstants.START_ELEMENT,
XMLStreamConstants.START_ELEMENT,
XMLStreamConstants.END_ELEMENT,
@@ -126,8 +124,8 @@ public class AndroidXmlReaderTest {
int pos = 0;
while(xmlReader.hasNext()) {
int elementId = xmlReader.next();
-// System.out.println("E: " + elementId);
- assertEquals(expected[pos++], elementId);
+ assertEquals("Unexpected type at position: " + pos,
+ expected[pos++], elementId);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb1ba468/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AtomEntryProducerTest.java
----------------------------------------------------------------------
diff --git a/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AtomEntryProducerTest.java b/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AtomEntryProducerTest.java
new file mode 100644
index 0000000..5f1ee53
--- /dev/null
+++ b/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AtomEntryProducerTest.java
@@ -0,0 +1,849 @@
+/*******************************************************************************
+ * 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.android.xml;
+
+import org.apache.olingo.odata2.api.edm.*;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.exception.ODataMessageException;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.xml.XMLStreamException;
+import org.apache.olingo.odata2.core.commons.ContentType;
+import org.apache.olingo.odata2.core.ep.AtomEntityProvider;
+import org.apache.olingo.odata2.testutil.helper.StringHelper;
+import org.apache.olingo.odata2.testutil.helper.XMLUnitHelper;
+import org.apache.olingo.odata2.testutil.mock.MockFacade;
+import org.custommonkey.xmlunit.SimpleNamespaceContext;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.junit.Test;
+import org.robolectric.annotation.Config;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.custommonkey.xmlunit.XMLAssert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ *
+ */
+@Config(manifest=Config.NONE)
+public class AtomEntryProducerTest extends AndroidTestBase {
+
+ @Test
+ public void noneSyndicationKeepInContentFalseMustNotShowInProperties() throws Exception {
+ // prepare Mock
+ EdmEntitySet employeesSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ EdmCustomizableFeedMappings employeeCustomPropertyMapping = mock(EdmCustomizableFeedMappings.class);
+ when(employeeCustomPropertyMapping.isFcKeepInContent()).thenReturn(Boolean.FALSE);
+ when(employeeCustomPropertyMapping.getFcNsPrefix()).thenReturn("customPre");
+ when(employeeCustomPropertyMapping.getFcNsUri()).thenReturn("http://customUri.com");
+ EdmTyped employeeEntryDateProperty = employeesSet.getEntityType().getProperty("EmployeeName");
+ when(((EdmProperty) employeeEntryDateProperty).getCustomizableFeedMappings()).thenReturn(
+ employeeCustomPropertyMapping);
+
+ Map<String, String> prefixMap = new HashMap<String, String>();
+ prefixMap.put("a", Edm.NAMESPACE_ATOM_2005);
+ prefixMap.put("d", Edm.NAMESPACE_D_2007_08);
+ prefixMap.put("m", Edm.NAMESPACE_M_2007_08);
+ prefixMap.put("xml", Edm.NAMESPACE_XML_1998);
+ prefixMap.put("customPre", "http://customUri.com");
+ XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(prefixMap));
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response = ser.writeEntry(employeesSet, employeeData, DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/customPre:EmployeeName", xmlString);
+ assertXpathNotExists("/a:entry/m:properties/d:EmployeeName", xmlString);
+ }
+
+ @Test
+ public void noneSyndicationKeepInContentTrueMustShowInProperties() throws Exception {
+ // prepare Mock
+ EdmEntitySet employeesSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ EdmCustomizableFeedMappings employeeCustomPropertyMapping = mock(EdmCustomizableFeedMappings.class);
+ when(employeeCustomPropertyMapping.isFcKeepInContent()).thenReturn(Boolean.TRUE);
+ when(employeeCustomPropertyMapping.getFcNsPrefix()).thenReturn("customPre");
+ when(employeeCustomPropertyMapping.getFcNsUri()).thenReturn("http://customUri.com");
+ EdmTyped employeeEntryDateProperty = employeesSet.getEntityType().getProperty("EmployeeName");
+ when(((EdmProperty) employeeEntryDateProperty).getCustomizableFeedMappings()).thenReturn(
+ employeeCustomPropertyMapping);
+
+ Map<String, String> prefixMap = new HashMap<String, String>();
+ prefixMap.put("a", Edm.NAMESPACE_ATOM_2005);
+ prefixMap.put("d", Edm.NAMESPACE_D_2007_08);
+ prefixMap.put("m", Edm.NAMESPACE_M_2007_08);
+ prefixMap.put("xml", Edm.NAMESPACE_XML_1998);
+ prefixMap.put("customPre", "http://customUri.com");
+ XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(prefixMap));
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response = ser.writeEntry(employeesSet, employeeData, DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/customPre:EmployeeName", xmlString);
+ assertXpathExists("/a:entry/m:properties/d:EmployeeName", xmlString);
+ }
+
+ @Test
+ public void noneSyndicationWithNullPrefix() throws Exception {
+ // prepare Mock
+ EdmEntitySet employeesSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ EdmCustomizableFeedMappings employeeCustomPropertyMapping = mock(EdmCustomizableFeedMappings.class);
+ when(employeeCustomPropertyMapping.isFcKeepInContent()).thenReturn(Boolean.TRUE);
+ when(employeeCustomPropertyMapping.getFcNsUri()).thenReturn("http://customUri.com");
+ EdmTyped employeeEntryDateProperty = employeesSet.getEntityType().getProperty("EmployeeName");
+ when(((EdmProperty) employeeEntryDateProperty).getCustomizableFeedMappings()).thenReturn(
+ employeeCustomPropertyMapping);
+
+ Map<String, String> prefixMap = new HashMap<String, String>();
+ prefixMap.put("a", Edm.NAMESPACE_ATOM_2005);
+ prefixMap.put("d", Edm.NAMESPACE_D_2007_08);
+ prefixMap.put("m", Edm.NAMESPACE_M_2007_08);
+ prefixMap.put("xml", Edm.NAMESPACE_XML_1998);
+ prefixMap.put("customPre", "http://customUri.com");
+ XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(prefixMap));
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ boolean thrown = false;
+ try {
+ ser.writeEntry(employeesSet, employeeData, DEFAULT_PROPERTIES);
+ } catch (EntityProviderException e) {
+ verifyRootCause(EntityProviderException.class, EntityProviderException.INVALID_NAMESPACE.getKey(), e);
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Exception should have been thrown");
+ }
+ }
+
+ @Test
+ public void noneSyndicationWithNullUri() throws Exception {
+ // prepare Mock
+ EdmEntitySet employeesSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ EdmCustomizableFeedMappings employeeCustomPropertyMapping = mock(EdmCustomizableFeedMappings.class);
+ when(employeeCustomPropertyMapping.isFcKeepInContent()).thenReturn(Boolean.TRUE);
+ when(employeeCustomPropertyMapping.getFcNsPrefix()).thenReturn("customPre");
+ EdmTyped employeeEntryDateProperty = employeesSet.getEntityType().getProperty("EmployeeName");
+ when(((EdmProperty) employeeEntryDateProperty).getCustomizableFeedMappings()).thenReturn(
+ employeeCustomPropertyMapping);
+
+ Map<String, String> prefixMap = new HashMap<String, String>();
+ prefixMap.put("a", Edm.NAMESPACE_ATOM_2005);
+ prefixMap.put("d", Edm.NAMESPACE_D_2007_08);
+ prefixMap.put("m", Edm.NAMESPACE_M_2007_08);
+ prefixMap.put("xml", Edm.NAMESPACE_XML_1998);
+ prefixMap.put("customPre", "http://customUri.com");
+ XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(prefixMap));
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ boolean thrown = false;
+ try {
+ ser.writeEntry(employeesSet, employeeData, DEFAULT_PROPERTIES);
+ } catch (EntityProviderException e) {
+ verifyRootCause(EntityProviderException.class, EntityProviderException.INVALID_NAMESPACE.getKey(), e);
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Exception should have been thrown");
+ }
+ }
+
+ @Test
+ public void noneSyndicationWithNullUriAndNullPrefix() throws Exception {
+ // prepare Mock
+ EdmEntitySet employeesSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ EdmCustomizableFeedMappings employeeCustomPropertyMapping = mock(EdmCustomizableFeedMappings.class);
+ when(employeeCustomPropertyMapping.isFcKeepInContent()).thenReturn(Boolean.TRUE);
+ EdmTyped employeeEntryDateProperty = employeesSet.getEntityType().getProperty("EmployeeName");
+ when(((EdmProperty) employeeEntryDateProperty).getCustomizableFeedMappings()).thenReturn(
+ employeeCustomPropertyMapping);
+
+ Map<String, String> prefixMap = new HashMap<String, String>();
+ prefixMap.put("a", Edm.NAMESPACE_ATOM_2005);
+ prefixMap.put("d", Edm.NAMESPACE_D_2007_08);
+ prefixMap.put("m", Edm.NAMESPACE_M_2007_08);
+ prefixMap.put("xml", Edm.NAMESPACE_XML_1998);
+ prefixMap.put("f", "http://customUri.com");
+ XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(prefixMap));
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ boolean thrown = false;
+ try {
+ ser.writeEntry(employeesSet, employeeData, DEFAULT_PROPERTIES);
+ } catch (EntityProviderException e) {
+ verifyRootCause(EntityProviderException.class, EntityProviderException.INVALID_NAMESPACE.getKey(), e);
+ thrown = true;
+ }
+ if (!thrown) {
+ fail("Exception should have been thrown");
+ }
+ }
+
+ @Test
+ public void syndicationWithComplexProperty() throws Exception {
+ // prepare Mock
+ EdmEntitySet employeesSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ EdmCustomizableFeedMappings employeeCustomPropertyMapping = mock(EdmCustomizableFeedMappings.class);
+ when(employeeCustomPropertyMapping.isFcKeepInContent()).thenReturn(Boolean.TRUE);
+ when(employeeCustomPropertyMapping.getFcNsPrefix()).thenReturn("customPre");
+ when(employeeCustomPropertyMapping.getFcNsUri()).thenReturn("http://customUri.com");
+ EdmTyped employeeLocationProperty = employeesSet.getEntityType().getProperty("Location");
+ when(((EdmProperty) employeeLocationProperty).getCustomizableFeedMappings()).thenReturn(
+ employeeCustomPropertyMapping);
+
+ Map<String, String> prefixMap = new HashMap<String, String>();
+ prefixMap.put("a", Edm.NAMESPACE_ATOM_2005);
+ prefixMap.put("d", Edm.NAMESPACE_D_2007_08);
+ prefixMap.put("m", Edm.NAMESPACE_M_2007_08);
+ prefixMap.put("xml", Edm.NAMESPACE_XML_1998);
+ prefixMap.put("customPre", "http://customUri.com");
+ XMLUnit.setXpathNamespaceContext(new SimpleNamespaceContext(prefixMap));
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response = ser.writeEntry(employeesSet, employeeData, DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathNotExists("/a:entry/customPre:Location", xmlString);
+ assertXpathExists("/a:entry/m:properties/d:Location", xmlString);
+ }
+
+ private void verifyRootCause(final Class<?> class1, final String key, final ODataMessageException e) {
+
+ Throwable thrownException = e;
+ Throwable lastFoundException = null;
+ if (e.getClass().equals(class1)) {
+ lastFoundException = e;
+ }
+
+ while (thrownException.getCause() != null) {
+ thrownException = thrownException.getCause();
+ if (thrownException.getClass().equals(class1)) {
+ lastFoundException = thrownException;
+ }
+ }
+
+ if (lastFoundException != null) {
+ ODataMessageException msgException = (ODataMessageException) lastFoundException;
+ assertEquals(key, msgException.getMessageReference().getKey());
+ } else {
+ fail("Exception of class: " + class1.getCanonicalName() + " in stacktrace not found.");
+ }
+ }
+
+ @Test
+ public void serializeAtomMediaResource() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+ assertXpathExists("/a:entry/a:content", xmlString);
+ assertXpathEvaluatesTo(ContentType.APPLICATION_OCTET_STREAM.toString(), "/a:entry/a:content/@type", xmlString);
+ assertXpathEvaluatesTo("Employees('1')/$value", "/a:entry/a:content/@src", xmlString);
+ assertXpathExists("/a:entry/m:properties", xmlString);
+
+ assertXpathExists("/a:entry/a:link[@href=\"Employees('1')/$value\"]", xmlString);
+ assertXpathExists("/a:entry/a:link[@rel='edit-media']", xmlString);
+ assertXpathExists("/a:entry/a:link[@type='application/octet-stream']", xmlString);
+
+ assertXpathExists("/a:entry/a:link[@href=\"Employees('1')\"]", xmlString);
+ assertXpathExists("/a:entry/a:link[@rel='edit']", xmlString);
+ assertXpathExists("/a:entry/a:link[@title='Employee']", xmlString);
+
+ // assert navigation link order
+ verifyTagOrdering(xmlString,
+ "link((?:(?!link).)*?)edit",
+ "link((?:(?!link).)*?)edit-media",
+ "link((?:(?!link).)*?)ne_Manager",
+ "link((?:(?!link).)*?)ne_Team",
+ "link((?:(?!link).)*?)ne_Room");
+ }
+
+ private String verifyResponse(final ODataResponse response) throws IOException {
+ assertNotNull(response);
+ assertNotNull(response.getEntity());
+ assertNull("EntityProvider should not set content header", response.getContentHeader());
+ String xmlString = StringHelper.inputStreamToString((InputStream) response.getEntity());
+ return xmlString;
+ }
+
+ @Test
+ public void serializeAtomMediaResourceWithMimeType() throws IOException, XpathException, SAXException,
+ XMLStreamException, ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("abc").build();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+ properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+ assertXpathExists("/a:entry/a:content", xmlString);
+ assertXpathEvaluatesTo("abc", "/a:entry/a:content/@type", xmlString);
+ assertXpathEvaluatesTo("Employees('1')/$value", "/a:entry/a:content/@src", xmlString);
+ assertXpathExists("/a:entry/m:properties", xmlString);
+ }
+
+ /**
+ * Test serialization of empty syndication title property. EmployeeName is set to NULL after the update (which is
+ * allowed because EmployeeName has default Nullable behavior which is true).
+ * Write of an empty atom title tag is allowed within RFC4287 (http://tools.ietf.org/html/rfc4287#section-4.2.14).
+ */
+ @Test
+ public void serializeEmployeeWithNullSyndicationTitleProperty() throws IOException, XpathException, SAXException,
+ XMLStreamException, ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties = EntityProviderWriteProperties.serviceRoot(BASE_URI).build();
+ employeeData.put("EmployeeName", null);
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+ properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/a:title", xmlString);
+ assertXpathEvaluatesTo("", "/a:entry/a:title", xmlString);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+ assertXpathExists("/a:entry/a:content", xmlString);
+ assertXpathEvaluatesTo("Employees('1')/$value", "/a:entry/a:content/@src", xmlString);
+ assertXpathExists("/a:entry/m:properties", xmlString);
+ }
+
+ @Test
+ public void serializeEmployeeAndCheckOrderOfTags() throws IOException, XpathException, SAXException,
+ XMLStreamException, ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("abc").build();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+ properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathExists("/a:entry/a:content", xmlString);
+ // verify self link
+ assertXpathExists("/a:entry/a:link[@href=\"Employees('1')\"]", xmlString);
+ // verify content media link
+ assertXpathExists("/a:entry/a:link[@href=\"Employees('1')/$value\"]", xmlString);
+ // verify one navigation link
+ assertXpathExists("/a:entry/a:link[@title='ne_Manager']", xmlString);
+
+ // verify content
+ assertXpathExists("/a:entry/a:content[@type='abc']", xmlString);
+ // verify properties
+ assertXpathExists("/a:entry/m:properties", xmlString);
+ assertXpathEvaluatesTo("9", "count(/a:entry/m:properties/*)", xmlString);
+
+ // verify order of tags
+ verifyTagOrdering(xmlString, "id", "title", "updated", "category",
+ "link((?:(?!link).)*?)edit",
+ "link((?:(?!link).)*?)edit-media",
+ "link((?:(?!link).)*?)ne_Manager",
+ "content", "properties");
+ }
+
+ @Test
+ public void serializeEmployeeAndCheckOrderOfPropertyTags() throws IOException, XpathException, SAXException,
+ XMLStreamException, ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("abc").build();
+ EdmEntitySet employeeEntitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ ODataResponse response = ser.writeEntry(employeeEntitySet, employeeData, properties);
+ String xmlString = verifyResponse(response);
+
+ // log.debug(xmlString);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathExists("/a:entry/a:content", xmlString);
+ // verify properties
+ assertXpathExists("/a:entry/m:properties", xmlString);
+ assertXpathEvaluatesTo("9", "count(/a:entry/m:properties/*)", xmlString);
+
+ // verify order of tags
+ List<String> expectedPropertyNamesFromEdm = employeeEntitySet.getEntityType().getPropertyNames();
+ verifyTagOrdering(xmlString, expectedPropertyNamesFromEdm.toArray(new String[0]));
+ }
+
+ @Test
+ public void serializeEmployeeAndCheckKeepInContentFalse() throws IOException, XpathException, SAXException,
+ XMLStreamException, ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("abc").build();
+ EdmEntitySet employeeEntitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+
+ // set "keepInContent" to false for EntryDate
+ EdmCustomizableFeedMappings employeeUpdatedMappings = mock(EdmCustomizableFeedMappings.class);
+ when(employeeUpdatedMappings.getFcTargetPath()).thenReturn(EdmTargetPath.SYNDICATION_UPDATED);
+ when(employeeUpdatedMappings.isFcKeepInContent()).thenReturn(Boolean.FALSE);
+ EdmTyped employeeEntryDateProperty = employeeEntitySet.getEntityType().getProperty("EntryDate");
+ when(((EdmProperty) employeeEntryDateProperty).getCustomizableFeedMappings()).thenReturn(employeeUpdatedMappings);
+
+ ODataResponse response = ser.writeEntry(employeeEntitySet, employeeData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathExists("/a:entry/a:content", xmlString);
+ // verify properties
+ assertXpathExists("/a:entry/m:properties", xmlString);
+ assertXpathEvaluatesTo("8", "count(/a:entry/m:properties/*)", xmlString);
+ //
+ assertXpathNotExists("/a:entry/m:properties/d:EntryDate", xmlString);
+
+ // verify order of tags
+ List<String> expectedPropertyNamesFromEdm =
+ new ArrayList<String>(employeeEntitySet.getEntityType().getPropertyNames());
+ expectedPropertyNamesFromEdm.remove(String.valueOf("EntryDate"));
+ verifyTagOrdering(xmlString, expectedPropertyNamesFromEdm.toArray(new String[0]));
+ }
+
+ @Test(expected = EntityProviderException.class)
+ public void serializeAtomEntryWithNullData() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ final EntityProviderWriteProperties properties = EntityProviderWriteProperties.serviceRoot(BASE_URI).build();
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"), null, properties);
+ }
+
+ @Test(expected = EntityProviderException.class)
+ public void serializeAtomEntryWithEmptyHashMap() throws IOException, XpathException, SAXException,
+ XMLStreamException, ODataException {
+ final EntityProviderWriteProperties properties = EntityProviderWriteProperties.serviceRoot(BASE_URI).build();
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"),
+ new HashMap<String, Object>(), properties);
+ }
+
+ @Test
+ public void serializeAtomEntry() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ final EntityProviderWriteProperties properties = EntityProviderWriteProperties.serviceRoot(BASE_URI).build();
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"), roomData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+ assertXpathExists("/a:entry/a:content", xmlString);
+ assertXpathEvaluatesTo(ContentType.APPLICATION_XML.toString(), "/a:entry/a:content/@type", xmlString);
+
+ assertXpathExists("/a:entry/a:content/m:properties", xmlString);
+ }
+
+ @Test
+ public void serializeAtomEntryWithSimplePropertyTypeInformation() throws Exception {
+ final EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).includeSimplePropertyType(true).build();
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"), roomData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/a:content/m:properties", xmlString);
+ assertXpathExists("/a:entry/a:content/m:properties/d:Id[@m:type=\"Edm.String\"]", xmlString);
+ assertXpathExists("/a:entry/a:content/m:properties/d:Name[@m:type=\"Edm.String\"]", xmlString);
+ assertXpathExists("/a:entry/a:content/m:properties/d:Seats[@m:type=\"Edm.Int16\"]", xmlString);
+ assertXpathExists("/a:entry/a:content/m:properties/d:Version[@m:type=\"Edm.Int16\"]", xmlString);
+ }
+
+ @Test
+ public void serializeEntryId() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+ assertXpathExists("/a:entry/a:id", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString() + "Employees('1')", "/a:entry/a:id/text()", xmlString);
+ }
+
+ @Test
+ public void serializeEntryTitle() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/a:title", xmlString);
+ assertXpathEvaluatesTo("text", "/a:entry/a:title/@type", xmlString);
+ assertXpathEvaluatesTo((String) employeeData.get("EmployeeName"), "/a:entry/a:title/text()", xmlString);
+ }
+
+ @Test
+ public void serializeEntryUpdated() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/a:updated", xmlString);
+ assertXpathEvaluatesTo("1999-01-01T00:00:00Z", "/a:entry/a:updated/text()", xmlString);
+ }
+
+ @Test
+ public void serializeIds() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getEntityContainer("Container2").getEntitySet("Photos"), photoData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+ assertXpathExists("/a:entry/a:id", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString() + "Container2.Photos(Id=1,Type='image%2Fpng')",
+ "/a:entry/a:id/text()", xmlString);
+ }
+
+ @Test
+ public void serializeProperties() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/m:properties", xmlString);
+ assertXpathEvaluatesTo((String) employeeData.get("RoomId"), "/a:entry/m:properties/d:RoomId/text()", xmlString);
+ assertXpathEvaluatesTo((String) employeeData.get("TeamId"), "/a:entry/m:properties/d:TeamId/text()", xmlString);
+ }
+
+ @Test
+ public void serializeWithValueEncoding() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ photoData.put("Type", "< Ö >");
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getEntityContainer("Container2").getEntitySet("Photos"), photoData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+ assertXpathExists("/a:entry/a:id", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString() + "Container2.Photos(Id=1,Type='%3C%20%C3%96%20%3E')",
+ "/a:entry/a:id/text()", xmlString);
+ assertXpathEvaluatesTo("Container2.Photos(Id=1,Type='%3C%20%C3%96%20%3E')", "/a:entry/a:link/@href", xmlString);
+ }
+
+ @Test
+ public void serializeCategory() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/a:category", xmlString);
+ assertXpathExists("/a:entry/a:category/@term", xmlString);
+ assertXpathExists("/a:entry/a:category/@scheme", xmlString);
+ assertXpathEvaluatesTo("RefScenario.Employee", "/a:entry/a:category/@term", xmlString);
+ assertXpathEvaluatesTo(Edm.NAMESPACE_SCHEME_2007_08, "/a:entry/a:category/@scheme", xmlString);
+ }
+
+ @Test
+ public void serializeETag() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getEntityContainer("Container2").getEntitySet("Photos"), photoData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathExists("/a:entry/@m:etag", xmlString);
+ assertXpathEvaluatesTo("W/\"1\"", "/a:entry/@m:etag", xmlString);
+ assertEquals("W/\"1\"", response.getETag());
+ }
+
+ @Test
+ public void serializeETagEncoding() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ Edm edm = MockFacade.getMockEdm();
+ EdmTyped roomIdProperty = edm.getEntityType("RefScenario", "Room").getProperty("Id");
+ EdmFacets facets = mock(EdmFacets.class);
+ when(facets.getConcurrencyMode()).thenReturn(EdmConcurrencyMode.Fixed);
+ when(facets.getMaxLength()).thenReturn(3);
+ when(((EdmProperty) roomIdProperty).getFacets()).thenReturn(facets);
+
+ roomData.put("Id", "<\">");
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(edm.getDefaultEntityContainer().getEntitySet("Rooms"), roomData, DEFAULT_PROPERTIES);
+
+ assertNotNull(response);
+ assertNotNull(response.getEntity());
+ assertNull("EntityProvider should not set content header", response.getContentHeader());
+ assertEquals("W/\"<\">.3\"", response.getETag());
+
+ String xmlString = StringHelper.inputStreamToString((InputStream) response.getEntity());
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathExists("/a:entry/@m:etag", xmlString);
+ assertXpathEvaluatesTo("W/\"<\">.3\"", "/a:entry/@m:etag", xmlString);
+ }
+
+ @Test
+ public void serializeCustomMapping() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getEntityContainer("Container2").getEntitySet("Photos"), photoData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathExists("/a:entry/ру:Содержание", xmlString);
+ assertXpathEvaluatesTo((String) photoData.get("Содержание"), "/a:entry/ру:Содержание/text()", xmlString);
+ verifyTagOrdering(xmlString, "category", "Содержание", "content", "properties");
+ }
+
+ @Test
+ public void testCustomProperties() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getEntityContainer("Container2").getEntitySet("Photos");
+
+ ODataResponse response = ser.writeEntry(entitySet, photoData, DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathExists("/a:entry/custom:CustomProperty", xmlString);
+ assertXpathNotExists("/a:entry/custom:CustomProperty/text()", xmlString);
+ assertXpathEvaluatesTo("true", "/a:entry/custom:CustomProperty/@m:null", xmlString);
+ verifyTagOrdering(xmlString, "category", "Содержание", "CustomProperty", "content", "properties");
+ }
+
+ @Test
+ public void testKeepInContentNull() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getEntityContainer("Container2").getEntitySet("Photos");
+
+ EdmProperty customProperty = (EdmProperty) entitySet.getEntityType().getProperty("CustomProperty");
+ when(customProperty.getCustomizableFeedMappings().isFcKeepInContent()).thenReturn(null);
+
+ ODataResponse response = ser.writeEntry(entitySet, photoData, DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry", xmlString);
+ assertXpathExists("/a:entry/custom:CustomProperty", xmlString);
+ assertXpathNotExists("/a:entry/custom:CustomProperty/text()", xmlString);
+ assertXpathEvaluatesTo("true", "/a:entry/custom:CustomProperty/@m:null", xmlString);
+ assertXpathExists("/a:entry/m:properties/d:CustomProperty", xmlString);
+ verifyTagOrdering(xmlString, "category", "Содержание", "CustomProperty", "content", "properties");
+ }
+
+ @Test
+ public void serializeAtomMediaResourceLinks() throws IOException, XpathException, SAXException, XMLStreamException,
+ ODataException {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ ODataResponse response =
+ ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+ DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ String rel = Edm.NAMESPACE_REL_2007_08 + "ne_Manager";
+
+ assertXpathExists("/a:entry/a:link[@href=\"Employees('1')/ne_Manager\"]", xmlString);
+ assertXpathExists("/a:entry/a:link[@rel='" + rel + "']", xmlString);
+ assertXpathExists("/a:entry/a:link[@type='application/atom+xml;type=entry']", xmlString);
+ assertXpathExists("/a:entry/a:link[@title='ne_Manager']", xmlString);
+ }
+
+ @Test
+ public void additionalLink() throws Exception {
+ Map<String, Map<String, Object>> links = new HashMap<String, Map<String, Object>>();
+ links.put("nr_Building", buildingData);
+ final ODataResponse response = createAtomEntityProvider().writeEntry(
+ MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"), roomData,
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).additionalLinks(links).build());
+ final String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/a:link[@title='nr_Building']", xmlString);
+ assertXpathNotExists("/a:entry/a:link[@href=\"Rooms('1')/nr_Building\"]", xmlString);
+ assertXpathExists("/a:entry/a:link[@href=\"Buildings('1')\"]", xmlString);
+ assertXpathNotExists("/a:entry/a:link[@type='application/atom+xml;type=entry']", xmlString);
+ }
+
+ @Test
+ public void additionalLinkToOneOfMany() throws Exception {
+ Map<String, Map<String, Object>> links = new HashMap<String, Map<String, Object>>();
+ links.put("nr_Employees", employeeData);
+ final ODataResponse response = createAtomEntityProvider().writeEntry(
+ MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"), roomData,
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).additionalLinks(links).build());
+ final String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/a:link[@title='nr_Employees']", xmlString);
+ assertXpathNotExists("/a:entry/a:link[@href=\"Rooms('1')/nr_Employees\"]", xmlString);
+ assertXpathExists("/a:entry/a:link[@href=\"Employees('1')\"]", xmlString);
+ assertXpathNotExists("/a:entry/a:link[@type='application/atom+xml;type=feed']", xmlString);
+ }
+
+ @Test
+ public void serializeWithCustomSrcAttributeOnEmployee() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ Map<String, Object> localEmployeeData = new HashMap<String, Object>(employeeData);
+ String mediaResourceSourceKey = "~src";
+ localEmployeeData.put(mediaResourceSourceKey, "http://localhost:8080/images/image1");
+ EdmEntitySet employeesSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ EdmMapping mapping = employeesSet.getEntityType().getMapping();
+ when(mapping.getMediaResourceSourceKey()).thenReturn(mediaResourceSourceKey);
+
+ ODataResponse response = ser.writeEntry(employeesSet, localEmployeeData, DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists(
+ "/a:entry/a:link[@href=\"Employees('1')/$value\" and" +
+ " @rel=\"edit-media\" and @type=\"application/octet-stream\"]", xmlString);
+ assertXpathExists("/a:entry/a:content[@type=\"application/octet-stream\"]", xmlString);
+ assertXpathExists("/a:entry/a:content[@src=\"http://localhost:8080/images/image1\"]", xmlString);
+ }
+
+ @Test
+ public void serializeWithCustomSrcAndTypeAttributeOnEmployee() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ Map<String, Object> localEmployeeData = new HashMap<String, Object>(employeeData);
+ String mediaResourceSourceKey = "~src";
+ localEmployeeData.put(mediaResourceSourceKey, "http://localhost:8080/images/image1");
+ String mediaResourceMimeTypeKey = "~type";
+ localEmployeeData.put(mediaResourceMimeTypeKey, "image/jpeg");
+ EdmEntitySet employeesSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ EdmMapping mapping = employeesSet.getEntityType().getMapping();
+ when(mapping.getMediaResourceSourceKey()).thenReturn(mediaResourceSourceKey);
+ when(mapping.getMediaResourceMimeTypeKey()).thenReturn(mediaResourceMimeTypeKey);
+ when(mapping.getMimeType()).thenReturn(null);
+ ODataResponse response = ser.writeEntry(employeesSet, localEmployeeData, DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists(
+ "/a:entry/a:link[@href=\"Employees('1')/$value\" and" +
+ " @rel=\"edit-media\" and @type=\"image/jpeg\"]", xmlString);
+ assertXpathExists("/a:entry/a:content[@type=\"image/jpeg\"]", xmlString);
+ assertXpathExists("/a:entry/a:content[@src=\"http://localhost:8080/images/image1\"]", xmlString);
+ }
+
+ @Test
+ public void serializeWithCustomSrcAttributeOnRoom() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ Map<String, Object> localRoomData = new HashMap<String, Object>(roomData);
+ String mediaResourceSourceKey = "~src";
+ localRoomData.put(mediaResourceSourceKey, "http://localhost:8080/images/image1");
+ EdmEntitySet roomsSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+ EdmEntityType roomType = roomsSet.getEntityType();
+ EdmMapping mapping = mock(EdmMapping.class);
+ when(roomType.getMapping()).thenReturn(mapping);
+ when(mapping.getMediaResourceSourceKey()).thenReturn(mediaResourceSourceKey);
+
+ ODataResponse response = ser.writeEntry(roomsSet, localRoomData, DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathNotExists(
+ "/a:entry/a:link[@href=\"Rooms('1')/$value\" and" +
+ " @rel=\"edit-media\" and @type=\"application/octet-stream\"]", xmlString);
+ assertXpathNotExists("/a:entry/a:content[@type=\"application/octet-stream\"]", xmlString);
+ assertXpathNotExists("/a:entry/a:content[@src=\"http://localhost:8080/images/image1\"]", xmlString);
+ }
+
+ @Test
+ public void serializeWithCustomSrcAndTypeAttributeOnRoom() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ Map<String, Object> localRoomData = new HashMap<String, Object>(roomData);
+ String mediaResourceSourceKey = "~src";
+ localRoomData.put(mediaResourceSourceKey, "http://localhost:8080/images/image1");
+ String mediaResourceMimeTypeKey = "~type";
+ localRoomData.put(mediaResourceMimeTypeKey, "image/jpeg");
+ EdmEntitySet roomsSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+ EdmEntityType roomType = roomsSet.getEntityType();
+ EdmMapping mapping = mock(EdmMapping.class);
+ when(roomType.getMapping()).thenReturn(mapping);
+ when(mapping.getMediaResourceSourceKey()).thenReturn(mediaResourceSourceKey);
+ when(mapping.getMediaResourceMimeTypeKey()).thenReturn(mediaResourceMimeTypeKey);
+
+ ODataResponse response = ser.writeEntry(roomsSet, localRoomData, DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathNotExists(
+ "/a:entry/a:link[@href=\"Rooms('1')/$value\" and" +
+ " @rel=\"edit-media\" and @type=\"image/jpeg\"]", xmlString);
+ assertXpathNotExists("/a:entry/a:content[@type=\"image/jpeg\"]", xmlString);
+ assertXpathNotExists("/a:entry/a:content[@src=\"http://localhost:8080/images/image1\"]", xmlString);
+ }
+
+ @Test
+ public void assureGetMimeTypeWinsOverGetMediaResourceMimeTypeKey() throws Exception {
+ // Keep this test till version 1.2
+ AtomEntityProvider ser = createAtomEntityProvider();
+ Map<String, Object> localEmployeeData = new HashMap<String, Object>(employeeData);
+ String mediaResourceMimeTypeKey = "~type";
+ localEmployeeData.put(mediaResourceMimeTypeKey, "wrong");
+ String originalMimeTypeKey = "~originalType";
+ localEmployeeData.put(originalMimeTypeKey, "right");
+ EdmEntitySet employeesSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ EdmMapping mapping = employeesSet.getEntityType().getMapping();
+ when(mapping.getMediaResourceMimeTypeKey()).thenReturn(mediaResourceMimeTypeKey);
+ when(mapping.getMimeType()).thenReturn(originalMimeTypeKey);
+ ODataResponse response = ser.writeEntry(employeesSet, localEmployeeData, DEFAULT_PROPERTIES);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:entry/a:content[@type=\"right\"]", xmlString);
+ assertXpathNotExists("/a:entry/a:content[@type=\"wrong\"]", xmlString);
+ }
+
+ private void verifyTagOrdering(final String xmlString, final String... toCheckTags) {
+ XMLUnitHelper.verifyTagOrdering(xmlString, toCheckTags);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/cb1ba468/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AtomFeedProducerTest.java
----------------------------------------------------------------------
diff --git a/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AtomFeedProducerTest.java b/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AtomFeedProducerTest.java
new file mode 100644
index 0000000..eaef473
--- /dev/null
+++ b/odata2-android/src/test/java/org/apache/olingo/odata2/android/xml/AtomFeedProducerTest.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * 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.android.xml;
+
+import org.apache.olingo.odata2.api.commons.InlineCount;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
+import org.apache.olingo.odata2.core.ep.AtomEntityProvider;
+import org.apache.olingo.odata2.testutil.helper.StringHelper;
+import org.apache.olingo.odata2.testutil.mock.MockFacade;
+import org.junit.Before;
+import org.junit.Test;
+import org.robolectric.annotation.Config;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+
+import static org.custommonkey.xmlunit.XMLAssert.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ *
+ */
+@Config(manifest=Config.NONE)
+public class AtomFeedProducerTest extends AndroidTestBase {
+
+ private GetEntitySetUriInfo view;
+
+ @Before
+ public void before() throws Exception {
+ initializeRoomData(1);
+
+ view = mock(GetEntitySetUriInfo.class);
+
+ EdmEntitySet set = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+ when(view.getTargetEntitySet()).thenReturn(set);
+ }
+
+ @Test
+ public void testWithIncludeSimplePropertyTypes() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).includeSimplePropertyType(true).build();
+ ODataResponse response = ser.writeFeed(view.getTargetEntitySet(), roomsData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:feed", xmlString);
+ assertXpathExists("/a:feed/a:entry/a:content/m:properties", xmlString);
+ assertXpathExists("/a:feed/a:entry/a:content/m:properties/d:Id[@m:type=\"Edm.String\"]", xmlString);
+ assertXpathExists("/a:feed/a:entry/a:content/m:properties/d:Name[@m:type=\"Edm.String\"]", xmlString);
+ assertXpathExists("/a:feed/a:entry/a:content/m:properties/d:Seats[@m:type=\"Edm.Int16\"]", xmlString);
+ assertXpathExists("/a:feed/a:entry/a:content/m:properties/d:Version[@m:type=\"Edm.Int16\"]", xmlString);
+ }
+
+ @Test
+ public void testFeedNamespaces() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("mediatype").build();
+ ODataResponse response = ser.writeFeed(view.getTargetEntitySet(), roomsData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:feed", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:feed/@xml:base", xmlString);
+ }
+
+ @Test
+ public void testSelfLink() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("mediatype").build();
+ ODataResponse response = ser.writeFeed(view.getTargetEntitySet(), roomsData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:feed/a:link[@rel='self']", xmlString);
+ assertXpathEvaluatesTo("Rooms", "/a:feed/a:link[@rel='self']/@href", xmlString);
+ assertXpathEvaluatesTo("Rooms", "/a:feed/a:link[@rel='self']/@title", xmlString);
+ }
+
+ @Test
+ public void testCustomSelfLink() throws Exception {
+ String customLink = "Test";
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("mediatype").selfLink(
+ new URI(customLink)).build();
+ ODataResponse response = ser.writeFeed(view.getTargetEntitySet(), roomsData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:feed/a:link[@rel='self']", xmlString);
+ assertXpathEvaluatesTo(customLink, "/a:feed/a:link[@rel='self']/@href", xmlString);
+ assertXpathEvaluatesTo("Rooms", "/a:feed/a:link[@rel='self']/@title", xmlString);
+ }
+
+ @Test
+ public void testFeedMandatoryParts() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("mediatype").build();
+ ODataResponse response = ser.writeFeed(view.getTargetEntitySet(), roomsData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:feed/a:id", xmlString);
+ assertXpathEvaluatesTo(BASE_URI.toASCIIString() + "Rooms", "/a:feed/a:id/text()", xmlString);
+
+ assertXpathExists("/a:feed/a:title", xmlString);
+ assertXpathEvaluatesTo("Rooms", "/a:feed/a:title/text()", xmlString);
+
+ assertXpathExists("/a:feed/a:updated", xmlString);
+ assertXpathExists("/a:feed/a:author", xmlString);
+ assertXpathExists("/a:feed/a:author/a:name", xmlString);
+ }
+
+ private String verifyResponse(final ODataResponse response) throws IOException {
+ assertNotNull(response);
+ assertNotNull(response.getEntity());
+ assertNull("EntityProvider should not set content header", response.getContentHeader());
+ String xmlString = StringHelper.inputStreamToString((InputStream) response.getEntity());
+ return xmlString;
+ }
+
+ @Test
+ public void testInlineCountAllpages() throws Exception {
+ initializeRoomData(20);
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties = EntityProviderWriteProperties.serviceRoot(BASE_URI)
+ .mediaResourceMimeType("mediatype")
+ .inlineCount(Integer.valueOf(103))
+ .inlineCountType(InlineCount.ALLPAGES)
+ .build();
+ ODataResponse response = ser.writeFeed(view.getTargetEntitySet(), roomsData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:feed/m:count", xmlString);
+ assertXpathEvaluatesTo("103", "/a:feed/m:count/text()", xmlString);
+ }
+
+ @Test
+ public void testInlineCountNone() throws Exception {
+ when(view.getInlineCount()).thenReturn(InlineCount.NONE);
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("mediatype").build();
+ ODataResponse response = ser.writeFeed(view.getTargetEntitySet(), roomsData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathNotExists("/a:feed/m:count", xmlString);
+ }
+
+ @Test
+ public void testNextLink() throws Exception {
+ when(view.getInlineCount()).thenReturn(InlineCount.NONE);
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties = EntityProviderWriteProperties.serviceRoot(BASE_URI)
+ .mediaResourceMimeType("mediatype")
+ .nextLink("http://thisisanextlink")
+ .build();
+ ODataResponse response = ser.writeFeed(view.getTargetEntitySet(), roomsData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:feed/a:link[@rel='next']", xmlString);
+ assertXpathEvaluatesTo("http://thisisanextlink", "/a:feed/a:link[@rel='next']/@href", xmlString);
+ }
+
+ @Test(expected = EntityProviderException.class)
+ public void testInlineCountInvalid() throws Exception {
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("mediatype").inlineCountType(
+ InlineCount.ALLPAGES).build();
+ ser.writeFeed(view.getTargetEntitySet(), roomsData, properties);
+ }
+
+ @Test
+ public void testEntries() throws Exception {
+ initializeRoomData(103);
+
+ AtomEntityProvider ser = createAtomEntityProvider();
+ EntityProviderWriteProperties properties =
+ EntityProviderWriteProperties.serviceRoot(BASE_URI).mediaResourceMimeType("mediatype").build();
+ ODataResponse response = ser.writeFeed(view.getTargetEntitySet(), roomsData, properties);
+ String xmlString = verifyResponse(response);
+
+ assertXpathExists("/a:feed/a:entry[1]", xmlString);
+ assertXpathExists("/a:feed/a:entry[2]", xmlString);
+ assertXpathExists("/a:feed/a:entry[103]", xmlString);
+ }
+
+}