You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ar...@apache.org on 2018/04/02 11:32:02 UTC
[21/24] olingo-odata2 git commit: [OLINGO-1253]Client Module for
Olingo v2
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/JsonSerializerDeserializer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/JsonSerializerDeserializer.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/JsonSerializerDeserializer.java
new file mode 100644
index 0000000..aaba634
--- /dev/null
+++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/JsonSerializerDeserializer.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.client.core.ep;
+
+import java.io.BufferedWriter;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.batch.BatchResponsePart;
+import org.apache.olingo.odata2.api.client.batch.BatchPart;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmTypeKind;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.processor.ODataErrorContext;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.client.api.ep.ContentTypeBasedDeserializer;
+import org.apache.olingo.odata2.client.api.ep.ContentTypeBasedSerializer;
+import org.apache.olingo.odata2.client.api.ep.Entity;
+import org.apache.olingo.odata2.client.api.ep.EntityCollection;
+import org.apache.olingo.odata2.client.api.ep.EntityCollectionSerializerProperties;
+import org.apache.olingo.odata2.client.api.ep.EntitySerializerProperties;
+import org.apache.olingo.odata2.client.api.ep.EntityStream;
+import org.apache.olingo.odata2.client.core.ep.deserializer.JsonEntityDeserializer;
+import org.apache.olingo.odata2.client.core.ep.serializer.JsonEntryEntitySerializer;
+import org.apache.olingo.odata2.client.core.ep.serializer.JsonFeedEntitySerializer;
+import org.apache.olingo.odata2.core.batch.BatchRequestWriter;
+import org.apache.olingo.odata2.core.batch.BatchResponseWriter;
+import org.apache.olingo.odata2.core.ep.EntityProviderProducerException;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
+import org.apache.olingo.odata2.core.ep.consumer.JsonErrorDocumentConsumer;
+import org.apache.olingo.odata2.core.ep.util.CircleStreamBuffer;
+
+/**
+ * This class includes methods to serialize deserialize JSON Content type
+ */
+public class JsonSerializerDeserializer implements ContentTypeBasedSerializer, ContentTypeBasedDeserializer {
+
+ private static final String DEFAULT_CHARSET = "UTF-8";
+
+ @Override
+ public ODataResponse writeEntry(EdmEntitySet entitySet, Entity data)
+ throws EntityProviderException {
+
+ final EntitySerializerProperties properties = data == null ?
+ EntitySerializerProperties.serviceRoot(null).build() : data.getWriteProperties() == null ?
+ EntitySerializerProperties.serviceRoot(null).build() : data.getWriteProperties();
+ final EntityInfoAggregator entityInfo = EntityInfoAggregator.create(entitySet, null);
+ CircleStreamBuffer buffer = new CircleStreamBuffer();
+
+ try {
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(buffer.getOutputStream(), DEFAULT_CHARSET));
+ JsonEntryEntitySerializer producer = new JsonEntryEntitySerializer(properties);
+ producer.append(writer, entityInfo, data);
+ writer.flush();
+ buffer.closeWrite();
+
+ return ODataResponse.entity(buffer.getInputStream())
+ .idLiteral(producer.getLocation())
+ .build();
+ } catch (EntityProviderException e) {
+ buffer.close();
+ throw e;
+ } catch (Exception e) {
+ buffer.close();
+ throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+
+ }
+
+ @Override
+ public ODataFeed readFeed(EdmEntitySet entitySet, EntityStream content)
+ throws EntityProviderException {
+ return new JsonEntityDeserializer().readFeed(entitySet, content);
+ }
+
+ @Override
+ public ODataEntry readEntry(EdmEntitySet entitySet, EntityStream content)
+ throws EntityProviderException {
+ return new JsonEntityDeserializer().readEntry(entitySet, content);
+
+ }
+
+ @Override
+ public ODataErrorContext readErrorDocument(InputStream errorDocument) throws EntityProviderException {
+ return new JsonErrorDocumentConsumer().readError(errorDocument);
+ }
+
+ @Override
+ public ODataResponse writeFeed(EdmEntitySet entitySet, EntityCollection data) throws EntityProviderException {
+ final EntityCollectionSerializerProperties properties = data == null ?
+ EntityCollectionSerializerProperties.serviceRoot(null).build() : data.getCollectionProperties() == null ?
+ EntityCollectionSerializerProperties.serviceRoot(null).build() : data.getCollectionProperties();
+ final EntityInfoAggregator entityInfo = EntityInfoAggregator.create(entitySet, null);
+ CircleStreamBuffer buffer = new CircleStreamBuffer();
+
+ try {
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(buffer.getOutputStream(), DEFAULT_CHARSET));
+ new JsonFeedEntitySerializer(properties).appendAsObject(writer, entityInfo, data);
+ writer.flush();
+ buffer.closeWrite();
+
+ return ODataResponse.entity(buffer.getInputStream()).build();
+ } catch (EntityProviderException e) {
+ buffer.close();
+ throw e;
+ } catch (Exception e) {
+ buffer.close();
+ throw new EntityProviderProducerException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+ }
+
+ @Override
+ public ODataResponse writeBatchResponse(List<BatchResponsePart> batchResponseParts) throws BatchException {
+ BatchResponseWriter batchWriter = new BatchResponseWriter();
+ return batchWriter.writeResponse(batchResponseParts);
+ }
+
+ @Override
+ public InputStream readBatchRequest(List<BatchPart> batchParts,
+ String boundary) {
+ BatchRequestWriter batchWriter = new BatchRequestWriter();
+ return batchWriter.writeBatchRequest(batchParts, boundary);
+ }
+
+ @Override
+ public Object readFunctionImport(EdmFunctionImport functionImport, EntityStream content)
+ throws EntityProviderException {
+ try {
+ if (functionImport.getReturnType().getType().getKind() == EdmTypeKind.ENTITY) {
+ return functionImport.getReturnType().getMultiplicity() == EdmMultiplicity.MANY
+ ? new JsonEntityDeserializer().readFeed(functionImport.getEntitySet(), content)
+ : new JsonEntityDeserializer().readEntry(functionImport.getEntitySet(), content);
+ } else {
+ final EntityPropertyInfo info = EntityInfoAggregator.create(functionImport);
+ return functionImport.getReturnType().getMultiplicity() == EdmMultiplicity.MANY ?
+ new JsonEntityDeserializer().readCollection(info, content) :
+ new JsonEntityDeserializer().readProperty(info, content).get(info.getName());
+ }
+ } catch (final EdmException e) {
+ throw new EntityProviderException(e.getMessageReference(), e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntityDeserializer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntityDeserializer.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntityDeserializer.java
new file mode 100644
index 0000000..49c61d7
--- /dev/null
+++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntityDeserializer.java
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.client.core.ep.deserializer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.client.api.ep.EntityStream;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
+
+import com.google.gson.stream.JsonReader;
+
+/**
+ * This class includes method for deserialization of feed and entry data
+ */
+public class JsonEntityDeserializer {
+
+ /** Default used charset for reader */
+ private static final String DEFAULT_CHARSET = "UTF-8";
+
+ /**
+ * Returns an ODataEntry deserializing EntityStream
+ * @param entitySet
+ * @param entityStream
+ * @return ODataEntry
+ * @throws EntityProviderException
+ */
+ public ODataEntry readEntry(final EdmEntitySet entitySet, final EntityStream entityStream)
+ throws EntityProviderException {
+ JsonReader reader = null;
+ EntityProviderException cachedException = null;
+
+ try {
+ EntityInfoAggregator eia = EntityInfoAggregator.create(entitySet);
+ reader = createJsonReader(entityStream.getContent());
+
+ return new JsonEntryDeserializer(reader, eia, entityStream.getReadProperties()).readSingleEntry();
+ } catch (UnsupportedEncodingException e) {
+ cachedException =
+ new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ throw cachedException;
+ } finally {// NOPMD (suppress DoNotThrowExceptionInFinally)
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) { //NOPMD - suppressed
+ if (cachedException != null) { //NOSONAR
+ throw cachedException; //NOSONAR
+ } else {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.//NOSONAR
+ addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns an ODataFeed deserializing EntityStream
+ * @param entitySet
+ * @param entityStream
+ * @return ODataFeed
+ * @throws EntityProviderException
+ */
+ public ODataFeed readFeed(final EdmEntitySet entitySet, final EntityStream entityStream)
+ throws EntityProviderException {
+ return readDeltaFeed(entitySet, entityStream);
+ }
+
+ /**
+ * Returns an ODataDeltaFeed deserializing EntityStream
+ * @param entitySet
+ * @param entityStream
+ * @return ODataDeltaFeed
+ * @throws EntityProviderException
+ */
+ public ODataDeltaFeed readDeltaFeed(final EdmEntitySet entitySet, final EntityStream entityStream)
+ throws EntityProviderException {
+
+ JsonReader reader = null;
+ EntityProviderException cachedException = null;
+
+ try {
+ EntityInfoAggregator eia = EntityInfoAggregator.create(entitySet);
+ reader = createJsonReader(entityStream.getContent());
+
+ JsonFeedDeserializer jfc = new JsonFeedDeserializer(reader, eia, entityStream.getReadProperties());
+ return jfc.readFeedStandalone();
+ } catch (UnsupportedEncodingException e) {
+ cachedException =
+ new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ throw cachedException;
+ } finally {// NOPMD (suppress DoNotThrowExceptionInFinally)
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) { //NOPMD - suppressed
+ if (cachedException != null) { //NOSONAR
+ throw cachedException; //NOSONAR
+ } else {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.//NOSONAR
+ addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+ }
+ }
+ }
+ }
+
+/**
+ *
+ * @param content
+ * @return JsonReader
+ * @throws EntityProviderException
+ * @throws UnsupportedEncodingException
+ */
+ private JsonReader createJsonReader(final Object content) throws EntityProviderException,
+ UnsupportedEncodingException {
+
+ if (content == null) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT
+ .addContent("Got not supported NULL object as content to de-serialize."));
+ }
+
+ if (content instanceof InputStream) {
+ return new JsonReader(new InputStreamReader((InputStream) content, DEFAULT_CHARSET));
+ }
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT
+ .addContent("Found not supported content of class '" + content.getClass() + "' to de-serialize."));
+ }
+
+ public List<?> readCollection(final EntityPropertyInfo info, final EntityStream entityStream)
+ throws EntityProviderException {
+ JsonReader reader = null;
+ EntityProviderException cachedException = null;
+
+ try {
+ reader = createJsonReader(entityStream.getContent());
+ return new JsonPropertyDeserializer().readCollection(reader, info, entityStream.getReadProperties());
+ } catch (final UnsupportedEncodingException e) {
+ cachedException = new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+ .addContent(e.getClass().getSimpleName()), e);
+ throw cachedException;
+ } finally {// NOPMD (suppress DoNotThrowExceptionInFinally)
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (final IOException e) {
+ if (cachedException != null) {
+ throw cachedException;
+ } else {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+ .addContent(e.getClass().getSimpleName()), e);
+ }
+ }
+ }
+ }
+ }
+
+ public Map<String, Object> readProperty(final EntityPropertyInfo propertyInfo, final EntityStream entityStream)
+ throws EntityProviderException {
+ JsonReader reader = null;
+ EntityProviderException cachedException = null;
+
+ try {
+ reader = createJsonReader(entityStream.getContent());
+ return new JsonPropertyDeserializer().readPropertyStandalone(reader, propertyInfo,
+ entityStream.getReadProperties());
+ } catch (final UnsupportedEncodingException e) {
+ cachedException =
+ new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ throw cachedException;
+ } finally {// NOPMD (suppress DoNotThrowExceptionInFinally)
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (final IOException e) {
+ if (cachedException != null) {
+ throw cachedException;
+ } else {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeserializer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeserializer.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeserializer.java
new file mode 100644
index 0000000..f9fb915
--- /dev/null
+++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeserializer.java
@@ -0,0 +1,451 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.client.core.ep.deserializer;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+import org.apache.olingo.odata2.client.api.ep.DeserializerProperties;
+import org.apache.olingo.odata2.client.api.ep.callback.OnDeserializeInlineContent;
+import org.apache.olingo.odata2.core.edm.EdmDateTimeOffset;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
+import org.apache.olingo.odata2.core.ep.aggregator.NavigationPropertyInfo;
+import org.apache.olingo.odata2.core.ep.entry.DeletedEntryMetadataImpl;
+import org.apache.olingo.odata2.core.ep.entry.EntryMetadataImpl;
+import org.apache.olingo.odata2.core.ep.entry.MediaMetadataImpl;
+import org.apache.olingo.odata2.core.ep.entry.ODataEntryImpl;
+import org.apache.olingo.odata2.core.ep.feed.JsonFeedEntry;
+import org.apache.olingo.odata2.core.ep.util.FormatJson;
+
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+
+/**
+ * This class Deserializes JsonEntry payloads
+ */
+public class JsonEntryDeserializer {
+
+ private final EntityInfoAggregator eia;
+ private final JsonReader reader;
+ private final DeserializerProperties readProperties;
+
+ private ODataEntryImpl resultEntry;
+ private Map<String, Object> properties;
+ private MediaMetadataImpl mediaMetadata;
+ private EntryMetadataImpl entryMetadata;
+
+ private DeletedEntryMetadataImpl resultDeletedEntry;
+
+ /**
+ *
+ * @param reader
+ * @param eia
+ * @param readProperties
+ */
+ public JsonEntryDeserializer(final JsonReader reader, final EntityInfoAggregator eia,
+ final DeserializerProperties readProperties) {
+ this.eia = eia;
+ this.readProperties = readProperties;
+ this.reader = reader;
+ }
+
+ /**
+ * Returns ODataEntry deserializing a single entry
+ * @return ODataEntry
+ * @throws EntityProviderException
+ */
+ public ODataEntry readSingleEntry() throws EntityProviderException {
+ try {
+ reader.beginObject();
+ String nextName = reader.nextName();
+ if (FormatJson.D.equals(nextName)) {
+ reader.beginObject();
+ readEntryContent();
+ reader.endObject();
+ } else {
+ handleName(nextName);
+ readEntryContent();
+ }
+ reader.endObject();
+
+ if (reader.peek() != JsonToken.END_DOCUMENT) {
+ throw new EntityProviderException(EntityProviderException.END_DOCUMENT_EXPECTED.addContent(reader.peek()
+ .toString()));
+ }
+ } catch (IOException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ } catch (EdmException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ } catch (IllegalStateException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+
+ return resultEntry;
+ }
+
+ /**
+ * Returns Feed deserializing feed entry
+ * @return JsonFeedEntry
+ * @throws EdmException
+ * @throws EntityProviderException
+ * @throws IOException
+ */
+ public JsonFeedEntry readFeedEntry() throws EdmException, EntityProviderException, IOException {//NOSONAR
+ reader.beginObject();
+ readEntryContent();
+ reader.endObject();
+
+ if (resultDeletedEntry == null) {
+ return new JsonFeedEntry(resultEntry);
+ } else {
+ return new JsonFeedEntry(resultDeletedEntry);
+ }
+ }
+
+ /**
+ *
+ * @throws IOException
+ * @throws EdmException
+ * @throws EntityProviderException
+ */
+ private void readEntryContent() throws IOException, EdmException, EntityProviderException {
+ while (reader.hasNext()) {
+ final String name = reader.nextName();
+ handleName(name);
+ }
+ }
+
+ /**
+ * Ensure that instance field {@link #resultEntry} exists.
+ * If it not already exists create an instance (as well as all other necessary objects like: {@link #properties},
+ * {@link #mediaMetadata}, {@link #entryMetadata}, {@link #expandSelectTree}).
+ */
+ private void ensureODataEntryExists() {
+ if (resultEntry == null) {
+ properties = new HashMap<String, Object>();
+ mediaMetadata = new MediaMetadataImpl();
+ entryMetadata = new EntryMetadataImpl();
+
+ resultEntry = new ODataEntryImpl(properties, mediaMetadata, entryMetadata, null);
+ }
+ }
+
+ /**
+ * Ensure that instance field {@link #resultDeletedEntry} exists.
+ * If it not already exists create an instance.
+ */
+ private void ensureDeletedEntryMetadataExists() {
+ if (resultDeletedEntry == null) {
+ resultDeletedEntry = new DeletedEntryMetadataImpl();
+ }
+ }
+
+ /**
+ *
+ * @param name
+ * @throws IOException
+ * @throws EdmException
+ * @throws EntityProviderException
+ */
+ private void handleName(final String name) throws IOException, EdmException, EntityProviderException {
+ if (FormatJson.METADATA.equals(name)) {
+ ensureODataEntryExists();
+ readMetadata();
+ validateMetadata();
+ } else if (FormatJson.ODATA_CONTEXT.equals(name)) {
+ readODataContext();
+ } else {
+ ensureODataEntryExists();
+ EntityPropertyInfo propertyInfo = eia.getPropertyInfo(name);
+ if (propertyInfo != null) {
+ //TODO: put Type mapping instead of null
+ Object propertyValue = new JsonPropertyDeserializer()
+ .readPropertyValue(reader, propertyInfo, null, readProperties);
+ if (properties.containsKey(name)) {
+ throw new EntityProviderException(EntityProviderException.DOUBLE_PROPERTY.addContent(name));
+ }
+ properties.put(name, propertyValue);
+ } else {
+ readNavigationProperty(name);
+ }
+ }
+ }
+ /**
+ *
+ * @throws IOException
+ * @throws EntityProviderException
+ */
+ private void readODataContext() throws IOException, EntityProviderException {
+ String contextValue = reader.nextString();
+ if (contextValue == null) {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent(FormatJson.ODATA_CONTEXT)
+ .addContent(FormatJson.RESULTS));
+ }
+
+ if (contextValue.startsWith(FormatJson.DELTA_CONTEXT_PREFIX)
+ && contextValue.endsWith(FormatJson.DELTA_CONTEXT_POSTFIX)) {
+ while (reader.hasNext()) {
+ ensureDeletedEntryMetadataExists();
+ String name = reader.nextName();
+ String value = reader.nextString();
+ if (FormatJson.ID.equals(name)) {
+ resultDeletedEntry.setUri(value);
+ } else if (FormatJson.DELTA_WHEN.equals(name)) {
+ Date when = parseWhen(value);
+ resultDeletedEntry.setWhen(when);
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ * @param value
+ * @return Date
+ * @throws EntityProviderException
+ */
+ private Date parseWhen(final String value) throws EntityProviderException {
+ try {
+ return EdmDateTimeOffset.getInstance().valueOfString(value, EdmLiteralKind.JSON, null, Date.class);
+ } catch (EdmSimpleTypeException e) {
+ throw new EntityProviderException(EntityProviderException.INVALID_DELETED_ENTRY_METADATA
+ .addContent("Unparsable format for when field value."), e);
+ }
+ }
+
+ /**
+ *
+ * @throws IOException
+ * @throws EdmException
+ * @throws EntityProviderException
+ */
+ private void readMetadata() throws IOException, EdmException, EntityProviderException {//NOSONAR
+ String name = null;
+ String value = null;
+ reader.beginObject();
+ while (reader.hasNext()) {
+ name = reader.nextName();
+
+ if (FormatJson.PROPERTIES.equals(name)) {
+ reader.skipValue();
+ continue;
+ }
+
+ value = reader.nextString();
+ if (FormatJson.ID.equals(name)) {
+ entryMetadata.setId(value);
+ } else if (FormatJson.URI.equals(name)) {
+ entryMetadata.setUri(value);
+ } else if (FormatJson.TYPE.equals(name)) {
+ String fullQualifiedName = eia.getEntityType().getNamespace() + Edm.DELIMITER + eia.getEntityType().getName();
+ if (!fullQualifiedName.equals(value)) {
+ throw new EntityProviderException(EntityProviderException.INVALID_ENTITYTYPE.addContent(fullQualifiedName)
+ .addContent(value));
+ }
+ } else if (FormatJson.ETAG.equals(name)) {
+ entryMetadata.setEtag(value);
+ } else if (FormatJson.EDIT_MEDIA.equals(name)) {
+ mediaMetadata.setEditLink(value);
+ } else if (FormatJson.MEDIA_SRC.equals(name)) {
+ mediaMetadata.setSourceLink(value);
+ } else if (FormatJson.MEDIA_ETAG.equals(name)) {
+ mediaMetadata.setEtag(value);
+ } else if (FormatJson.CONTENT_TYPE.equals(name)) {
+ mediaMetadata.setContentType(value);
+ } else {
+ throw new EntityProviderException(EntityProviderException.INVALID_CONTENT.addContent(name).addContent(
+ FormatJson.METADATA));
+ }
+ }
+
+ reader.endObject();
+ }
+
+ /**
+ *
+ * @throws EdmException
+ * @throws EntityProviderException
+ */
+ private void validateMetadata() throws EdmException, EntityProviderException {
+ if (eia.getEntityType().hasStream()) {
+ if (mediaMetadata.getSourceLink() == null) {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent(FormatJson.MEDIA_SRC)
+ .addContent(FormatJson.METADATA));
+ }
+ if (mediaMetadata.getContentType() == null) {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent(FormatJson.CONTENT_TYPE)
+ .addContent(FormatJson.METADATA));
+ }
+ } else {
+ if (mediaMetadata.getContentType() != null || mediaMetadata.getEditLink() != null
+ || mediaMetadata.getEtag() != null || mediaMetadata.getSourceLink() != null) {
+ throw new EntityProviderException(EntityProviderException.MEDIA_DATA_NOT_INITIAL);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param navigationPropertyName
+ * @throws IOException
+ * @throws EntityProviderException
+ * @throws EdmException
+ */
+ private void readNavigationProperty(final String navigationPropertyName) throws IOException, EntityProviderException,
+ EdmException {
+ NavigationPropertyInfo navigationPropertyInfo = eia.getNavigationPropertyInfo(navigationPropertyName);
+ if (navigationPropertyInfo == null) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent(navigationPropertyName));
+ }
+
+ JsonToken peek = reader.peek();
+ if (peek == JsonToken.BEGIN_OBJECT) {
+ reader.beginObject();
+ String name = reader.nextName();
+ if (FormatJson.DEFERRED.equals(name)) {
+ reader.beginObject();
+ String uri = reader.nextName();
+ if (FormatJson.URI.equals(uri)) {
+ String value = reader.nextString();
+ entryMetadata.putAssociationUri(navigationPropertyInfo.getName(), value);
+ } else {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent(uri));
+ }
+ reader.endObject();
+ } else {
+ handleInlineEntries(navigationPropertyName, name);
+ }
+ reader.endObject();
+ } else if (peek == JsonToken.NULL) {
+ reader.nextNull();
+ } else {
+ handleArray(navigationPropertyName);
+ }
+ }
+
+ /**
+ * @param navigationPropertyName
+ * @throws EdmException
+ * @throws EntityProviderException
+ * @throws IOException
+ */
+ private void handleArray(final String navigationPropertyName) throws EdmException, EntityProviderException,
+ IOException {
+ final EdmNavigationProperty navigationProperty =
+ (EdmNavigationProperty) eia.getEntityType().getProperty(navigationPropertyName);
+ final EdmEntitySet inlineEntitySet = eia.getEntitySet().getRelatedEntitySet(navigationProperty);
+ final EntityInfoAggregator inlineInfo = EntityInfoAggregator.create(inlineEntitySet);
+ OnDeserializeInlineContent callback = readProperties.getCallback();
+ DeserializerProperties inlineReadProperties;
+ try {
+ if (callback == null) {
+ inlineReadProperties =
+ DeserializerProperties.init()
+ .isValidatingFacets(readProperties.isValidatingFacets())
+ .build();
+
+ } else {
+ inlineReadProperties = callback.receiveReadProperties(readProperties, navigationProperty);
+ }
+ } catch (ODataApplicationException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+
+ ODataFeed feed = new JsonFeedDeserializer(reader, inlineInfo, inlineReadProperties).readInlineFeedStandalone();
+ properties.put(navigationPropertyName, feed);
+ resultEntry.setContainsInlineEntry(true);
+ }
+
+ /**
+ * @param navigationPropertyName
+ * @param name
+ * @throws EdmException
+ * @throws EntityProviderException
+ * @throws IOException
+ */
+ private void handleInlineEntries(final String navigationPropertyName, String name) throws EdmException,
+ EntityProviderException, IOException {
+ EdmNavigationProperty navigationProperty =
+ (EdmNavigationProperty) eia.getEntityType().getProperty(navigationPropertyName);
+ EdmEntitySet inlineEntitySet = eia.getEntitySet().getRelatedEntitySet(navigationProperty);
+ EntityInfoAggregator inlineEia = EntityInfoAggregator.create(inlineEntitySet);
+ OnDeserializeInlineContent callback = readProperties.getCallback();
+ final DeserializerProperties inlineReadProperties;
+ try {
+ if (callback == null) {
+ inlineReadProperties =
+ DeserializerProperties.init()
+ .isValidatingFacets(readProperties.isValidatingFacets())
+ .build();
+
+ } else {
+ inlineReadProperties = callback.receiveReadProperties(readProperties, navigationProperty);
+ }
+ } catch (ODataApplicationException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+ if (navigationProperty.getMultiplicity() == EdmMultiplicity.MANY) {
+ JsonFeedDeserializer inlineConsumer = new JsonFeedDeserializer(reader, inlineEia, inlineReadProperties);
+ ODataFeed feed = inlineConsumer.readStartedInlineFeed(name);
+ properties.put(navigationPropertyName, feed);
+ resultEntry.setContainsInlineEntry(true);
+ } else {
+ JsonEntryDeserializer inlineConsumer = new JsonEntryDeserializer(reader, inlineEia, inlineReadProperties);
+ ODataEntry entry = inlineConsumer.readInlineEntry(name);
+ properties.put(navigationPropertyName, entry);
+ resultEntry.setContainsInlineEntry(true);
+ }
+ }
+
+ /**
+ *
+ * @param name
+ * @return ODataEntry
+ * @throws EdmException
+ * @throws EntityProviderException
+ * @throws IOException
+ */
+ private ODataEntry readInlineEntry(final String name) throws EdmException, EntityProviderException, IOException {
+ // consume the already started content
+ handleName(name);
+ // consume the rest of the entry content
+ readEntryContent();
+ return resultEntry;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonErrorDocumentDeserializer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonErrorDocumentDeserializer.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonErrorDocumentDeserializer.java
new file mode 100644
index 0000000..8b5cc45
--- /dev/null
+++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonErrorDocumentDeserializer.java
@@ -0,0 +1,278 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.client.core.ep.deserializer;
+
+import 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 com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+
+/**
+ * Consuming (read / deserialization) for OData error document in JSON format.
+ */
+public class JsonErrorDocumentDeserializer {
+ /** Default used charset for reader */
+ private static final String DEFAULT_CHARSET = "UTF-8";
+ private static final String FOUND = "' found.";
+ /**
+ * Map containing language code (language - country) to Locale mapping
+ * based on Locale.getAvailableLocales()
+ * */
+ private static final 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.
+ *
+ * @param errorDocument OData error document in JSON format
+ * @return created ODataErrorContext based on input stream content.
+ * @throws EntityProviderException if an exception during read / deserialization occurs.
+ */
+ 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);
+ }
+ }
+
+ /**
+ *
+ * @param reader
+ * @return ODataErrorContext
+ * @throws IOException
+ * @throws EntityProviderException
+ */
+ 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;
+ }
+
+ /**
+ *
+ * @param reader
+ * @return ODataErrorContext
+ * @throws IOException
+ * @throws EntityProviderException
+ */
+ 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;
+ }
+
+ /**
+ *
+ * @param reader
+ * @param errorContext
+ * @throws IOException
+ */
+ private void parseInnerError(final JsonReader reader, final ODataErrorContext errorContext) throws IOException {
+ 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 (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
+ errorContext.setInnerError(readJson(reader));
+ }
+ }
+
+ /**
+ *
+ * @param reader
+ * @return String
+ * @throws IOException
+ */
+ private String readJson(final JsonReader reader) throws IOException {
+ StringBuilder sb = new StringBuilder();
+
+ 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 (token == JsonToken.BEGIN_OBJECT) {
+ reader.beginObject();
+ sb.append("{")
+ .append(readJson(reader))
+ .append("}");
+ reader.endObject();
+ } else if (token == JsonToken.BEGIN_ARRAY) {
+ reader.beginArray();
+ sb.append("[")
+ .append(readJson(reader))
+ .append("]");
+ reader.endArray();
+ } else {
+ sb.append("\"")
+ .append(reader.nextString())
+ .append("\"");
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ *
+ * @param reader
+ * @param errorContext
+ * @throws IOException
+ * @throws EntityProviderException
+ */
+ 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/9e949e40/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonFeedDeserializer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonFeedDeserializer.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonFeedDeserializer.java
new file mode 100644
index 0000000..dd79c3a
--- /dev/null
+++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonFeedDeserializer.java
@@ -0,0 +1,255 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.client.core.ep.deserializer;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+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.client.api.ep.DeserializerProperties;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
+import org.apache.olingo.odata2.core.ep.feed.FeedMetadataImpl;
+import org.apache.olingo.odata2.core.ep.feed.JsonFeedEntry;
+import org.apache.olingo.odata2.core.ep.feed.ODataDeltaFeedImpl;
+import org.apache.olingo.odata2.core.ep.util.FormatJson;
+
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+
+/**
+ * This class Deserializes JsonFeed payloads
+ */
+public class JsonFeedDeserializer {
+
+ private JsonReader reader;
+ private EntityInfoAggregator eia;
+ private DeserializerProperties readProperties;
+ private List<DeletedEntryMetadata> deletedEntries = new ArrayList<DeletedEntryMetadata>();
+ private List<ODataEntry> entries = new ArrayList<ODataEntry>();
+ private FeedMetadataImpl feedMetadata = new FeedMetadataImpl();
+ private boolean resultsArrayPresent = false;
+ private static final String JSONFEED = "JsonFeed";
+
+ /**
+ *
+ * @param reader
+ * @param eia
+ * @param readProperties
+ */
+ public JsonFeedDeserializer(final JsonReader reader, final EntityInfoAggregator eia,
+ final DeserializerProperties readProperties) {
+ this.reader = reader;
+ this.eia = eia;
+ this.readProperties = readProperties;
+ }
+
+ /**
+ *
+ * @return ODataDeltaFeed
+ * @throws EntityProviderException
+ */
+ public ODataDeltaFeed readFeedStandalone() throws EntityProviderException {
+ try {
+ readFeed();
+
+ if (reader.peek() != JsonToken.END_DOCUMENT) {
+
+ throw new EntityProviderException(EntityProviderException.END_DOCUMENT_EXPECTED.addContent(reader.peek()
+ .toString()));
+ }
+
+ } catch (IOException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ } catch (EdmException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ } catch (IllegalStateException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+ return new ODataDeltaFeedImpl(entries, feedMetadata, deletedEntries);
+ }
+
+ /**
+ *
+ * @throws IOException
+ * @throws EdmException
+ * @throws EntityProviderException
+ */
+ private void readFeed() throws IOException, EdmException, EntityProviderException {
+ JsonToken peek = reader.peek();
+ if (peek == JsonToken.BEGIN_ARRAY) {
+ readArrayContent();
+ } else {
+ reader.beginObject();
+ final String nextName = reader.nextName();
+ if (FormatJson.D.equals(nextName)) {
+ if (reader.peek() == JsonToken.BEGIN_ARRAY) {
+ readArrayContent();
+ } else {
+ reader.beginObject();
+ readFeedContent();
+ reader.endObject();
+ }
+ } else {
+ handleName(nextName);
+ readFeedContent();
+ }
+
+ reader.endObject();
+ }
+ }
+
+ /**
+ *
+ * @throws IOException
+ * @throws EdmException
+ * @throws EntityProviderException
+ */
+ private void readFeedContent() throws IOException, EdmException, EntityProviderException {
+ while (reader.hasNext()) {
+ final String nextName = reader.nextName();
+ handleName(nextName);
+ }
+
+ if (!resultsArrayPresent) {
+ throw new EntityProviderException(EntityProviderException.MISSING_RESULTS_ARRAY);
+ }
+ }
+
+ /**
+ *
+ * @param nextName
+ * @throws IOException
+ * @throws EdmException
+ * @throws EntityProviderException
+ */
+ private void handleName(final String nextName) throws IOException, EdmException, EntityProviderException {
+ if (FormatJson.RESULTS.equals(nextName)) {
+ resultsArrayPresent = true;
+ readArrayContent();
+
+ } else if (FormatJson.COUNT.equals(nextName)) {
+ readInlineCount(reader, feedMetadata);
+
+ } else if (FormatJson.NEXT.equals(nextName)) {
+ if (reader.peek() == JsonToken.STRING && feedMetadata.getNextLink() == null) {
+ String nextLink = reader.nextString();
+ feedMetadata.setNextLink(nextLink);
+ } else {
+ throw new EntityProviderException(EntityProviderException.INVALID_CONTENT.addContent(nextName).addContent(
+ JSONFEED));
+ }
+
+ } else if (FormatJson.DELTA.equals(nextName)) {
+ if (reader.peek() == JsonToken.STRING && feedMetadata.getDeltaLink() == null) {
+ String deltaLink = reader.nextString();
+ feedMetadata.setDeltaLink(deltaLink);
+ } else {
+ throw new EntityProviderException(EntityProviderException.INVALID_CONTENT.addContent(nextName).addContent(
+ JSONFEED));
+ }
+ } else {
+ throw new EntityProviderException(EntityProviderException.INVALID_CONTENT.addContent(nextName).addContent(
+ JSONFEED));
+ }
+ }
+
+ /**
+ *
+ * @throws IOException
+ * @throws EdmException
+ * @throws EntityProviderException
+ */
+ private void readArrayContent() throws IOException, EdmException, EntityProviderException {
+ reader.beginArray();
+ while (reader.hasNext()) {
+ final JsonFeedEntry entry = new JsonEntryDeserializer(reader, eia, readProperties).readFeedEntry();
+ if (entry.isODataEntry()) {
+ entries.add(entry.getODataEntry());
+ } else {
+ deletedEntries.add(entry.getDeletedEntryMetadata());
+ }
+ }
+ reader.endArray();
+ }
+
+ /**
+ *
+ * @param reader
+ * @param feedMetadata
+ * @throws IOException
+ * @throws EntityProviderException
+ */
+ protected static void readInlineCount(final JsonReader reader, final FeedMetadataImpl feedMetadata)
+ throws IOException, EntityProviderException {
+ if (reader.peek() == JsonToken.STRING && feedMetadata.getInlineCount() == null) {
+ int inlineCount;
+ try {
+ inlineCount = reader.nextInt();
+ } catch (final NumberFormatException e) {
+ throw new EntityProviderException(EntityProviderException.INLINECOUNT_INVALID.addContent(""), e);
+ }
+ if (inlineCount >= 0) {
+ feedMetadata.setInlineCount(inlineCount);
+ } else {
+ throw new EntityProviderException(EntityProviderException.INLINECOUNT_INVALID.addContent(inlineCount));
+ }
+ } else {
+ throw new EntityProviderException(EntityProviderException.INLINECOUNT_INVALID.addContent(reader.peek()));
+ }
+ }
+
+ /**
+ *
+ * @param name
+ * @return ODataFeed
+ * @throws EdmException
+ * @throws EntityProviderException
+ * @throws IOException
+ */
+ protected ODataFeed readStartedInlineFeed(final String name) throws EdmException, EntityProviderException,
+ IOException {
+ // consume the already started content
+ handleName(name);
+ // consume the rest of the entry content
+ readFeedContent();
+ return new ODataDeltaFeedImpl(entries, feedMetadata);
+ }
+
+ /**
+ *
+ * @return ODataFeed
+ * @throws EdmException
+ * @throws EntityProviderException
+ * @throws IOException
+ */
+ protected ODataFeed readInlineFeedStandalone() throws EdmException, EntityProviderException, IOException {
+ readFeed();
+ return new ODataDeltaFeedImpl(entries, feedMetadata);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonPropertyDeserializer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonPropertyDeserializer.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonPropertyDeserializer.java
new file mode 100644
index 0000000..44d8d07
--- /dev/null
+++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonPropertyDeserializer.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.client.core.ep.deserializer;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.client.api.ep.DeserializerProperties;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityComplexPropertyInfo;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
+import org.apache.olingo.odata2.core.ep.util.FormatJson;
+
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+
+/**
+ * JSON property consumer.
+ */
+public class JsonPropertyDeserializer {
+
+ /**
+ * Deserializes Property
+ * @param reader
+ * @param edmProperty
+ * @param readProperties
+ * @return Map<String, Object>
+ * @throws EntityProviderException
+ */
+ public Map<String, Object> readPropertyStandalone(JsonReader reader, final EdmProperty edmProperty,
+ final DeserializerProperties readProperties) throws EntityProviderException {
+ return readPropertyStandalone(reader, EntityInfoAggregator.create(edmProperty), readProperties);
+ }
+
+ /**
+ * Deserializes Property
+ * @param reader
+ * @param propertyInfo
+ * @param readProperties
+ * @return Map<String, Object>
+ * @throws EntityProviderException
+ */
+ public Map<String, Object> readPropertyStandalone(final JsonReader reader, final EntityPropertyInfo propertyInfo,
+ final DeserializerProperties readProperties) throws EntityProviderException {
+ Map<String, Object> typeMappings = null ;
+ Map<String, Object> result = new HashMap<String, Object>();
+
+ try {
+ reader.beginObject();
+ String nextName = reader.nextName();
+ if (FormatJson.D.equals(nextName)) {
+ reader.beginObject();
+ nextName = reader.nextName();
+ handleName(reader, typeMappings, propertyInfo, readProperties, result, nextName);
+ reader.endObject();
+ } else {
+ handleName(reader, typeMappings, propertyInfo, readProperties, result, nextName);
+ }
+ reader.endObject();
+
+ if (reader.peek() != JsonToken.END_DOCUMENT) {
+ throw new EntityProviderException(EntityProviderException.END_DOCUMENT_EXPECTED.addContent(reader.peek()
+ .toString()));
+ }
+
+ return result;
+ } catch (final IOException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ } catch (final IllegalStateException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+ }
+
+ /**
+ * This method reads through a collection of entities and deserializes each entry
+ * @param reader
+ * @param propertyInfo
+ * @param readProperties
+ * @return List<?>
+ * @throws EntityProviderException
+ */
+ public List<?> readCollection(JsonReader reader, final EntityPropertyInfo propertyInfo,
+ final DeserializerProperties readProperties) throws EntityProviderException {
+ final Object typeMapping = null ;
+ List<Object> result = new ArrayList<Object>();
+ String name = null;
+ boolean wrapped = false;
+ boolean version2 = false;
+
+ try {
+ if (reader.peek() == JsonToken.BEGIN_OBJECT) {
+ reader.beginObject();
+ name = reader.nextName();
+ if (FormatJson.D.equals(name)) {
+ wrapped = true;
+ if (reader.peek() == JsonToken.BEGIN_OBJECT) {
+ reader.beginObject();
+ name = reader.nextName();
+ } else {
+ name = null;
+ }
+ }
+ }
+ if (name != null) {
+ version2 = true;
+ if (FormatJson.METADATA.equals(name)) {
+ readAndCheckTypeInfo(reader,
+ "Collection(" + propertyInfo.getType().getNamespace() + Edm.DELIMITER
+ + propertyInfo.getType().getName() + ")");
+ name = reader.nextName();
+ }
+ if (!FormatJson.RESULTS.equals(name)) {
+ throw new EntityProviderException(EntityProviderException.INVALID_PARENT_TAG
+ .addContent(FormatJson.RESULTS, name));
+ }
+ }
+ reader.beginArray();
+ while (reader.hasNext()) {
+ result.add(readPropertyValue(reader, propertyInfo, typeMapping, readProperties));
+ }
+ reader.endArray();
+ if (version2) {
+ reader.endObject();
+ }
+ if (wrapped) {
+ reader.endObject();
+ }
+
+ if (reader.peek() != JsonToken.END_DOCUMENT) {
+ throw new EntityProviderException(EntityProviderException.END_DOCUMENT_EXPECTED
+ .addContent(reader.peek().toString()));
+ }
+
+ return result;
+ } catch (final EdmException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+ .addContent(e.getClass().getSimpleName()), e);
+ } catch (final IOException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+ .addContent(e.getClass().getSimpleName()), e);
+ } catch (final IllegalStateException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+ .addContent(e.getClass().getSimpleName()), e);
+ }
+ }
+
+ private void handleName(final JsonReader reader, final Map<String, Object> typeMappings,
+ final EntityPropertyInfo entityPropertyInfo, final DeserializerProperties readProperties,
+ final Map<String, Object> result, final String nextName) throws EntityProviderException {
+ if (!entityPropertyInfo.getName().equals(nextName)) {
+ throw new EntityProviderException(EntityProviderException.ILLEGAL_ARGUMENT.addContent(nextName));
+ }
+ final Object mapping = typeMappings == null ? null : typeMappings.get(nextName);
+ final Object propertyValue = readPropertyValue(reader, entityPropertyInfo, mapping, readProperties);
+ result.put(nextName, propertyValue);
+ }
+
+ protected Object readPropertyValue(final JsonReader reader, final EntityPropertyInfo entityPropertyInfo,
+ final Object typeMapping, final DeserializerProperties readProperties)
+ throws EntityProviderException {
+ try {
+ return entityPropertyInfo.isComplex() ?
+ readComplexProperty(reader, (EntityComplexPropertyInfo) entityPropertyInfo, typeMapping, readProperties) :
+ readSimpleProperty(reader, entityPropertyInfo, typeMapping, readProperties);
+ } catch (final EdmException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ } catch (final IOException e) {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+ }
+
+ private Object readSimpleProperty(final JsonReader reader, final EntityPropertyInfo entityPropertyInfo,
+ final Object typeMapping, final DeserializerProperties readProperties)
+ throws EdmException, EntityProviderException, IOException {
+ final EdmSimpleType type = (EdmSimpleType) entityPropertyInfo.getType();
+ Object value = null;
+ final JsonToken tokenType = reader.peek();
+ if (tokenType == JsonToken.NULL) {
+ reader.nextNull();
+ } else {
+ switch (EdmSimpleTypeKind.valueOf(type.getName())) {
+ case Boolean:
+ if (tokenType == JsonToken.BOOLEAN) {
+ value = reader.nextBoolean();
+ value = value.toString();
+ } else {
+ throw new EntityProviderException(EntityProviderException.INVALID_PROPERTY_VALUE
+ .addContent(entityPropertyInfo.getName()));
+ }
+ break;
+ case Byte:
+ case SByte:
+ case Int16:
+ case Int32:
+ if (tokenType == JsonToken.NUMBER) {
+ value = reader.nextInt();
+ value = value.toString();
+ } else {
+ throw new EntityProviderException(EntityProviderException.INVALID_PROPERTY_VALUE
+ .addContent(entityPropertyInfo.getName()));
+ }
+ break;
+ case Single:
+ case Double:
+ if (tokenType == JsonToken.STRING) {
+ value = reader.nextString();
+ } else if (tokenType == JsonToken.NUMBER) {
+ value = reader.nextDouble();
+ value = value.toString();
+ } else {
+ throw new EntityProviderException(EntityProviderException.INVALID_PROPERTY_VALUE
+ .addContent(entityPropertyInfo.getName()));
+ }
+ break;
+ default:
+ if (tokenType == JsonToken.STRING) {
+ value = reader.nextString();
+ } else {
+ throw new EntityProviderException(EntityProviderException.INVALID_PROPERTY_VALUE
+ .addContent(entityPropertyInfo.getName()));
+ }
+ break;
+ }
+ }
+
+ final Class<?> typeMappingClass = typeMapping == null ? type.getDefaultType() : (Class<?>) typeMapping;
+ final EdmFacets facets = readProperties == null || readProperties.isValidatingFacets() ?
+ entityPropertyInfo.getFacets() : null;
+ return type.valueOfString((String) value, EdmLiteralKind.JSON, facets, typeMappingClass);
+ }
+
+ @SuppressWarnings("unchecked")
+ private Object readComplexProperty(final JsonReader reader, final EntityComplexPropertyInfo complexPropertyInfo,
+ final Object typeMapping, final DeserializerProperties readProperties)
+ throws EdmException, EntityProviderException, IOException {
+ if (reader.peek().equals(JsonToken.NULL)) {
+ reader.nextNull();
+ if ((readProperties == null || readProperties.isValidatingFacets()) && complexPropertyInfo.isMandatory()) {
+ throw new EntityProviderException(EntityProviderException.INVALID_PROPERTY_VALUE.addContent(complexPropertyInfo
+ .getName()));
+ }
+ return null;
+ }
+
+ reader.beginObject();
+ Map<String, Object> data = new HashMap<String, Object>();
+
+ Map<String, Object> mapping;
+ if (typeMapping != null) {
+ if (typeMapping instanceof Map) {
+ mapping = (Map<String, Object>) typeMapping;
+ } else {
+ throw new EntityProviderException(EntityProviderException.INVALID_MAPPING.addContent(complexPropertyInfo
+ .getName()));
+ }
+ } else {
+ mapping = new HashMap<String, Object>();
+ }
+
+ while (reader.hasNext()) {
+ final String childName = reader.nextName();
+ if (FormatJson.METADATA.equals(childName)) {
+ readAndCheckTypeInfo(reader,
+ complexPropertyInfo.getType().getNamespace() + Edm.DELIMITER + complexPropertyInfo.getType().getName());
+ } else {
+ EntityPropertyInfo childPropertyInfo = complexPropertyInfo.getPropertyInfo(childName);
+ if (childPropertyInfo == null) {
+ throw new EntityProviderException(EntityProviderException.INVALID_PROPERTY.addContent(childName));
+ }
+ Object childData = readPropertyValue(reader, childPropertyInfo, mapping.get(childName), readProperties);
+ if (data.containsKey(childName)) {
+ throw new EntityProviderException(EntityProviderException.DOUBLE_PROPERTY.addContent(childName));
+ }
+ data.put(childName, childData);
+ }
+ }
+ reader.endObject();
+ return data;
+ }
+
+ protected void readAndCheckTypeInfo(final JsonReader reader, String expectedTypeName)
+ throws IOException, EntityProviderException {
+ reader.beginObject();
+ if (!FormatJson.TYPE.equals(reader.nextName())) {
+ throw new EntityProviderException(EntityProviderException.MISSING_ATTRIBUTE.addContent(FormatJson.TYPE)
+ .addContent(FormatJson.METADATA));
+ }
+ final String actualTypeName = reader.nextString();
+ if (!expectedTypeName.equals(actualTypeName)) {
+ throw new EntityProviderException(EntityProviderException.INVALID_ENTITYTYPE.addContent(expectedTypeName)
+ .addContent(actualTypeName));
+ }
+ reader.endObject();
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlEntityDeserializer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlEntityDeserializer.java b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlEntityDeserializer.java
new file mode 100644
index 0000000..ea3393c
--- /dev/null
+++ b/odata2-lib/odata-client-core/src/main/java/org/apache/olingo/odata2/client/core/ep/deserializer/XmlEntityDeserializer.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.client.core.ep.deserializer;
+
+import java.util.Map;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.olingo.odata2.api.edm.EdmEntitySet;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed;
+import org.apache.olingo.odata2.client.api.ep.EntityStream;
+import org.apache.olingo.odata2.core.commons.XmlHelper;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
+
+/**
+ * Xml entity (content type dependent) consumer for reading input (from <code>content</code>).
+ *
+ *
+ */
+public class XmlEntityDeserializer {
+
+ /**
+ *
+ * @throws EntityProviderException
+ */
+ public XmlEntityDeserializer() throws EntityProviderException {
+ super();
+ }
+
+ /**
+ * Returns an ODataDeltaFeed deserializing EntityStream
+ * @param entitySet
+ * @param entity
+ * @return ODataDeltaFeed
+ * @throws EntityProviderException
+ */
+ public ODataDeltaFeed readFeed(final EdmEntitySet entitySet, final EntityStream entity)
+ throws EntityProviderException {
+ XMLStreamReader reader = null;
+ EntityProviderException cachedException = null;
+
+ try {
+ reader = XmlHelper.createStreamReader(entity.getContent());
+
+ EntityInfoAggregator eia = EntityInfoAggregator.create(entitySet);
+ XmlFeedDeserializer xfc = new XmlFeedDeserializer();
+ return xfc.readFeed(reader, eia, entity.getReadProperties());
+ } catch (EntityProviderException e) {
+ cachedException = e;
+ throw cachedException;
+ } finally { //NOPMD - suppressed
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (XMLStreamException e) {
+ if (cachedException != null) {
+ throw cachedException; //NOSONAR
+ } else {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.//NOSONAR
+ addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns an ODataEntry deserializing EntityStream
+ * @param entitySet
+ * @param entity
+ * @return ODataEntry
+ * @throws EntityProviderException
+ */
+ public ODataEntry readEntry(final EdmEntitySet entitySet, final EntityStream entity)
+ throws EntityProviderException {
+ XMLStreamReader reader = null;
+ EntityProviderException cachedException = null;
+
+ try {
+ reader = XmlHelper.createStreamReader(entity.getContent());
+ EntityInfoAggregator eia = EntityInfoAggregator.create(entitySet);
+
+ return new XmlEntryDeserializer().readEntry(reader, eia, entity.getReadProperties(), false);
+ } catch (EntityProviderException e) {
+ cachedException = e;
+ throw cachedException;
+ } finally {//NOPMD - suppressed
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (XMLStreamException e) {
+ if (cachedException != null) {
+ throw cachedException; //NOSONAR
+ } else {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED.//NOSONAR
+ addContent(e.getClass()
+ .getSimpleName()), e);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ * @param info
+ * @param entityStream
+ * @return
+ * @throws EntityProviderException
+ */
+ public Object readCollection(final EntityPropertyInfo info, EntityStream entityStream)
+ throws EntityProviderException {
+ XMLStreamReader reader = null;
+ EntityProviderException cachedException = null;
+ try {
+ reader = XmlHelper.createStreamReader(entityStream.getContent());
+ return new XmlPropertyDeserializer().readCollection(reader, info, entityStream.getReadProperties());
+ } catch (final EntityProviderException e) {
+ cachedException = e;
+ throw cachedException;
+ } finally {// NOPMD (suppress DoNotThrowExceptionInFinally)
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (final XMLStreamException e) {
+ if (cachedException != null) {
+ throw cachedException;
+ } else {
+ throw new EntityProviderException(EntityProviderException.EXCEPTION_OCCURRED
+ .addContent(e.getClass().getSimpleName()), e);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ * @param propertyInfo
+ * @param entityStream
+ * @return
+ * @throws EntityProviderException
+ */
+ public Map<String, Object> readProperty(final EntityPropertyInfo propertyInfo, final EntityStream entityStream)
+ throws EntityProviderException {
+ XMLStreamReader reader = null;
+ EntityProviderException cachedException = null;
+ try {
+ reader = XmlHelper.createStreamReader(entityStream.getContent());
+ return new XmlPropertyDeserializer().readProperty(reader, propertyInfo, entityStream.getReadProperties());
+ } 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);
+ }
+ }
+ }
+ }
+ }
+}