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:36 UTC

[08/38] git commit: [OLINGO-196] Added JSON implementation

[OLINGO-196] Added JSON 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/69e73b56
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/69e73b56
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/69e73b56

Branch: refs/heads/Olingo-129_PocJpaDataStore
Commit: 69e73b56c4d39492ea6f1832e5bd3f6d2f827522
Parents: 1c2bcda
Author: Michael Bolz <mi...@apache.org>
Authored: Mon Mar 24 13:55:41 2014 +0100
Committer: Michael Bolz <mi...@apache.org>
Committed: Tue Mar 25 10:52:55 2014 +0100

----------------------------------------------------------------------
 .../odata2/core/ep/AtomEntityProvider.java      |   2 +-
 .../odata2/core/ep/JsonEntityProvider.java      |   2 +-
 .../odata2/core/ep/ProviderFacadeImpl.java      |   4 +-
 .../ep/consumer/JsonErrorDocumentConsumer.java  | 170 ++++++++++++++++-
 .../ep/consumer/XmlErrorDocumentConsumer.java   |   7 +-
 .../odata2/core/rt/RuntimeDelegateImpl.java     |   2 +-
 .../odata2/core/ep/ProviderFacadeImplTest.java  |  17 +-
 .../consumer/JsonErrorDocumentConsumerTest.java | 189 +++++++++++++++++++
 .../core/ep/consumer/XmlEntityConsumerTest.java |   4 +-
 9 files changed, 382 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/69e73b56/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
index 3b6f121..441dace 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/AtomEntityProvider.java
@@ -405,7 +405,7 @@ public class AtomEntityProvider implements ContentTypeBasedEntityProvider {
   }
 
   @Override
-  public ODataErrorContext readErrorDocument(InputStream errorDocument) throws EntityProviderException {
+  public ODataErrorContext readErrorDocument(final InputStream errorDocument) throws EntityProviderException {
     XmlErrorDocumentConsumer xmlErrorDocumentConsumer = new XmlErrorDocumentConsumer();
     return xmlErrorDocumentConsumer.readError(errorDocument);
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/69e73b56/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
index 32c68a2..def8c6a 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/JsonEntityProvider.java
@@ -344,7 +344,7 @@ public class JsonEntityProvider implements ContentTypeBasedEntityProvider {
   }
 
   @Override
-  public ODataErrorContext readErrorDocument(InputStream errorDocument) throws EntityProviderException {
+  public ODataErrorContext readErrorDocument(final InputStream errorDocument) throws EntityProviderException {
     return new JsonErrorDocumentConsumer().readError(errorDocument);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/69e73b56/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
index 16c5693..803c97c 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/ProviderFacadeImpl.java
@@ -155,8 +155,8 @@ public class ProviderFacadeImpl implements EntityProviderInterface {
   }
 
   @Override
-  public ODataErrorContext readErrorDocument(InputStream errorDocument, String contentType)
-          throws EntityProviderException {
+  public ODataErrorContext readErrorDocument(final InputStream errorDocument, final String contentType)
+      throws EntityProviderException {
     return create(contentType).readErrorDocument(errorDocument);
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/69e73b56/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 fad6dd9..3b065d0 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
@@ -18,15 +18,38 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.core.ep.consumer;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
 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.ep.util.FormatJson;
 
-import java.io.InputStream;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
 
 /**
  * Consuming (read / deserialization) for OData error document in JSON format.
  */
 public class JsonErrorDocumentConsumer {
+  /** Default used charset for reader */
+  private static final String DEFAULT_CHARSET = "UTF-8";
+  /** 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.
@@ -35,7 +58,148 @@ public class JsonErrorDocumentConsumer {
    * @return created ODataErrorContext based on input stream content.
    * @throws EntityProviderException if an exception during read / deserialization occurs.
    */
-  public ODataErrorContext readError(InputStream errorDocument) throws EntityProviderException {
-    throw new RuntimeException("Not yet implemented");
+  public ODataErrorContext readError(final InputStream errorDocument) throws EntityProviderException {
+    JsonReader reader = createJsonReader(errorDocument);
+    try {
+      return parseJson(reader);
+    } catch (IOException e) {
+      throw new EntityProviderException(
+          EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getMessage()), e);
+    }
+  }
+
+  private ODataErrorContext parseJson(final JsonReader reader) throws IOException, EntityProviderException {
+    ODataErrorContext errorContext;
+
+    if (reader.hasNext()) {
+      reader.beginObject();
+      String currentName = reader.nextName();
+      if (FormatJson.ERROR.equals(currentName)) {
+        errorContext = parseError(reader);
+      } else {
+        throw new EntityProviderException(EntityProviderException.INVALID_STATE.addContent(
+            "Invalid object with name '" + currentName + "' found."));
+      }
+    } else {
+      throw new EntityProviderException(EntityProviderException.INVALID_STATE.addContent(
+          "No content to parse found."));
+    }
+
+    errorContext.setContentType(ContentType.APPLICATION_JSON.toContentTypeString());
+    return errorContext;
+  }
+
+  private ODataErrorContext parseError(final JsonReader reader) throws IOException, EntityProviderException {
+    ODataErrorContext errorContext = new ODataErrorContext();
+    String currentName;
+    reader.beginObject();
+    boolean messageFound = false;
+    boolean codeFound = false;
+
+    while (reader.hasNext()) {
+      currentName = reader.nextName();
+      if (FormatJson.CODE.equals(currentName)) {
+        codeFound = true;
+        errorContext.setErrorCode(getValue(reader));
+      } else if (FormatJson.MESSAGE.equals(currentName)) {
+        messageFound = true;
+        parseMessage(reader, errorContext);
+      } else if (FormatJson.INNER_ERROR.equals(currentName)) {
+        parseInnerError(reader, errorContext);
+      } else {
+        throw new EntityProviderException(EntityProviderException.INVALID_STATE.addContent(
+            "Invalid name '" + currentName + "' found."));
+      }
+    }
+
+    if (!codeFound) {
+      throw new EntityProviderException(
+          EntityProviderException.MISSING_PROPERTY.addContent("Mandatory 'code' property not found.'"));
+    }
+    if (!messageFound) {
+      throw new EntityProviderException(
+          EntityProviderException.MISSING_PROPERTY.addContent("Mandatory 'message' property not found.'"));
+    }
+
+    reader.endObject();
+    return errorContext;
+  }
+
+  private void parseInnerError(final JsonReader reader, final ODataErrorContext errorContext) throws IOException {
+    // implementation for parse content as provided by JsonErrorDocumentProducer
+    String innerError = reader.nextString();
+    errorContext.setInnerError(innerError);
+    // 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 not provided
+  }
+
+  private void parseMessage(final JsonReader reader, final ODataErrorContext errorContext)
+      throws IOException, EntityProviderException {
+
+    reader.beginObject();
+    boolean valueFound = false;
+    boolean langFound = false;
+    String currentName;
+
+    while (reader.hasNext()) {
+      currentName = reader.nextName();
+      if (FormatJson.LANG.equals(currentName)) {
+        langFound = true;
+        String langValue = getValue(reader);
+        if (langValue != null) {
+          errorContext.setLocale(getLocale(langValue));
+        }
+      } else if (FormatJson.VALUE.equals(currentName)) {
+        valueFound = true;
+        errorContext.setMessage(getValue(reader));
+      } else {
+        throw new EntityProviderException(EntityProviderException.INVALID_STATE.addContent("Invalid name '" +
+            currentName + "' found."));
+      }
+    }
+
+    if (!langFound) {
+      throw new EntityProviderException(
+          EntityProviderException.MISSING_PROPERTY.addContent("Mandatory 'lang' property not found.'"));
+    }
+    if (!valueFound) {
+      throw new EntityProviderException(
+          EntityProviderException.MISSING_PROPERTY.addContent("Mandatory 'value' property not found.'"));
+    }
+    reader.endObject();
+  }
+
+  private Locale getLocale(final String langValue) {
+    return AVAILABLE_LOCALES.get(langValue);
+  }
+
+  /**
+   * Read the string value from the JsonReader or 'null' if no value is available.
+   *
+   * @param reader to read from
+   * @return the string value or 'null'
+   * @throws IOException if an exception occurs
+   */
+  private String getValue(final JsonReader reader) throws IOException {
+    JsonToken token = reader.peek();
+    if (JsonToken.NULL == token) {
+      reader.skipValue();
+      return null;
+    }
+    return reader.nextString();
+  }
+
+  private JsonReader createJsonReader(final InputStream in) throws EntityProviderException {
+    if (in == null) {
+      throw new EntityProviderException(EntityProviderException.INVALID_STATE
+          .addContent(("Got not supported NULL object as content to de-serialize.")));
+    }
+    try {
+      return new JsonReader(new InputStreamReader(in, DEFAULT_CHARSET));
+    } catch (final UnsupportedEncodingException e) {
+      throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+          .getSimpleName()), e);
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/69e73b56/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 c7f0a51..21f3f8c 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
@@ -18,17 +18,16 @@
  ******************************************************************************/
 package org.apache.olingo.odata2.core.ep.consumer;
 
+import java.io.InputStream;
+
 import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.processor.ODataErrorContext;
 
-import java.io.InputStream;
-
 /**
  * Consuming (read / deserialization) for OData error document in XML format.
  */
 public class XmlErrorDocumentConsumer {
 
-
   /**
    * Deserialize / read OData error document in ODataErrorContext.
    *
@@ -36,7 +35,7 @@ public class XmlErrorDocumentConsumer {
    * @return created ODataErrorContext based on input stream content.
    * @throws EntityProviderException if an exception during read / deserialization occurs.
    */
-  public ODataErrorContext readError(InputStream errorDocument) throws EntityProviderException {
+  public ODataErrorContext readError(final InputStream errorDocument) throws EntityProviderException {
     throw new RuntimeException("Not yet implementedØ");
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/69e73b56/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rt/RuntimeDelegateImpl.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rt/RuntimeDelegateImpl.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rt/RuntimeDelegateImpl.java
index d3a974c..b081d62 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rt/RuntimeDelegateImpl.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rt/RuntimeDelegateImpl.java
@@ -142,7 +142,7 @@ public class RuntimeDelegateImpl extends RuntimeDelegateInstance {
   }
 
   @Override
-  public String extractExceptionMessage(ODataMessageException exception) {
+  public String extractExceptionMessage(final ODataMessageException exception) {
     Message msg = MessageService.getMessage(Locale.ENGLISH, exception.getMessageReference());
     return msg.getText();
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/69e73b56/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 434d43d..fdc8525 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
@@ -32,6 +32,7 @@ import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 import junit.framework.Assert;
@@ -43,12 +44,14 @@ import org.apache.olingo.odata2.api.edm.EdmEntitySet;
 import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
 import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
 import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
 import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
 import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
 import org.apache.olingo.odata2.api.ep.entry.DeletedEntryMetadata;
 import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
 import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed;
 import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.processor.ODataErrorContext;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
 import org.apache.olingo.odata2.core.commons.ContentType;
 import org.apache.olingo.odata2.core.edm.EdmDateTimeOffset;
@@ -233,6 +236,19 @@ public class ProviderFacadeImplTest extends AbstractConsumerTest {
   }
 
   @Test
+  public void readErrorDocumentJson() throws EntityProviderException {
+    ProviderFacadeImpl providerFacade = new ProviderFacadeImpl();
+    String errorDoc = "{\"error\":{\"code\":\"ErrorCode\",\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}}";
+    ODataErrorContext errorContext = providerFacade.readErrorDocument(StringHelper.encapsulate(errorDoc),
+        ContentType.APPLICATION_JSON.toContentTypeString());
+    //
+    assertEquals("Wrong content type", "application/json", 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>>();
@@ -346,5 +362,4 @@ public class ProviderFacadeImplTest extends AbstractConsumerTest {
         new ProviderFacadeImpl().writeFunctionImport(HttpContentType.APPLICATION_JSON, function, properties, null);
     assertEquals("{\"d\":{\"MaximalAge\":99}}", StringHelper.inputStreamToString((InputStream) result.getEntity()));
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/69e73b56/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
new file mode 100644
index 0000000..204498d
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonErrorDocumentConsumerTest.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.util.Locale;
+
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.processor.ODataErrorContext;
+import org.apache.olingo.odata2.testutil.helper.StringHelper;
+import org.junit.Test;
+
+/**
+ *  
+ */
+public class JsonErrorDocumentConsumerTest extends AbstractConsumerTest {
+
+  private static final String JSON_ERROR_DOCUMENT_SIMPLE = "{\"error\":{\"code\":\"ErrorCode\"," +
+      "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}}";
+  private static final String JSON_ERROR_DOCUMENT_NULL_LOCALE = "{\"error\":{\"code\":\"ErrorCode\"," +
+      "\"message\":{\"lang\":null,\"value\":\"Message\"}}}";
+  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_INVALID_JSON = "\"error\":{\"code\":\"ErrorCode\"," +
+      "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}}";
+  /* error document with name 'locale' instead of 'lang' for message object */
+  private static final String JSON_ERROR_DOCUMENT_UNKNOWN_CONTENT = "{\"error\":{\"code\":\"ErrorCode\"," +
+      "\"message\":{\"locale\":\"en-US\",\"value\":\"Message\"}}}";
+  /* error document without value for message object */
+  private static final String JSON_ERROR_DOCUMENT_INVALID_CONTENT = "{\"error\":{\"code\":\"ErrorCode\"," +
+      "\"message\":{\"lang\":\"en-US\"}}}";
+  private static final String JSON_ERROR_DOCUMENT_MISSING_MESSAGE = "{\"error\":{\"code\":\"ErrorCode\"}}";
+  private static final String JSON_ERROR_DOCUMENT_MISSING_CODE = "{\"error\":{" +
+      "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}}";
+  private static final String JSON_ERROR_DOCUMENT_MISSING_ERROR = "{\"code\":\"ErrorCode\"," +
+      "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}";
+  private JsonErrorDocumentConsumer jedc = new JsonErrorDocumentConsumer();
+
+  @Test
+  public void simpleErrorDocument() throws Exception {
+    InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_SIMPLE);
+    ODataErrorContext error = jedc.readError(in);
+
+    assertEquals("Wrong content type", "application/json", 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 localeNull() throws Exception {
+    InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_NULL_LOCALE);
+    ODataErrorContext error = jedc.readError(in);
+
+    assertEquals("Wrong content type", "application/json", 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(JSON_ERROR_DOCUMENT_INNER_ERROR);
+    ODataErrorContext error = jedc.readError(in);
+
+    assertEquals("Wrong content type", "application/json", 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(JSON_ERROR_DOCUMENT_INVALID_JSON);
+    try {
+      jedc.readError(in);
+      fail("Expected exception was not thrown");
+    } catch (EntityProviderException e) {
+      assertEquals(EntityProviderException.EXCEPTION_OCCURRED, e.getMessageReference());
+      throw e;
+    }
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void invalidEmptyDocument() throws EntityProviderException {
+    InputStream in = StringHelper.encapsulate("");
+    try {
+      jedc.readError(in);
+      fail("Expected exception was not thrown");
+    } catch (EntityProviderException e) {
+      assertEquals(EntityProviderException.EXCEPTION_OCCURRED, e.getMessageReference());
+      throw e;
+    }
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void nullParameter() throws EntityProviderException {
+    try {
+      jedc.readError(null);
+      fail("Expected exception was not thrown");
+    } catch (EntityProviderException e) {
+      assertEquals(EntityProviderException.INVALID_STATE, e.getMessageReference());
+      throw e;
+    }
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void invalidErrorDocumentUnknown() throws EntityProviderException {
+    InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_UNKNOWN_CONTENT);
+    try {
+      jedc.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 invalidErrorDocument() throws EntityProviderException {
+    InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_INVALID_CONTENT);
+    try {
+      jedc.readError(in);
+      fail("Expected exception was not thrown");
+    } catch (EntityProviderException e) {
+      assertEquals(EntityProviderException.MISSING_PROPERTY, e.getMessageReference());
+      throw e;
+    }
+  }
+
+  @Test(expected = EntityProviderException.class)
+  public void invalidErrorDocumentMissingError() throws EntityProviderException {
+    InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_MISSING_ERROR);
+    try {
+      jedc.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 invalidErrorDocumentMissingCode() throws EntityProviderException {
+    InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_MISSING_CODE);
+    try {
+      jedc.readError(in);
+      fail("Expected exception was not thrown");
+    } catch (EntityProviderException e) {
+      assertEquals(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(JSON_ERROR_DOCUMENT_MISSING_MESSAGE);
+    try {
+      jedc.readError(in);
+      fail("Expected exception was not thrown");
+    } catch (EntityProviderException e) {
+      assertEquals(EntityProviderException.MISSING_PROPERTY, e.getMessageReference());
+      assertTrue(e.getMessage().contains("message"));
+      throw e;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/69e73b56/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
index b357c71..59df942 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
@@ -577,7 +577,7 @@ public class XmlEntityConsumerTest extends AbstractXmlConsumerTest {
     assertEquals("Building 1", inlineBuildingProps.get("Name"));
     assertNull(inlineBuildingProps.get("Image"));
     assertNull(inlineBuildingProps.get("nb_Rooms"));
-    
+
     assertEquals("Rooms('1')/nr_Employees", entry.getMetadata().getAssociationUris("nr_Employees").get(0));
     assertEquals("Rooms('1')/nr_Building", entry.getMetadata().getAssociationUris("nr_Building").get(0));
   }
@@ -2325,7 +2325,7 @@ public class XmlEntityConsumerTest extends AbstractXmlConsumerTest {
     Map<String, Object> properties = result.getProperties();
     assertEquals(1, properties.size());
     assertEquals("1", properties.get("Id"));
-    
+
     assertEquals("Rooms('1')/nr_Building", result.getMetadata().getAssociationUris("nr_Building").get(0));
     assertEquals("Rooms('1')/nr_Employees", result.getMetadata().getAssociationUris("nr_Employees").get(0));
   }