[OLINGO-196] Added tests and improved innerError handling (XML/JSON)
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/1f37db3e Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/1f37db3e Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/1f37db3e Branch: refs/heads/Olingo-129_PocJpaDataStore Commit: 1f37db3e9b84f074bf9450cc2c7565ccb3fc9cf1 Parents: 6a5fc6c Author: Michael Bolz <[email protected]> Authored: Thu Mar 27 09:16:14 2014 +0100 Committer: Michael Bolz <[email protected]> Committed: Thu Mar 27 09:28:28 2014 +0100 ---------------------------------------------------------------------- .../ep/consumer/JsonErrorDocumentConsumer.java | 37 ++--- .../ep/consumer/XmlErrorDocumentConsumer.java | 23 +-- .../consumer/JsonErrorDocumentConsumerTest.java | 16 +- .../consumer/XmlErrorDocumentConsumerTest.java | 148 +++++++++++-------- 4 files changed, 123 insertions(+), 101 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f37db3e/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumer.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumer.java index 5f5610b..32253d1 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumer.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumer.java @@ -127,11 +127,12 @@ public class JsonErrorDocumentConsumer { } private void parseInnerError(final JsonReader reader, final ODataErrorContext errorContext) throws IOException { - if(reader.peek() == JsonToken.STRING) { + JsonToken token = reader.peek(); + if (token == JsonToken.STRING) { // implementation for parse content as provided by JsonErrorDocumentProducer String innerError = reader.nextString(); errorContext.setInnerError(innerError); - } else if(reader.peek() == JsonToken.BEGIN_OBJECT) { + } else if (token == JsonToken.BEGIN_OBJECT) { // implementation for OData v2 Section 2.2.8.1.2 JSON Error Response // (RFC4627 Section 2.2 -> https://www.ietf.org/rfc/rfc4627.txt)) // currently partial provided @@ -139,33 +140,33 @@ public class JsonErrorDocumentConsumer { } } - - private String readJson(JsonReader reader) throws IOException { + private String readJson(final JsonReader reader) throws IOException { StringBuilder sb = new StringBuilder(); - while(reader.hasNext()) { - if(reader.peek() == JsonToken.NAME) { - if(sb.length() > 0) { + while (reader.hasNext()) { + JsonToken token = reader.peek(); + if (token == JsonToken.NAME) { + if (sb.length() > 0) { sb.append(","); } String name = reader.nextName(); sb.append("\"").append(name).append("\"").append(":"); - } else if(reader.peek() == JsonToken.BEGIN_OBJECT) { + } else if (token == JsonToken.BEGIN_OBJECT) { reader.beginObject(); - sb.append("{"); - sb.append(readJson(reader)); - sb.append("}"); + sb.append("{") + .append(readJson(reader)) + .append("}"); reader.endObject(); - } else if(reader.peek() == JsonToken.BEGIN_ARRAY) { + } else if (token == JsonToken.BEGIN_ARRAY) { reader.beginArray(); - sb.append("["); - sb.append(readJson(reader)); - sb.append("]"); + sb.append("[") + .append(readJson(reader)) + .append("]"); reader.endArray(); } else { - sb.append("\""); - sb.append(reader.nextString()); - sb.append("\""); + sb.append("\"") + .append(reader.nextString()) + .append("\""); } } http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f37db3e/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 4b6b8ac..661e5c7 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 @@ -139,38 +139,29 @@ public class XmlErrorDocumentConsumer { return notFinished(reader, FormatXml.M_ERROR); } - private boolean notFinished(final XMLStreamReader reader, String tagName) throws XMLStreamException { + private boolean notFinished(final XMLStreamReader reader, final String tagName) throws XMLStreamException { boolean finished = reader.isEndElement() && tagName.equals(reader.getLocalName()); return !finished && reader.hasNext(); } private void handleInnerError(final XMLStreamReader reader, final ODataErrorContext errorContext) throws XMLStreamException { - reader.next(); - String innerError = null; - if(reader.isCharacters()) { - innerError = reader.getText(); - } else if(reader.isStartElement()) { - innerError = handleComplexInnerError(reader); - } - errorContext.setInnerError(innerError); - } - private String handleComplexInnerError(XMLStreamReader reader) throws XMLStreamException { StringBuilder sb = new StringBuilder(); - while(notFinished(reader, FormatXml.M_INNER_ERROR)) { - if(reader.hasName()) { + while (notFinished(reader, FormatXml.M_INNER_ERROR)) { + if (reader.hasName() && !FormatXml.M_INNER_ERROR.equals(reader.getLocalName())) { sb.append("<"); - if(reader.isEndElement()) { + if (reader.isEndElement()) { sb.append("/"); } sb.append(reader.getLocalName()).append(">"); - } else if(reader.isCharacters()) { + } else if (reader.isCharacters()) { sb.append(reader.getText()); } reader.next(); } - return sb.toString(); + + errorContext.setInnerError(sb.toString()); } private void handleMessage(final XMLStreamReader reader, final ODataErrorContext errorContext) http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f37db3e/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumerTest.java index 9776289..e5d6c65 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumerTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumerTest.java @@ -43,14 +43,14 @@ public class JsonErrorDocumentConsumerTest extends AbstractConsumerTest { private static final String JSON_ERROR_DOCUMENT_INNER_ERROR = "{\"error\":{\"code\":\"ErrorCode\"," + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, \"innererror\":\"Some InnerError\"}}"; private static final String JSON_ERROR_DOCUMENT_INNER_ERROR_COMPLEX = "{\"error\":{\"code\":\"ErrorCode\"," + - "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, " + - "\"innererror\":{\"moreInner\":\"More Inner Error\"}}}"; + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, " + + "\"innererror\":{\"moreInner\":\"More Inner Error\"}}}"; private static final String JSON_ERROR_DOCUMENT_INNER_ERROR_COMPLEX_OBJECT = "{\"error\":{\"code\":\"ErrorCode\"," + - "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, " + - "\"innererror\":{\"moreInner\":\"More Inner Error\",\"secondInner\":\"Second\"}}}"; + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, " + + "\"innererror\":{\"moreInner\":\"More Inner Error\",\"secondInner\":\"Second\"}}}"; private static final String JSON_ERROR_DOCUMENT_INNER_ERROR_COMPLEX_ARRAY = "{\"error\":{\"code\":\"ErrorCode\"," + - "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, " + - "\"innererror\":{\"innerArray\":[\"More Inner Error\",\"Second\"]}}}"; + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, " + + "\"innererror\":{\"innerArray\":[\"More Inner Error\",\"Second\"]}}}"; private static final String JSON_ERROR_DOCUMENT_INVALID_JSON = "\"error\":{\"code\":\"ErrorCode\"," + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}}"; /* error document with name 'locale' instead of 'lang' for message object */ @@ -119,7 +119,7 @@ public class JsonErrorDocumentConsumerTest extends AbstractConsumerTest { assertEquals("Wrong message", "Message", error.getMessage()); assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); assertEquals("Wrong inner error", - "{\"moreInner\":\"More Inner Error\",\"secondInner\":\"Second\"}", error.getInnerError()); + "{\"moreInner\":\"More Inner Error\",\"secondInner\":\"Second\"}", error.getInnerError()); } @Test @@ -131,7 +131,7 @@ public class JsonErrorDocumentConsumerTest extends AbstractConsumerTest { assertEquals("Wrong message", "Message", error.getMessage()); assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); assertEquals("Wrong inner error", - "{\"innerArray\":[\"More Inner Error\"\"Second\"]}", error.getInnerError()); + "{\"innerArray\":[\"More Inner Error\"\"Second\"]}", error.getInnerError()); } @Test(expected = EntityProviderException.class) http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/1f37db3e/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 index ff3cc4f..7092808 100644 --- 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 @@ -6,9 +6,9 @@ * 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 @@ -37,70 +37,70 @@ import org.junit.Test; 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>"; + "<?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>"; + "<?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>"; + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</code>\n" + + "\t<message xml:lang=\"en-US\">Message</message>\n" + + "<innererror>Some InnerError</innererror>\n" + + "</error>"; private static final String XML_ERROR_DOCUMENT_INNER_ERROR_COMPLEX = - "<?xml version='1.0' encoding='UTF-8'?>\n" + - "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + - "\t<code>ErrorCode</code>\n" + - "\t<message xml:lang=\"en-US\">Message</message>\n" + - "<innererror>" + - "<moreInner>More Inner Error</moreInner>" + - "</innererror>\n" + - "</error>"; + "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + + "\t<code>ErrorCode</code>\n" + + "\t<message xml:lang=\"en-US\">Message</message>\n" + + "<innererror>" + + "<moreInner>More Inner Error</moreInner>" + + "</innererror>\n" + + "</error>"; private static final String XML_ERROR_DOCUMENT_INVALID_XML = - "<?xml version='1.0' encoding='UTF-8'?>\n" + - "<error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">\n" + - "\t<code>ErrorCode</CODE>\n" + - "\t<message xml:lang=\"en-US\">Message</message>\n" + - "</error>"; + "<?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>"; + "<?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>"; + "<?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>"; + "<?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>"; + "<?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>"; + "<?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 @@ -159,6 +159,36 @@ public class XmlErrorDocumentConsumerTest extends AbstractConsumerTest { assertEquals("Wrong inner error", "<moreInner>More Inner Error</moreInner>", error.getInnerError()); } + @Test + public void innerErrorComplexTwo() throws Exception { + String innerErrorText = "<firstTag>tagText</firstTag><secondTag>secondText</secondTag>"; + String innerError = "<innererror>" + innerErrorText + "</innererror>"; + String errorDocument = XML_ERROR_DOCUMENT_INNER_ERROR_COMPLEX.replaceAll( + "<innererror.*error>", innerError); + InputStream in = StringHelper.encapsulate(errorDocument); + ODataErrorContext error = xedc.readError(in); + + assertEquals("Wrong content type", "application/xml", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong inner error", innerErrorText, error.getInnerError()); + } + + @Test + public void innerErrorComplexMoreCharacters() throws Exception { + String innerErrorText = "\n\t<firstTag>tagText</firstTag>\n<secondTag>secondText</secondTag>\n"; + String innerError = "<innererror>" + innerErrorText + "</innererror>"; + String errorDocument = XML_ERROR_DOCUMENT_INNER_ERROR_COMPLEX.replaceAll( + "<innererror.*error>", innerError); + InputStream in = StringHelper.encapsulate(errorDocument); + ODataErrorContext error = xedc.readError(in); + + assertEquals("Wrong content type", "application/xml", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong inner error", innerErrorText, error.getInnerError()); + } + @Test(expected = EntityProviderException.class) public void invalidJson() throws EntityProviderException { InputStream in = StringHelper.encapsulate(XML_ERROR_DOCUMENT_INVALID_XML); @@ -179,7 +209,7 @@ public class XmlErrorDocumentConsumerTest extends AbstractConsumerTest { fail("Expected exception was not thrown"); } catch (EntityProviderException e) { assertEquals("Got wrong exception: " + e.getMessageReference().getKey(), - EntityProviderException.INVALID_STATE, e.getMessageReference()); + EntityProviderException.INVALID_STATE, e.getMessageReference()); throw e; } } @@ -215,7 +245,7 @@ public class XmlErrorDocumentConsumerTest extends AbstractConsumerTest { fail("Expected exception was not thrown"); } catch (EntityProviderException e) { assertEquals("Got wrong exception: " + e.getMessageReference().getKey(), - EntityProviderException.INVALID_STATE, e.getMessageReference()); + EntityProviderException.INVALID_STATE, e.getMessageReference()); throw e; } } @@ -228,7 +258,7 @@ public class XmlErrorDocumentConsumerTest extends AbstractConsumerTest { fail("Expected exception was not thrown"); } catch (EntityProviderException e) { assertEquals("Got wrong exception: " + e.getMessageReference().getKey(), - EntityProviderException.MISSING_PROPERTY, e.getMessageReference()); + EntityProviderException.MISSING_PROPERTY, e.getMessageReference()); assertTrue(e.getMessage().contains("code")); throw e; } @@ -242,7 +272,7 @@ public class XmlErrorDocumentConsumerTest extends AbstractConsumerTest { fail("Expected exception was not thrown"); } catch (EntityProviderException e) { assertEquals("Got wrong exception: " + e.getMessageReference().getKey(), - EntityProviderException.MISSING_PROPERTY, e.getMessageReference()); + EntityProviderException.MISSING_PROPERTY, e.getMessageReference()); assertTrue(e.getMessage().contains("message")); throw e; }
