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/18 07:06:38 UTC
[10/38] git commit: [OLINGO-196] Added XML implementation
[OLINGO-196] Added XML implementation
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/9b1ba14b
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/9b1ba14b
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/9b1ba14b
Branch: refs/heads/Olingo-129_PocJpaDataStore
Commit: 9b1ba14ba5a12a9237904729b884836f77527128
Parents: 69e73b5
Author: Michael Bolz <mi...@apache.org>
Authored: Tue Mar 25 16:12:53 2014 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Wed Mar 26 06:34:49 2014 +0100
----------------------------------------------------------------------
.../olingo/odata2/core/commons/XmlHelper.java | 4 +
.../ep/consumer/XmlErrorDocumentConsumer.java | 122 +++++++++-
.../odata2/core/ep/ProviderFacadeImplTest.java | 18 ++
.../consumer/XmlErrorDocumentConsumerTest.java | 228 +++++++++++++++++++
4 files changed, 371 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9b1ba14b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/XmlHelper.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/XmlHelper.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/XmlHelper.java
index f4bf49b..3efa87b 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/XmlHelper.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/commons/XmlHelper.java
@@ -32,6 +32,10 @@ public class XmlHelper {
private static final String DEFAULT_CHARSET = "UTF-8";
public static XMLStreamReader createStreamReader(final Object content) throws EntityProviderException {
+ if (content == null) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT
+ .addContent("Got not allowed NULL parameter for creation of XMLStreamReader."));
+ }
XMLStreamReader streamReader;
try {
XMLInputFactory factory = XMLInputFactory.newInstance();
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9b1ba14b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlErrorDocumentConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlErrorDocumentConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlErrorDocumentConsumer.java
index 21f3f8c..d21cec4 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlErrorDocumentConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlErrorDocumentConsumer.java
@@ -19,14 +19,35 @@
package org.apache.olingo.odata2.core.ep.consumer;
import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import org.apache.olingo.odata2.api.edm.Edm;
import org.apache.olingo.odata2.api.ep.EntityProviderException;
import org.apache.olingo.odata2.api.processor.ODataErrorContext;
+import org.apache.olingo.odata2.core.commons.ContentType;
+import org.apache.olingo.odata2.core.commons.XmlHelper;
+import org.apache.olingo.odata2.core.ep.util.FormatXml;
+
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
/**
* Consuming (read / deserialization) for OData error document in XML format.
*/
public class XmlErrorDocumentConsumer {
+ /** Map containing language code (language - country) to Locale mapping
+ * based on Locale.getAvailableLocales()
+ * */
+ private final static Map<String, Locale> AVAILABLE_LOCALES = new HashMap<String, Locale>();
+ static {
+ Locale[] locales = Locale.getAvailableLocales();
+ for (Locale l : locales) {
+ AVAILABLE_LOCALES.put(l.getLanguage() + "-" + l.getCountry(), l);
+ }
+ }
/**
* Deserialize / read OData error document in ODataErrorContext.
@@ -36,6 +57,105 @@ public class XmlErrorDocumentConsumer {
* @throws EntityProviderException if an exception during read / deserialization occurs.
*/
public ODataErrorContext readError(final InputStream errorDocument) throws EntityProviderException {
- throw new RuntimeException("Not yet implementedØ");
+ XMLStreamReader reader = null;
+ EntityProviderException cachedException = null;
+
+ try {
+ reader = XmlHelper.createStreamReader(errorDocument);
+ return parserError(reader);
+ } catch (XMLStreamException e) {
+ cachedException = new EntityProviderException(EntityProviderException.INVALID_STATE.addContent(
+ e.getMessage()), e);
+ throw cachedException;
+ } catch (EntityProviderException e) {
+ cachedException = e;
+ throw cachedException;
+ } finally {// NOPMD (suppress DoNotThrowExceptionInFinally)
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (XMLStreamException e) {
+ if (cachedException != null) {
+ throw cachedException;
+ } else {
+ throw new EntityProviderException(
+ EntityProviderException.EXCEPTION_OCCURRED.addContent(
+ e.getClass().getSimpleName()), e);
+ }
+ }
+ }
+ }
+ }
+
+ private ODataErrorContext parserError(XMLStreamReader reader) throws XMLStreamException, EntityProviderException {
+ // read xml tag
+ reader.require(XMLStreamConstants.START_DOCUMENT, null, null);
+ reader.nextTag();
+
+ // read error tag
+ reader.require(XMLStreamConstants.START_ELEMENT, Edm.NAMESPACE_M_2007_08, FormatXml.M_ERROR);
+
+ // read error data
+ boolean codeFound = false;
+ boolean messageFound = false;
+ ODataErrorContext errorContext = new ODataErrorContext();
+ while(notFinished(reader)) {
+ reader.nextTag();
+ if(reader.isStartElement()) {
+ String name = reader.getLocalName();
+ if(FormatXml.M_CODE.equals(name)) {
+ codeFound = true;
+ handleCode(reader, errorContext);
+ } else if(FormatXml.M_MESSAGE.equals(name)) {
+ messageFound = true;
+ handleMessage(reader, errorContext);
+ } else if(FormatXml.M_INNER_ERROR.equals(name)) {
+ handleInnerError(reader, errorContext);
+ } else {
+ throw new EntityProviderException(
+ EntityProviderException.INVALID_CONTENT.addContent(name, FormatXml.M_ERROR));
+ }
+ }
+ }
+ validate(codeFound, messageFound);
+
+ errorContext.setContentType(ContentType.APPLICATION_XML.toContentTypeString());
+ return errorContext;
+ }
+
+ private void validate(boolean codeFound, boolean messageFound) throws EntityProviderException {
+ if (!codeFound) {
+ throw new EntityProviderException(
+ EntityProviderException.MISSING_PROPERTY.addContent("Mandatory 'code' property not found.'"));
+ } else if (!messageFound) {
+ throw new EntityProviderException(
+ EntityProviderException.MISSING_PROPERTY.addContent("Mandatory 'message' property not found.'"));
+ }
+ }
+
+ private boolean notFinished(XMLStreamReader reader) throws XMLStreamException {
+ boolean finished = reader.isEndElement() && FormatXml.M_ERROR.equals(reader.getLocalName());
+ return !finished && reader.hasNext();
+ }
+
+ private void handleInnerError(XMLStreamReader reader, ODataErrorContext errorContext) throws XMLStreamException {
+ String innerError = reader.getElementText();
+ errorContext.setInnerError(innerError);
+ }
+
+ private void handleMessage(XMLStreamReader reader, ODataErrorContext errorContext) throws XMLStreamException {
+ String lang = reader.getAttributeValue(Edm.NAMESPACE_XML_1998, FormatXml.XML_LANG);
+ errorContext.setLocale(getLocale(lang));
+ String message = reader.getElementText();
+ errorContext.setMessage(message);
+ }
+
+ private void handleCode(XMLStreamReader reader, ODataErrorContext errorContext) throws XMLStreamException {
+ String code = reader.getElementText();
+ errorContext.setErrorCode(code);
+ }
+
+ private Locale getLocale(final String langValue) {
+ return AVAILABLE_LOCALES.get(langValue);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9b1ba14b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java
index fdc8525..58577aa 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImplTest.java
@@ -249,6 +249,24 @@ public class ProviderFacadeImplTest extends AbstractConsumerTest {
}
@Test
+ public void readErrorDocumentXml() throws EntityProviderException {
+ ProviderFacadeImpl providerFacade = new ProviderFacadeImpl();
+ String errorDoc =
+ "<?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>";
+ ODataErrorContext errorContext = providerFacade.readErrorDocument(StringHelper.encapsulate(errorDoc),
+ ContentType.APPLICATION_XML.toContentTypeString());
+ //
+ assertEquals("Wrong content type", "application/xml", errorContext.getContentType());
+ assertEquals("Wrong message", "Message", errorContext.getMessage());
+ assertEquals("Wrong error code", "ErrorCode", errorContext.getErrorCode());
+ assertEquals("Wrong locale for lang", Locale.US, errorContext.getLocale());
+ }
+
+ @Test
public void writeFeed() throws Exception {
final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
List<Map<String, Object>> propertiesList = new ArrayList<Map<String, Object>>();
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9b1ba14b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlErrorDocumentConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlErrorDocumentConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlErrorDocumentConsumerTest.java
new file mode 100644
index 0000000..4106bcd
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlErrorDocumentConsumerTest.java
@@ -0,0 +1,228 @@
+/*******************************************************************************
+ * 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.core.ep.consumer;
+
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.processor.ODataErrorContext;
+import org.apache.olingo.odata2.testutil.helper.StringHelper;
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.util.Locale;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class XmlErrorDocumentConsumerTest extends AbstractConsumerTest {
+
+ 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_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 XmlErrorDocumentConsumer xedc = new XmlErrorDocumentConsumer();
+
+ @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(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;
+ }
+ }
+}