You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by il...@apache.org on 2014/03/20 11:27:10 UTC

[16/21] [OLINGO-200] New StAX (replacing DOM) (de)serializers in place - still IT to check

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ODataSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ODataSerializer.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ODataSerializer.java
index 9110d2b..e7f9682 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ODataSerializer.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/op/ODataSerializer.java
@@ -24,9 +24,8 @@ import java.io.Writer;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.data.Feed;
 import org.apache.olingo.client.api.data.Link;
+import org.apache.olingo.client.api.data.Property;
 import org.apache.olingo.client.api.format.ODataFormat;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 
 /**
  * Utility class for serialization.
@@ -66,22 +65,20 @@ public interface ODataSerializer extends Serializable {
   void entry(Entry obj, Writer writer);
 
   /**
-   * Writes entry content onto the given stream.
+   * Writes the property object onto the given stream.
    *
-   * @param element element to be streamed.
-   * @param format streaming format.
+   * @param property object to be streamed.
    * @param out output stream.
    */
-  void property(Element element, ODataFormat format, OutputStream out);
+  void property(Property property, OutputStream out);
 
   /**
-   * Writes entry content by the given writer.
+   * Writes the property object by the given writer.
    *
-   * @param element element to be streamed.
-   * @param format streaming format.
+   * @param property object to be streamed.
    * @param writer writer.
    */
-  void property(Element element, ODataFormat format, Writer writer);
+  void property(Property property, Writer writer);
 
   /**
    * Writes link onto the given stream.
@@ -100,20 +97,4 @@ public interface ODataSerializer extends Serializable {
    * @param writer writer.
    */
   void link(Link link, ODataFormat format, Writer writer);
-
-  /**
-   * Writes DOM object onto the given stream.
-   *
-   * @param content DOM to be streamed.
-   * @param out output stream.
-   */
-  void dom(Node content, OutputStream out);
-
-  /**
-   * Writes DOM object by the given writer.
-   *
-   * @param content DOM to be streamed.
-   * @param writer writer.
-   */
-  void dom(Node content, Writer writer);
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/GeoUtils.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/GeoUtils.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/GeoUtils.java
new file mode 100644
index 0000000..c4270fe
--- /dev/null
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/GeoUtils.java
@@ -0,0 +1,90 @@
+/*
+ * 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.client.api.utils;
+
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.geospatial.Geospatial;
+
+public final class GeoUtils {
+
+  private GeoUtils() {
+    // Empty private constructor for static utility classes       
+  }
+
+  public static Geospatial.Dimension getDimension(final ODataJClientEdmPrimitiveType type) {
+    Geospatial.Dimension dimension;
+
+    switch (type) {
+      case Geography:
+      case GeographyCollection:
+      case GeographyLineString:
+      case GeographyMultiLineString:
+      case GeographyPoint:
+      case GeographyMultiPoint:
+      case GeographyPolygon:
+      case GeographyMultiPolygon:
+        dimension = Geospatial.Dimension.GEOGRAPHY;
+        break;
+
+      default:
+        dimension = Geospatial.Dimension.GEOMETRY;
+    }
+
+    return dimension;
+  }
+
+  public static ODataJClientEdmPrimitiveType getType(final Geospatial.Dimension dimension, final String elementName) {
+    ODataJClientEdmPrimitiveType type = null;
+
+    if (Constants.ELEM_POINT.equals(elementName)) {
+      type = dimension == Geospatial.Dimension.GEOGRAPHY
+              ? ODataJClientEdmPrimitiveType.GeographyPoint
+              : ODataJClientEdmPrimitiveType.GeometryPoint;
+    } else if (Constants.ELEM_MULTIPOINT.equals(elementName)) {
+      type = dimension == Geospatial.Dimension.GEOGRAPHY
+              ? ODataJClientEdmPrimitiveType.GeographyMultiPoint
+              : ODataJClientEdmPrimitiveType.GeometryMultiPoint;
+    } else if (Constants.ELEM_LINESTRING.equals(elementName)) {
+      type = dimension == Geospatial.Dimension.GEOGRAPHY
+              ? ODataJClientEdmPrimitiveType.GeographyLineString
+              : ODataJClientEdmPrimitiveType.GeometryLineString;
+    } else if (Constants.ELEM_MULTILINESTRING.equals(elementName)) {
+      type = dimension == Geospatial.Dimension.GEOGRAPHY
+              ? ODataJClientEdmPrimitiveType.GeographyMultiLineString
+              : ODataJClientEdmPrimitiveType.GeometryMultiLineString;
+    } else if (Constants.ELEM_POLYGON.equals(elementName)) {
+      type = dimension == Geospatial.Dimension.GEOGRAPHY
+              ? ODataJClientEdmPrimitiveType.GeographyPolygon
+              : ODataJClientEdmPrimitiveType.GeometryPolygon;
+    } else if (Constants.ELEM_MULTIPOLYGON.equals(elementName)) {
+      type = dimension == Geospatial.Dimension.GEOGRAPHY
+              ? ODataJClientEdmPrimitiveType.GeographyMultiPolygon
+              : ODataJClientEdmPrimitiveType.GeometryMultiPolygon;
+    } else if (Constants.ELEM_GEOCOLLECTION.equals(elementName)
+            || Constants.ELEM_GEOMEMBERS.equals(elementName)) {
+
+      type = dimension == Geospatial.Dimension.GEOGRAPHY
+              ? ODataJClientEdmPrimitiveType.GeographyCollection
+              : ODataJClientEdmPrimitiveType.GeometryCollection;
+    }
+
+    return type;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/XMLUtils.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/XMLUtils.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/XMLUtils.java
deleted file mode 100644
index 8baa7e3..0000000
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/utils/XMLUtils.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.client.api.utils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.client.api.Constants;
-import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
-import org.apache.olingo.client.api.domain.geospatial.Geospatial;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * XML utilities.
- */
-public final class XMLUtils {
-
-  /**
-   * DOM factory.
-   */
-  public static final DocumentBuilderFactory DOC_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
-
-  private XMLUtils() {
-    // Empty private constructor for static utility classes       
-  }
-
-  /**
-   * Gets XML node name.
-   *
-   * @param node node.
-   * @return node name.
-   */
-  public static String getSimpleName(final Node node) {
-    return node.getLocalName() == null
-            ? node.getNodeName().substring(node.getNodeName().indexOf(':') + 1)
-            : node.getLocalName();
-  }
-
-  /**
-   * Gets the given node's children of the given type.
-   *
-   * @param node parent.
-   * @param nodetype searched child type.
-   * @return children.
-   */
-  public static List<Node> getChildNodes(final Node node, final short nodetype) {
-    final List<Node> result = new ArrayList<Node>();
-
-    final NodeList children = node.getChildNodes();
-    for (int i = 0; i < children.getLength(); i++) {
-      final Node child = children.item(i);
-      if (child.getNodeType() == nodetype) {
-        result.add(child);
-      }
-    }
-
-    return result;
-  }
-
-  /**
-   * Gets the given node's children with the given name.
-   *
-   * @param node parent.
-   * @param name searched child name.
-   * @return children.
-   */
-  public static List<Element> getChildElements(final Element node, final String name) {
-    final List<Element> result = new ArrayList<Element>();
-
-    if (StringUtils.isNotBlank(name)) {
-      final NodeList children = node.getChildNodes();
-      for (int i = 0; i < children.getLength(); i++) {
-        final Node child = children.item(i);
-        if ((child instanceof Element) && name.equals(child.getNodeName())) {
-          result.add((Element) child);
-        }
-      }
-    }
-
-    return result;
-  }
-
-  /**
-   * Checks if the given node has <tt>element</tt> children.
-   *
-   * @param node parent.
-   * @return 'TRUE' if the given node has at least one <tt>element</tt> child; 'FALSE' otherwise.
-   */
-  public static boolean hasElementsChildNode(final Node node) {
-    boolean found = false;
-
-    for (Node child : getChildNodes(node, Node.ELEMENT_NODE)) {
-      if (Constants.ELEM_ELEMENT.equals(XMLUtils.getSimpleName(child))) {
-        found = true;
-      }
-    }
-
-    return found;
-  }
-
-  /**
-   * Checks if the given node has only text children.
-   *
-   * @param node parent.
-   * @return 'TRUE' if the given node has only text children; 'FALSE' otherwise.
-   */
-  public static boolean hasOnlyTextChildNodes(final Node node) {
-    boolean result = true;
-    final NodeList children = node.getChildNodes();
-    for (int i = 0; result && i < children.getLength(); i++) {
-      final Node child = children.item(i);
-      if (child.getNodeType() != Node.TEXT_NODE) {
-        result = false;
-      }
-    }
-
-    return result;
-  }
-
-  public static ODataJClientEdmPrimitiveType simpleTypeForNode(final Geospatial.Dimension dimension, final Node node) {
-    ODataJClientEdmPrimitiveType type = null;
-
-    if (Constants.ELEM_POINT.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? ODataJClientEdmPrimitiveType.GeographyPoint
-              : ODataJClientEdmPrimitiveType.GeometryPoint;
-    } else if (Constants.ELEM_MULTIPOINT.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? ODataJClientEdmPrimitiveType.GeographyMultiPoint
-              : ODataJClientEdmPrimitiveType.GeometryMultiPoint;
-    } else if (Constants.ELEM_LINESTRING.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? ODataJClientEdmPrimitiveType.GeographyLineString
-              : ODataJClientEdmPrimitiveType.GeometryLineString;
-    } else if (Constants.ELEM_MULTILINESTRING.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? ODataJClientEdmPrimitiveType.GeographyMultiLineString
-              : ODataJClientEdmPrimitiveType.GeometryMultiLineString;
-    } else if (Constants.ELEM_POLYGON.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? ODataJClientEdmPrimitiveType.GeographyPolygon
-              : ODataJClientEdmPrimitiveType.GeometryPolygon;
-    } else if (Constants.ELEM_MULTIPOLYGON.equals(node.getNodeName())) {
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? ODataJClientEdmPrimitiveType.GeographyMultiPolygon
-              : ODataJClientEdmPrimitiveType.GeometryMultiPolygon;
-    } else if (Constants.ELEM_GEOCOLLECTION.equals(node.getNodeName())
-            || Constants.ELEM_GEOMEMBERS.equals(node.getNodeName())) {
-
-      type = dimension == Geospatial.Dimension.GEOGRAPHY
-              ? ODataJClientEdmPrimitiveType.GeographyCollection
-              : ODataJClientEdmPrimitiveType.GeometryCollection;
-    }
-
-    return type;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/pom.xml
----------------------------------------------------------------------
diff --git a/lib/client-core/pom.xml b/lib/client-core/pom.xml
index 2705261..9c52285 100644
--- a/lib/client-core/pom.xml
+++ b/lib/client-core/pom.xml
@@ -75,6 +75,10 @@
       <groupId>org.mockito</groupId>
       <artifactId>mockito-all</artifactId>
     </dependency>
+    <dependency>
+      <groupId>xmlunit</groupId>
+      <artifactId>xmlunit</artifactId>
+    </dependency>
     
     <dependency>
       <groupId>org.apache.olingo</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomDealer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomDealer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomDealer.java
new file mode 100644
index 0000000..64fa3d8
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomDealer.java
@@ -0,0 +1,80 @@
+/*
+ * 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.client.core.data;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+
+abstract class AbstractAtomDealer {
+
+  protected static final String TYPE_TEXT = "text";
+
+  protected final ODataServiceVersion version;
+
+  protected final QName etagQName;
+
+  protected final QName inlineQName;
+
+  protected final QName actionQName;
+
+  protected final QName propertiesQName;
+
+  protected final QName typeQName;
+
+  protected final QName nullQName;
+
+  protected final QName elementQName;
+
+  protected final QName countQName;
+
+  public AbstractAtomDealer(final ODataServiceVersion version) {
+    this.version = version;
+
+    this.etagQName =
+            new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ATTR_ETAG);
+    this.inlineQName =
+            new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ELEM_INLINE);
+    this.actionQName =
+            new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ELEM_ACTION);
+    this.propertiesQName =
+            new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.PROPERTIES);
+    this.typeQName = new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATTR_TYPE);
+    this.nullQName = new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATTR_NULL);
+    this.elementQName =
+            new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES), Constants.ELEM_ELEMENT);
+    this.countQName =
+            new QName(version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA), Constants.ATOM_ELEM_COUNT);
+  }
+
+  protected void namespaces(final XMLStreamWriter writer) throws XMLStreamException {
+    writer.writeNamespace(StringUtils.EMPTY, Constants.NS_ATOM);
+    writer.writeNamespace(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI);
+    writer.writeNamespace(Constants.PREFIX_METADATA, version.getNamespaceMap().get(ODataServiceVersion.NS_METADATA));
+    writer.writeNamespace(
+            Constants.PREFIX_DATASERVICES, version.getNamespaceMap().get(ODataServiceVersion.NS_DATASERVICES));
+    writer.writeNamespace(Constants.PREFIX_GML, Constants.NS_GML);
+    writer.writeNamespace(Constants.PREFIX_GEORSS, Constants.NS_GEORSS);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomObject.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomObject.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomObject.java
new file mode 100644
index 0000000..76004d1
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractAtomObject.java
@@ -0,0 +1,78 @@
+/*
+ * 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.client.core.data;
+
+import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
+import java.net.URI;
+import java.text.ParseException;
+import java.util.Date;
+
+abstract class AbstractAtomObject extends AbstractPayloadObject {
+
+  private static final long serialVersionUID = -4391162864875546927L;
+
+  private static final ISO8601DateFormat ISO_DATEFORMAT = new ISO8601DateFormat();
+
+  private URI baseURI;
+
+  private String id;
+
+  private String title;
+
+  private String summary;
+
+  private Date updated;
+
+  public URI getBaseURI() {
+    return baseURI;
+  }
+
+  public void setBaseURI(final String baseURI) {
+    this.baseURI = URI.create(baseURI);
+  }
+
+  public String getId() {
+    return id;
+  }
+
+  public String getTitle() {
+    return title;
+  }
+
+  public String getSummary() {
+    return summary;
+  }
+
+  public Date getUpdated() {
+    return updated;
+  }
+
+  public void setCommonProperty(final String key, final String value) throws ParseException {
+    if ("id".equals(key)) {
+      this.id = value;
+    } else if ("title".equals(key)) {
+      this.title = value;
+    } else if ("summary".equals(key)) {
+      this.summary = value;
+    } else if ("updated".equals(key)) {
+      this.updated = ISO_DATEFORMAT.parse(value);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractEntry.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractEntry.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractEntry.java
index 4d7e8db..f92c44b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractEntry.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractEntry.java
@@ -23,13 +23,13 @@ import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.data.Link;
+import org.apache.olingo.client.api.data.Property;
 import org.apache.olingo.client.api.domain.ODataOperation;
-import org.w3c.dom.Element;
 
 /**
  * Abstract base for classes implementing an OData entry in Atom and JSON.
  */
-public abstract class AbstractEntry extends AbstractPayloadObject implements Entry {
+public abstract class AbstractEntry extends AbstractAtomObject implements Entry {
 
   private static final long serialVersionUID = 2127764552600969783L;
 
@@ -37,8 +37,6 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
 
   private String type;
 
-  private String id;
-
   private Link readLink;
 
   private Link editLink;
@@ -51,9 +49,7 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
 
   private final List<ODataOperation> operations = new ArrayList<ODataOperation>();
 
-  private Element content;
-
-  private Element mediaEntryProperties;
+  private final List<Property> properties = new ArrayList<Property>();
 
   private String mediaContentSource;
 
@@ -64,7 +60,6 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
     return eTag;
   }
 
-  @Override
   public void setETag(final String eTag) {
     this.eTag = eTag;
   }
@@ -80,16 +75,6 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
   }
 
   @Override
-  public String getId() {
-    return id;
-  }
-
-  @Override
-  public void setId(final String id) {
-    this.id = id;
-  }
-
-  @Override
   public Link getSelfLink() {
     return readLink;
   }
@@ -130,26 +115,21 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
   }
 
   @Override
-  public Element getContent() {
-    return content;
+  public List<Property> getProperties() {
+    return properties;
   }
 
   @Override
-  public void setContent(final Element content) {
-    this.content = content;
-  }
+  public Property getProperty(final String name) {
+    Property result = null;
 
-  /**
-   * {@inheritDoc }
-   */
-  @Override
-  public Element getMediaEntryProperties() {
-    return mediaEntryProperties;
-  }
+    for (Property property : properties) {
+      if (name.equals(property.getName())) {
+        result = property;
+      }
+    }
 
-  @Override
-  public void setMediaEntryProperties(final Element mediaEntryProperties) {
-    this.mediaEntryProperties = mediaEntryProperties;
+    return result;
   }
 
   @Override
@@ -174,6 +154,6 @@ public abstract class AbstractEntry extends AbstractPayloadObject implements Ent
 
   @Override
   public boolean isMediaEntry() {
-    return getMediaEntryProperties() != null || StringUtils.isNotBlank(this.mediaContentSource);
+    return StringUtils.isNotBlank(this.mediaContentSource);
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
new file mode 100644
index 0000000..d353c07
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonDeserializer.java
@@ -0,0 +1,171 @@
+/*
+ * 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.client.core.data;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.data.CollectionValue;
+import org.apache.olingo.client.api.data.ComplexValue;
+import org.apache.olingo.client.api.data.Value;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.ODataJClientEdmType;
+import org.apache.olingo.client.api.domain.ODataPropertyType;
+
+abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<T> {
+
+  private final JSONGeoValueDeserializer geoDeserializer = new JSONGeoValueDeserializer();
+
+  protected ODataJClientEdmPrimitiveType getPrimitiveType(final JsonNode node) {
+    ODataJClientEdmPrimitiveType result = ODataJClientEdmPrimitiveType.String;
+
+    if (node.isIntegralNumber()) {
+      result = ODataJClientEdmPrimitiveType.Int32;
+    } else if (node.isBoolean()) {
+      result = ODataJClientEdmPrimitiveType.Boolean;
+    } else if (node.isFloatingPointNumber()) {
+      result = ODataJClientEdmPrimitiveType.Double;
+    }
+
+    return result;
+  }
+
+  private ODataPropertyType guessPropertyType(final JsonNode node) {
+    ODataPropertyType type = null;
+
+    if (node.isValueNode() || node.isNull()) {
+      type = ODataPropertyType.PRIMITIVE;
+    } else if (node.isArray()) {
+      type = ODataPropertyType.COLLECTION;
+    } else if (node.isObject()) {
+      type = ODataPropertyType.COMPLEX;
+    } else {
+      type = ODataPropertyType.EMPTY;
+    }
+
+    return type;
+  }
+
+  private Value fromPrimitive(final JsonNode node, final ODataJClientEdmType typeInfo) {
+    Value value = null;
+
+    if (node.isNull()) {
+      value = new NullValueImpl();
+    } else {
+      if (typeInfo != null && typeInfo.isGeospatialType()) {
+        final ODataJClientEdmPrimitiveType geoType = ODataJClientEdmPrimitiveType.fromValue(typeInfo.getBaseType());
+
+        value = new GeospatialValueImpl(this.geoDeserializer.deserialize(node, geoType));
+      } else {
+        value = new PrimitiveValueImpl(node.asText());
+      }
+    }
+
+    return value;
+  }
+
+  private ComplexValue fromComplex(final JsonNode node) {
+    final ComplexValue value = new ComplexValueImpl();
+
+    String type = null;
+    for (final Iterator<Map.Entry<String, JsonNode>> itor = node.fields(); itor.hasNext();) {
+      final Map.Entry<String, JsonNode> field = itor.next();
+
+      if (type == null && field.getKey().endsWith(Constants.JSON_TYPE_SUFFIX)) {
+        type = field.getValue().asText();
+      } else {
+        final JSONPropertyImpl property = new JSONPropertyImpl();
+        property.setName(field.getKey());
+        property.setType(type);
+        type = null;
+
+        value(property, field.getValue());
+        value.get().add(property);
+      }
+    }
+
+    return value;
+  }
+
+  private CollectionValue fromCollection(final Iterator<JsonNode> nodeItor, final ODataJClientEdmType typeInfo) {
+    final CollectionValueImpl value = new CollectionValueImpl();
+
+    final ODataJClientEdmType type = typeInfo == null
+            ? null
+            : new ODataJClientEdmType(typeInfo.getBaseType());
+
+    while (nodeItor.hasNext()) {
+      final JsonNode child = nodeItor.next();
+
+      if (child.isValueNode()) {
+        value.get().add(fromPrimitive(child, type));
+      } else if (child.isContainerNode()) {
+        if (child.has(Constants.JSON_TYPE)) {
+          ((ObjectNode) child).remove(Constants.JSON_TYPE);
+        }
+        value.get().add(fromComplex(child));
+      }
+    }
+
+    return value;
+  }
+
+  protected void value(final JSONPropertyImpl property, final JsonNode node) {
+    final ODataJClientEdmType typeInfo = StringUtils.isBlank(property.getType())
+            ? null
+            : new ODataJClientEdmType(property.getType());
+
+    final ODataPropertyType propType = typeInfo == null
+            ? guessPropertyType(node)
+            : typeInfo.isCollection()
+            ? ODataPropertyType.COLLECTION
+            : typeInfo.isPrimitiveType()
+            ? ODataPropertyType.PRIMITIVE
+            : ODataPropertyType.COMPLEX;
+
+    switch (propType) {
+      case COLLECTION:
+        property.setValue(fromCollection(node.elements(), typeInfo));
+        break;
+
+      case COMPLEX:
+        if (node.has(Constants.JSON_TYPE)) {
+          property.setType(node.get(Constants.JSON_TYPE).asText());
+          ((ObjectNode) node).remove(Constants.JSON_TYPE);
+        }
+        property.setValue(fromComplex(node));
+        break;
+
+      case PRIMITIVE:
+        if (property.getType() == null) {
+          property.setType(getPrimitiveType(node).toString());
+        }
+        property.setValue(fromPrimitive(node, typeInfo));
+        break;
+
+      case EMPTY:
+      default:
+        property.setValue(new PrimitiveValueImpl(StringUtils.EMPTY));
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonSerializer.java
new file mode 100644
index 0000000..3398ed9
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractJsonSerializer.java
@@ -0,0 +1,94 @@
+/*
+ * 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.client.core.data;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.olingo.client.api.data.CollectionValue;
+import org.apache.olingo.client.api.data.Property;
+import org.apache.olingo.client.api.data.Value;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.ODataJClientEdmType;
+
+abstract class AbstractJsonSerializer<T> extends ODataJacksonSerializer<T> {
+
+  private static final ODataJClientEdmPrimitiveType[] NUMBER_TYPES = {
+    ODataJClientEdmPrimitiveType.Byte, ODataJClientEdmPrimitiveType.SByte,
+    ODataJClientEdmPrimitiveType.Single, ODataJClientEdmPrimitiveType.Double,
+    ODataJClientEdmPrimitiveType.Int16, ODataJClientEdmPrimitiveType.Int32, ODataJClientEdmPrimitiveType.Int64
+  };
+
+  private final JSONGeoValueSerializer geoSerializer = new JSONGeoValueSerializer();
+
+  private void collection(final JsonGenerator jgen, final String itemType, final CollectionValue value)
+          throws IOException {
+
+    jgen.writeStartArray();
+    for (Value item : value.get()) {
+      value(jgen, itemType, item);
+    }
+    jgen.writeEndArray();
+  }
+
+  private void value(final JsonGenerator jgen, final String type, final Value value) throws IOException {
+    final ODataJClientEdmType typeInfo = type == null
+            ? null
+            : new ODataJClientEdmType(type);
+
+    if (value.isNull()) {
+      jgen.writeNull();
+    } else if (value.isSimple()) {
+      final boolean isNumber = typeInfo == null
+              ? NumberUtils.isNumber(value.asSimple().get())
+              : ArrayUtils.contains(NUMBER_TYPES, typeInfo.getPrimitiveType());
+      final boolean isBoolean = typeInfo == null
+              ? (value.asSimple().get().equalsIgnoreCase(Boolean.TRUE.toString())
+              || value.asSimple().get().equalsIgnoreCase(Boolean.FALSE.toString()))
+              : typeInfo.getPrimitiveType() == ODataJClientEdmPrimitiveType.Boolean;
+
+      if (isNumber) {
+        jgen.writeNumber(value.asSimple().get());
+      } else if (isBoolean) {
+        jgen.writeBoolean(BooleanUtils.toBoolean(value.asSimple().get()));
+      } else {
+        jgen.writeString(value.asSimple().get());
+      }
+    } else if (value.isGeospatial()) {
+      jgen.writeStartObject();
+      geoSerializer.serialize(jgen, value.asGeospatial().get());
+      jgen.writeEndObject();
+    } else if (value.isCollection()) {
+      collection(jgen, typeInfo == null ? null : typeInfo.getBaseType(), value.asCollection());
+    } else if (value.isComplex()) {
+      jgen.writeStartObject();
+      for (Property property : value.asComplex().get()) {
+        property(jgen, property, property.getName());
+      }
+      jgen.writeEndObject();
+    }
+  }
+
+  protected void property(final JsonGenerator jgen, final Property property, final String name) throws IOException {
+    jgen.writeFieldName(name);
+    value(jgen, property.getType(), property.getValue());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractPropertyImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractPropertyImpl.java
new file mode 100644
index 0000000..3e92ac4
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractPropertyImpl.java
@@ -0,0 +1,80 @@
+/*
+ * 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.client.core.data;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.olingo.client.api.data.Property;
+import org.apache.olingo.client.api.data.Value;
+
+public abstract class AbstractPropertyImpl implements Property {
+
+  private String name;
+
+  private String type;
+
+  private Value value;
+
+  @Override
+  public String getName() {
+    return name;
+  }
+
+  @Override
+  public void setName(final String name) {
+    this.name = name;
+  }
+
+  @Override
+  public String getType() {
+    return type;
+  }
+
+  @Override
+  public void setType(final String type) {
+    this.type = type;
+  }
+
+  @Override
+  public Value getValue() {
+    return value;
+  }
+
+  @Override
+  public void setValue(final Value value) {
+    this.value = value;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return EqualsBuilder.reflectionEquals(this, obj);
+  }
+
+  @Override
+  public int hashCode() {
+    return HashCodeBuilder.reflectionHashCode(this);
+  }
+
+  @Override
+  public String toString() {
+    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractValue.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractValue.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractValue.java
new file mode 100644
index 0000000..9f2d19a
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AbstractValue.java
@@ -0,0 +1,98 @@
+/*
+ * 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.client.core.data;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.olingo.client.api.data.CollectionValue;
+import org.apache.olingo.client.api.data.ComplexValue;
+import org.apache.olingo.client.api.data.GeospatialValue;
+import org.apache.olingo.client.api.data.NullValue;
+import org.apache.olingo.client.api.data.PrimitiveValue;
+import org.apache.olingo.client.api.data.Value;
+
+public abstract class AbstractValue implements Value {
+
+  @Override
+  public boolean isNull() {
+    return false;
+  }
+
+  @Override
+  public boolean isSimple() {
+    return false;
+  }
+
+  @Override
+  public boolean isGeospatial() {
+    return false;
+  }
+
+  @Override
+  public boolean isComplex() {
+    return false;
+  }
+
+  @Override
+  public boolean isCollection() {
+    return false;
+  }
+
+  @Override
+  public NullValue asNull() {
+    return isNull() ? (NullValue) this : null;
+  }
+
+  @Override
+  public PrimitiveValue asSimple() {
+    return isSimple() ? (PrimitiveValue) this : null;
+  }
+
+  @Override
+  public GeospatialValue asGeospatial() {
+    return isGeospatial() ? (GeospatialValue) this : null;
+  }
+
+  @Override
+  public ComplexValue asComplex() {
+    return isComplex() ? (ComplexValue) this : null;
+  }
+
+  @Override
+  public CollectionValue asCollection() {
+    return isCollection() ? (CollectionValue) this : null;
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    return EqualsBuilder.reflectionEquals(this, obj);
+  }
+
+  @Override
+  public int hashCode() {
+    return HashCodeBuilder.reflectionHashCode(this);
+  }
+
+  @Override
+  public String toString() {
+    return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
index 0b5e974..d80bcf3 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomDeserializer.java
@@ -18,201 +18,322 @@
  */
 package org.apache.olingo.client.core.data;
 
-import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
+import java.io.InputStream;
 import java.net.URI;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.client.api.ODataClient;
+import java.text.ParseException;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import org.apache.http.entity.ContentType;
 import org.apache.olingo.client.api.Constants;
 import org.apache.olingo.client.api.domain.ODataOperation;
-import org.apache.olingo.client.api.utils.XMLUtils;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 
-public class AtomDeserializer {
+public class AtomDeserializer extends AbstractAtomDealer {
 
   private static final Logger LOG = LoggerFactory.getLogger(AtomDeserializer.class);
 
-  private static final ISO8601DateFormat ISO_DATEFORMAT = new ISO8601DateFormat();
+  private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance();
 
-  private final ODataClient client;
+  private final AtomPropertyDeserializer propDeserializer;
 
-  public AtomDeserializer(final ODataClient client) {
-    this.client = client;
+  public AtomDeserializer(final ODataServiceVersion version) {
+    super(version);
+    this.propDeserializer = new AtomPropertyDeserializer(version);
   }
 
-  private void common(final Element input, final AtomObject object) {
-    if (StringUtils.isNotBlank(input.getAttribute(Constants.ATTR_XMLBASE))) {
-      object.setBaseURI(input.getAttribute(Constants.ATTR_XMLBASE));
-    }
+  private AtomPropertyImpl property(final InputStream input) throws XMLStreamException {
+    final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+    return propDeserializer.deserialize(reader, skipBeforeFirstStartElement(reader));
+  }
 
-    final List<Element> ids = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_ID);
-    if (!ids.isEmpty()) {
-      object.setId(ids.get(0).getTextContent());
+  private StartElement skipBeforeFirstStartElement(final XMLEventReader reader) throws XMLStreamException {
+    StartElement startEvent = null;
+    while (reader.hasNext() && startEvent == null) {
+      final XMLEvent event = reader.nextEvent();
+      if (event.isStartElement()) {
+        startEvent = event.asStartElement();
+      }
+    }
+    if (startEvent == null) {
+      throw new IllegalArgumentException("Cannot find any XML start element");
     }
 
-    final List<Element> titles = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_TITLE);
-    if (!titles.isEmpty()) {
-      object.setTitle(titles.get(0).getTextContent());
+    return startEvent;
+  }
+
+  private void common(final XMLEventReader reader, final StartElement start,
+          final AbstractAtomObject object, final String key) throws XMLStreamException {
+
+    boolean foundEndElement = false;
+    while (reader.hasNext() && !foundEndElement) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+        try {
+          object.setCommonProperty(key, event.asCharacters().getData());
+        } catch (ParseException e) {
+          throw new XMLStreamException("While parsing Atom entry or feed common elements", e);
+        }
+      }
+
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndElement = true;
+      }
     }
+  }
 
-    final List<Element> summaries = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_SUMMARY);
-    if (!summaries.isEmpty()) {
-      object.setSummary(summaries.get(0).getTextContent());
+  private void inline(final XMLEventReader reader, final StartElement start, final LinkImpl link)
+          throws XMLStreamException {
+
+    boolean foundEndElement = false;
+    while (reader.hasNext() && !foundEndElement) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.isStartElement() && inlineQName.equals(event.asStartElement().getName())) {
+        StartElement inline = null;
+        while (reader.hasNext() && inline == null) {
+          final XMLEvent innerEvent = reader.peek();
+          if (innerEvent.isCharacters() && innerEvent.asCharacters().isWhiteSpace()) {
+            reader.nextEvent();
+          } else if (innerEvent.isStartElement()) {
+            inline = innerEvent.asStartElement();
+          }
+        }
+        if (inline != null) {
+          if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(inline.getName())) {
+            link.setInlineEntry(entry(reader, inline));
+          }
+          if (Constants.QNAME_ATOM_ELEM_FEED.equals(inline.getName())) {
+            link.setInlineFeed(feed(reader, inline));
+          }
+        }
+      }
+
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndElement = true;
+      }
     }
+  }
+
+  private void properties(final XMLEventReader reader, final StartElement start, final AtomEntryImpl entry)
+          throws XMLStreamException {
+
+    boolean foundEndProperties = false;
+    while (reader.hasNext() && !foundEndProperties) {
+      final XMLEvent event = reader.nextEvent();
 
-    final List<Element> updateds = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_UPDATED);
-    if (!updateds.isEmpty()) {
-      try {
-        object.setUpdated(ISO_DATEFORMAT.parse(updateds.get(0).getTextContent()));
-      } catch (Exception e) {
-        LOG.error("Could not parse date {}", updateds.get(0).getTextContent(), e);
+      if (event.isStartElement()) {
+        entry.getProperties().add(propDeserializer.deserialize(reader, event.asStartElement()));
+      }
+
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndProperties = true;
       }
     }
   }
 
-  public AtomEntryImpl entry(final Element input) {
-    if (!Constants.ATOM_ELEM_ENTRY.equals(input.getNodeName())) {
+  private AtomEntryImpl entry(final XMLEventReader reader, final StartElement start) throws XMLStreamException {
+    if (!Constants.QNAME_ATOM_ELEM_ENTRY.equals(start.getName())) {
       return null;
     }
 
     final AtomEntryImpl entry = new AtomEntryImpl();
-
-    common(input, entry);
-
-    final String etag = input.getAttribute(Constants.ATOM_ATTR_ETAG);
-    if (StringUtils.isNotBlank(etag)) {
-      entry.setETag(etag);
+    final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
+    if (xmlBase != null) {
+      entry.setBaseURI(xmlBase.getValue());
     }
-
-    final List<Element> categories = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_CATEGORY);
-    if (!categories.isEmpty()) {
-      entry.setType(categories.get(0).getAttribute(Constants.ATOM_ATTR_TERM));
+    final Attribute etag = start.getAttributeByName(etagQName);
+    if (etag != null) {
+      entry.setETag(etag.getValue());
     }
 
-    final List<Element> links = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_LINK);
-    for (Element linkElem : links) {
-      final LinkImpl link = new LinkImpl();
-      link.setRel(linkElem.getAttribute(Constants.ATTR_REL));
-      link.setTitle(linkElem.getAttribute(Constants.ATTR_TITLE));
-      link.setHref(linkElem.getAttribute(Constants.ATTR_HREF));
-
-      if (Constants.SELF_LINK_REL.equals(link.getRel())) {
-        entry.setSelfLink(link);
-      } else if (Constants.EDIT_LINK_REL.equals(link.getRel())) {
-        entry.setEditLink(link);
-      } else if (link.getRel().startsWith(
-              client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL))) {
-
-        link.setType(linkElem.getAttribute(Constants.ATTR_TYPE));
-        entry.getNavigationLinks().add(link);
-
-        final List<Element> inlines = XMLUtils.getChildElements(linkElem, Constants.ATOM_ELEM_INLINE);
-        if (!inlines.isEmpty()) {
-          final List<Element> entries =
-                  XMLUtils.getChildElements(inlines.get(0), Constants.ATOM_ELEM_ENTRY);
-          if (!entries.isEmpty()) {
-            link.setInlineEntry(entry(entries.get(0)));
+    boolean foundEndEntry = false;
+    while (reader.hasNext() && !foundEndEntry) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.isStartElement()) {
+        if (Constants.QNAME_ATOM_ELEM_ID.equals(event.asStartElement().getName())) {
+          common(reader, event.asStartElement(), entry, "id");
+        } else if (Constants.QNAME_ATOM_ELEM_TITLE.equals(event.asStartElement().getName())) {
+          common(reader, event.asStartElement(), entry, "title");
+        } else if (Constants.QNAME_ATOM_ELEM_SUMMARY.equals(event.asStartElement().getName())) {
+          common(reader, event.asStartElement(), entry, "summary");
+        } else if (Constants.QNAME_ATOM_ELEM_UPDATED.equals(event.asStartElement().getName())) {
+          common(reader, event.asStartElement(), entry, "updated");
+        } else if (Constants.QNAME_ATOM_ELEM_CATEGORY.equals(event.asStartElement().getName())) {
+          final Attribute term = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM));
+          if (term != null) {
+            entry.setType(term.getValue());
           }
-
-          final List<Element> feeds =
-                  XMLUtils.getChildElements(inlines.get(0), Constants.ATOM_ELEM_FEED);
-          if (!feeds.isEmpty()) {
-            link.setInlineFeed(feed(feeds.get(0)));
+        } else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
+          final LinkImpl link = new LinkImpl();
+          final Attribute rel = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_REL));
+          if (rel != null) {
+            link.setRel(rel.getValue());
+          }
+          final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
+          if (title != null) {
+            link.setTitle(title.getValue());
+          }
+          final Attribute href = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_HREF));
+          if (href != null) {
+            link.setHref(href.getValue());
+          }
+          final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
+          if (type != null) {
+            link.setType(type.getValue());
           }
-        }
-      } else if (link.getRel().startsWith(
-              client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.ASSOCIATION_LINK_REL))) {
-
-        entry.getAssociationLinks().add(link);
-      } else if (link.getRel().startsWith(
-              client.getServiceVersion().getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL))) {
 
-        entry.getMediaEditLinks().add(link);
-      }
-    }
+          if (Constants.SELF_LINK_REL.equals(link.getRel())) {
+            entry.setSelfLink(link);
+          } else if (Constants.EDIT_LINK_REL.equals(link.getRel())) {
+            entry.setEditLink(link);
+          } else if (link.getRel().startsWith(version.getNamespaceMap().get(ODataServiceVersion.NAVIGATION_LINK_REL))) {
+            entry.getNavigationLinks().add(link);
+            inline(reader, event.asStartElement(), link);
+          } else if (link.getRel().startsWith(
+                  version.getNamespaceMap().get(ODataServiceVersion.ASSOCIATION_LINK_REL))) {
+
+            entry.getAssociationLinks().add(link);
+          } else if (link.getRel().startsWith(
+                  version.getNamespaceMap().get(ODataServiceVersion.MEDIA_EDIT_LINK_REL))) {
+
+            final Attribute metag = event.asStartElement().getAttributeByName(etagQName);
+            if (metag != null) {
+              link.setMediaETag(metag.getValue());
+            }
+            entry.getMediaEditLinks().add(link);
+          }
+        } else if (actionQName.equals(event.asStartElement().getName())) {
+          final ODataOperation operation = new ODataOperation();
+          final Attribute metadata = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_METADATA));
+          if (metadata != null) {
+            operation.setMetadataAnchor(metadata.getValue());
+          }
+          final Attribute title = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TITLE));
+          if (title != null) {
+            operation.setTitle(title.getValue());
+          }
+          final Attribute target = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TARGET));
+          if (target != null) {
+            operation.setTarget(URI.create(target.getValue()));
+          }
 
-    final List<Element> authors = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_AUTHOR);
-    if (!authors.isEmpty()) {
-      final AtomEntryImpl.Author author = new AtomEntryImpl.Author();
-      for (Node child : XMLUtils.getChildNodes(input, Node.ELEMENT_NODE)) {
-        if (Constants.ATOM_ELEM_AUTHOR_NAME.equals(XMLUtils.getSimpleName(child))) {
-          author.setName(child.getTextContent());
-        } else if (Constants.ATOM_ELEM_AUTHOR_URI.equals(XMLUtils.getSimpleName(child))) {
-          author.setUri(child.getTextContent());
-        } else if (Constants.ATOM_ELEM_AUTHOR_EMAIL.equals(XMLUtils.getSimpleName(child))) {
-          author.setEmail(child.getTextContent());
+          entry.getOperations().add(operation);
+        } else if (Constants.QNAME_ATOM_ELEM_CONTENT.equals(event.asStartElement().getName())) {
+          final Attribute type = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
+          if (type == null || ContentType.APPLICATION_XML.getMimeType().equals(type.getValue())) {
+            properties(reader, skipBeforeFirstStartElement(reader), entry);
+          } else {
+            entry.setMediaContentType(type.getValue());
+            final Attribute src = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_SRC));
+            if (src != null) {
+              entry.setMediaContentSource(src.getValue());
+            }
+          }
+        } else if (propertiesQName.equals(event.asStartElement().getName())) {
+          properties(reader, event.asStartElement(), entry);
         }
       }
-      if (!author.isEmpty()) {
-        entry.setAuthor(author);
+
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndEntry = true;
       }
     }
 
-    final List<Element> actions = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_ACTION);
-    for (Element action : actions) {
-      final ODataOperation operation = new ODataOperation();
-      operation.setMetadataAnchor(action.getAttribute(Constants.ATTR_METADATA));
-      operation.setTitle(action.getAttribute(Constants.ATTR_TITLE));
-      operation.setTarget(URI.create(action.getAttribute(Constants.ATTR_TARGET)));
+    return entry;
+  }
 
-      entry.getOperations().add(operation);
-    }
+  private AtomEntryImpl entry(final InputStream input) throws XMLStreamException {
+    final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+    return entry(reader, skipBeforeFirstStartElement(reader));
+  }
 
-    final List<Element> contents = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_CONTENT);
-    if (!contents.isEmpty()) {
-      final Element content = contents.get(0);
+  private void count(final XMLEventReader reader, final StartElement start, final AtomFeedImpl feed)
+          throws XMLStreamException {
 
-      List<Element> props = XMLUtils.getChildElements(content, Constants.ELEM_PROPERTIES);
-      if (props.isEmpty()) {
-        entry.setMediaContentSource(content.getAttribute(Constants.ATOM_ATTR_SRC));
-        entry.setMediaContentType(content.getAttribute(Constants.ATTR_TYPE));
+    boolean foundEndElement = false;
+    while (reader.hasNext() && !foundEndElement) {
+      final XMLEvent event = reader.nextEvent();
 
-        props = XMLUtils.getChildElements(input, Constants.ELEM_PROPERTIES);
-        if (!props.isEmpty()) {
-          entry.setMediaEntryProperties(props.get(0));
-        }
-      } else {
-        entry.setContent(props.get(0));
+      if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+        feed.setCount(Integer.valueOf(event.asCharacters().getData()));
       }
-    }
 
-    return entry;
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndElement = true;
+      }
+    }
   }
 
-  public AtomFeedImpl feed(final Element input) {
-    if (!Constants.ATOM_ELEM_FEED.equals(input.getNodeName())) {
+  private AtomFeedImpl feed(final XMLEventReader reader, final StartElement start) throws XMLStreamException {
+    if (!Constants.QNAME_ATOM_ELEM_FEED.equals(start.getName())) {
       return null;
     }
 
     final AtomFeedImpl feed = new AtomFeedImpl();
-
-    common(input, feed);
-
-    final List<Element> entries = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_ENTRY);
-    for (Element entry : entries) {
-      feed.getEntries().add(entry(entry));
+    final Attribute xmlBase = start.getAttributeByName(Constants.QNAME_ATTR_XML_BASE);
+    if (xmlBase != null) {
+      feed.setBaseURI(xmlBase.getValue());
     }
 
-    final List<Element> links = XMLUtils.getChildElements(input, Constants.ATOM_ELEM_LINK);
-    for (Element link : links) {
-      if (Constants.NEXT_LINK_REL.equals(link.getAttribute(Constants.ATTR_REL))) {
-        feed.setNext(URI.create(link.getAttribute(Constants.ATTR_HREF)));
+    boolean foundEndFeed = false;
+    while (reader.hasNext() && !foundEndFeed) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.isStartElement()) {
+        if (countQName.equals(event.asStartElement().getName())) {
+          count(reader, event.asStartElement(), feed);
+        } else if (Constants.QNAME_ATOM_ELEM_ID.equals(event.asStartElement().getName())) {
+          common(reader, event.asStartElement(), feed, "id");
+        } else if (Constants.QNAME_ATOM_ELEM_TITLE.equals(event.asStartElement().getName())) {
+          common(reader, event.asStartElement(), feed, "title");
+        } else if (Constants.QNAME_ATOM_ELEM_SUMMARY.equals(event.asStartElement().getName())) {
+          common(reader, event.asStartElement(), feed, "summary");
+        } else if (Constants.QNAME_ATOM_ELEM_UPDATED.equals(event.asStartElement().getName())) {
+          common(reader, event.asStartElement(), feed, "updated");
+        } else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
+          final Attribute rel = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_REL));
+          if (rel != null && Constants.NEXT_LINK_REL.equals(rel.getValue())) {
+            final Attribute href = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATTR_HREF));
+            if (href != null) {
+              feed.setNext(URI.create(href.getValue()));
+            }
+          }
+        } else if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(event.asStartElement().getName())) {
+          feed.getEntries().add(entry(reader, event.asStartElement()));
+        }
       }
-    }
 
-    final List<Element> counts = XMLUtils.getChildElements(input, Constants.ATOM_ATTR_COUNT);
-    if (!counts.isEmpty()) {
-      try {
-        feed.setCount(Integer.parseInt(counts.get(0).getTextContent()));
-      } catch (Exception e) {
-        LOG.error("Could not parse $inlinecount {}", counts.get(0).getTextContent(), e);
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndFeed = true;
       }
     }
 
     return feed;
   }
+
+  private AtomFeedImpl feed(final InputStream input) throws XMLStreamException {
+    final XMLEventReader reader = FACTORY.createXMLEventReader(input);
+    return feed(reader, skipBeforeFirstStartElement(reader));
+  }
+
+  @SuppressWarnings("unchecked")
+  public <T> T read(final InputStream input, final Class<T> reference) throws XMLStreamException {
+    if (AtomFeedImpl.class.equals(reference)) {
+      return (T) feed(input);
+    } else if (AtomEntryImpl.class.equals(reference)) {
+      return (T) entry(input);
+    } else if (AtomPropertyImpl.class.equals(reference)) {
+      return (T) property(input);
+    }
+    return null;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomEntryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomEntryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomEntryImpl.java
index 704da5e..aa7c0c1 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomEntryImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomEntryImpl.java
@@ -18,102 +18,8 @@
  */
 package org.apache.olingo.client.core.data;
 
-import java.net.URI;
-import java.util.Date;
-import org.apache.commons.lang3.StringUtils;
-
-public class AtomEntryImpl extends AbstractEntry implements AtomObject {
+public class AtomEntryImpl extends AbstractEntry {
 
   private static final long serialVersionUID = 6973729343868293279L;
 
-  public static class Author {
-
-    private String name;
-
-    private String uri;
-
-    private String email;
-
-    public String getName() {
-      return name;
-    }
-
-    public void setName(final String name) {
-      this.name = name;
-    }
-
-    public String getUri() {
-      return uri;
-    }
-
-    public void setUri(final String uri) {
-      this.uri = uri;
-    }
-
-    public String getEmail() {
-      return email;
-    }
-
-    public void setEmail(final String email) {
-      this.email = email;
-    }
-
-    public boolean isEmpty() {
-      return StringUtils.isBlank(name) && StringUtils.isBlank(uri) && StringUtils.isBlank(email);
-    }
-  }
-  private URI baseURI;
-
-  private String title;
-
-  private String summary;
-
-  private Date updated;
-
-  private Author author;
-
-  @Override
-  public void setBaseURI(final String baseURI) {
-    this.baseURI = URI.create(baseURI);
-  }
-
-  @Override
-  public URI getBaseURI() {
-    return baseURI;
-  }
-
-  public String getTitle() {
-    return title;
-  }
-
-  @Override
-  public void setTitle(final String title) {
-    this.title = title;
-  }
-
-  public String getSummary() {
-    return summary;
-  }
-
-  @Override
-  public void setSummary(final String summary) {
-    this.summary = summary;
-  }
-
-  public Date getUpdated() {
-    return updated == null ? null : new Date(updated.getTime());
-  }
-
-  @Override
-  public void setUpdated(final Date updated) {
-    this.updated = new Date(updated.getTime());
-  }
-
-  public Author getAuthor() {
-    return author;
-  }
-
-  public void setAuthor(final Author author) {
-    this.author = author;
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomFeedImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomFeedImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomFeedImpl.java
index 08a85db..94f2540 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomFeedImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomFeedImpl.java
@@ -20,7 +20,6 @@ package org.apache.olingo.client.core.data;
 
 import java.net.URI;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import org.apache.olingo.client.api.data.Entry;
 import org.apache.olingo.client.api.data.Feed;
@@ -30,20 +29,10 @@ import org.apache.olingo.client.api.data.Feed;
  *
  * @see AtomEntry
  */
-public class AtomFeedImpl extends AbstractPayloadObject implements AtomObject, Feed {
+public class AtomFeedImpl extends AbstractAtomObject implements Feed {
 
   private static final long serialVersionUID = 5466590540021319153L;
 
-  private URI baseURI;
-
-  private String id;
-
-  private String title;
-
-  private String summary;
-
-  private Date updated;
-
   private Integer count;
 
   private final List<Entry> entries = new ArrayList<Entry>();
@@ -51,51 +40,6 @@ public class AtomFeedImpl extends AbstractPayloadObject implements AtomObject, F
   private URI next;
 
   @Override
-  public URI getBaseURI() {
-    return baseURI;
-  }
-
-  @Override
-  public void setBaseURI(final String baseURI) {
-    this.baseURI = URI.create(baseURI);
-  }
-
-  public String getId() {
-    return id;
-  }
-
-  @Override
-  public void setId(final String id) {
-    this.id = id;
-  }
-
-  public String getTitle() {
-    return title;
-  }
-
-  @Override
-  public void setTitle(final String title) {
-    this.title = title;
-  }
-
-  public String getSummary() {
-    return summary;
-  }
-
-  @Override
-  public void setSummary(final String summary) {
-    this.summary = summary;
-  }
-
-  public Date getUpdated() {
-    return new Date(updated.getTime());
-  }
-
-  @Override
-  public void setUpdated(final Date updated) {
-    this.updated = new Date(updated.getTime());
-  }
-
   public void setCount(final Integer count) {
     this.count = count;
   }

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueDeserializer.java
new file mode 100644
index 0000000..e733d2a
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueDeserializer.java
@@ -0,0 +1,252 @@
+/*
+ * 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.client.core.data;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.domain.ODataJClientEdmPrimitiveType;
+import org.apache.olingo.client.api.domain.geospatial.Geospatial;
+import org.apache.olingo.client.api.domain.geospatial.GeospatialCollection;
+import org.apache.olingo.client.api.domain.geospatial.LineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiLineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiPoint;
+import org.apache.olingo.client.api.domain.geospatial.MultiPolygon;
+import org.apache.olingo.client.api.domain.geospatial.Point;
+import org.apache.olingo.client.api.domain.geospatial.Polygon;
+
+class AtomGeoValueDeserializer {
+
+  private List<Point> points(final XMLEventReader reader, final StartElement start,
+          final ODataJClientEdmPrimitiveType type, final String crs) throws XMLStreamException {
+
+    final List<Point> result = new ArrayList<Point>();
+
+    boolean foundEndProperty = false;
+    while (reader.hasNext() && !foundEndProperty) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.isCharacters() && !event.asCharacters().isWhiteSpace()) {
+        final String[] pointInfo = event.asCharacters().getData().split(" ");
+
+        final Point point = new Point(GeoUtils.getDimension(type), crs);
+        point.setX(Double.valueOf(pointInfo[0]));
+        point.setY(Double.valueOf(pointInfo[1]));
+        result.add(point);
+      }
+
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndProperty = true;
+      }
+    }
+
+    return result;
+  }
+
+  private MultiPoint multipoint(final XMLEventReader reader, final StartElement start,
+          final ODataJClientEdmPrimitiveType type, final String crs) throws XMLStreamException {
+
+    List<Point> points = Collections.<Point>emptyList();
+
+    boolean foundEndProperty = false;
+    while (reader.hasNext() && !foundEndProperty) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.isStartElement() && event.asStartElement().getName().equals(Constants.QNAME_POINTMEMBERS)) {
+        points = points(reader, event.asStartElement(), type, null);
+      }
+
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndProperty = true;
+      }
+    }
+
+    return new MultiPoint(GeoUtils.getDimension(type), crs, points);
+  }
+
+  private LineString lineString(final XMLEventReader reader, final StartElement start,
+          final ODataJClientEdmPrimitiveType type, final String crs) throws XMLStreamException {
+
+    return new LineString(GeoUtils.getDimension(type), crs, points(reader, start, type, null));
+  }
+
+  private Polygon polygon(final XMLEventReader reader, final StartElement start,
+          final ODataJClientEdmPrimitiveType type, final String crs) throws XMLStreamException {
+
+    List<Point> extPoints = null;
+    List<Point> intPoints = null;
+
+    boolean foundEndProperty = false;
+    while (reader.hasNext() && !foundEndProperty) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.isStartElement()) {
+        if (event.asStartElement().getName().equals(Constants.QNAME_POLYGON_EXTERIOR)) {
+          extPoints = points(reader, event.asStartElement(), type, null);
+        }
+        if (event.asStartElement().getName().equals(Constants.QNAME_POLYGON_INTERIOR)) {
+          intPoints = points(reader, event.asStartElement(), type, null);
+        }
+      }
+
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndProperty = true;
+      }
+    }
+
+    return new Polygon(GeoUtils.getDimension(type), crs, intPoints, extPoints);
+  }
+
+  private MultiLineString multiLineString(final XMLEventReader reader, final StartElement start,
+          final ODataJClientEdmPrimitiveType type, final String crs) throws XMLStreamException {
+
+    final List<LineString> lineStrings = new ArrayList<LineString>();
+
+    boolean foundEndProperty = false;
+    while (reader.hasNext() && !foundEndProperty) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.isStartElement() && event.asStartElement().getName().equals(Constants.QNAME_LINESTRING)) {
+        lineStrings.add(lineString(reader, event.asStartElement(), type, null));
+      }
+
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndProperty = true;
+      }
+    }
+
+    return new MultiLineString(GeoUtils.getDimension(type), crs, lineStrings);
+  }
+
+  private MultiPolygon multiPolygon(final XMLEventReader reader, final StartElement start,
+          final ODataJClientEdmPrimitiveType type, final String crs) throws XMLStreamException {
+
+    final List<Polygon> polygons = new ArrayList<Polygon>();
+
+    boolean foundEndProperty = false;
+    while (reader.hasNext() && !foundEndProperty) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.isStartElement() && event.asStartElement().getName().equals(Constants.QNAME_POLYGON)) {
+        polygons.add(polygon(reader, event.asStartElement(), type, null));
+      }
+
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndProperty = true;
+      }
+    }
+
+    return new MultiPolygon(GeoUtils.getDimension(type), crs, polygons);
+  }
+
+  private GeospatialCollection collection(final XMLEventReader reader, final StartElement start,
+          final ODataJClientEdmPrimitiveType type, final String crs) throws XMLStreamException {
+
+    final List<Geospatial> geospatials = new ArrayList<Geospatial>();
+
+    boolean foundEndCollection = false;
+    while (reader.hasNext() && !foundEndCollection) {
+      final XMLEvent event = reader.nextEvent();
+
+      if (event.isStartElement() && event.asStartElement().getName().equals(Constants.QNAME_GEOMEMBERS)) {
+        boolean foundEndMembers = false;
+        while (reader.hasNext() && !foundEndMembers) {
+          final XMLEvent subevent = reader.nextEvent();
+
+          if (subevent.isStartElement()) {
+            geospatials.add(deserialize(reader, subevent.asStartElement(),
+                    GeoUtils.getType(GeoUtils.getDimension(type), subevent.asStartElement().getName().getLocalPart())));
+          }
+
+          if (subevent.isEndElement() && Constants.QNAME_GEOMEMBERS.equals(subevent.asEndElement().getName())) {
+            foundEndMembers = true;
+          }
+        }
+      }
+
+      if (event.isEndElement() && start.getName().equals(event.asEndElement().getName())) {
+        foundEndCollection = true;
+      }
+    }
+
+    return new GeospatialCollection(GeoUtils.getDimension(type), crs, geospatials);
+  }
+
+  public Geospatial deserialize(final XMLEventReader reader, final StartElement start,
+          final ODataJClientEdmPrimitiveType type) throws XMLStreamException {
+
+    String crs = null;
+    final Attribute srsName = start.getAttributeByName(Constants.QNAME_ATTR_SRSNAME);
+    if (srsName != null) {
+      crs = StringUtils.substringAfterLast(srsName.getValue(), "/");
+    }
+
+    Geospatial value;
+
+    switch (type) {
+      case GeographyPoint:
+      case GeometryPoint:
+        value = points(reader, start, type, crs).get(0);
+        break;
+
+      case GeographyMultiPoint:
+      case GeometryMultiPoint:
+        value = multipoint(reader, start, type, crs);
+        break;
+
+      case GeographyLineString:
+      case GeometryLineString:
+        value = lineString(reader, start, type, crs);
+        break;
+
+      case GeographyMultiLineString:
+      case GeometryMultiLineString:
+        value = multiLineString(reader, start, type, crs);
+        break;
+
+      case GeographyPolygon:
+      case GeometryPolygon:
+        value = polygon(reader, start, type, crs);
+        break;
+
+      case GeographyMultiPolygon:
+      case GeometryMultiPolygon:
+        value = multiPolygon(reader, start, type, crs);
+        break;
+
+      case GeographyCollection:
+      case GeometryCollection:
+        value = collection(reader, start, type, crs);
+        break;
+
+      default:
+        value = null;
+    }
+
+    return value;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueSerializer.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueSerializer.java
new file mode 100644
index 0000000..409ff99
--- /dev/null
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomGeoValueSerializer.java
@@ -0,0 +1,222 @@
+/*
+ * 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.client.core.data;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Collections;
+import java.util.Iterator;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.apache.olingo.client.api.Constants;
+import org.apache.olingo.client.api.domain.geospatial.Geospatial;
+import org.apache.olingo.client.api.domain.geospatial.GeospatialCollection;
+import org.apache.olingo.client.api.domain.geospatial.LineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiLineString;
+import org.apache.olingo.client.api.domain.geospatial.MultiPoint;
+import org.apache.olingo.client.api.domain.geospatial.MultiPolygon;
+import org.apache.olingo.client.api.domain.geospatial.Point;
+import org.apache.olingo.client.api.domain.geospatial.Polygon;
+
+class AtomGeoValueSerializer {
+
+  public static final ThreadLocal<DecimalFormat> DOUBLE_FORMAT = new ThreadLocal<DecimalFormat>() {
+    @Override
+    protected DecimalFormat initialValue() {
+      DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols();
+      otherSymbols.setDecimalSeparator('.');
+      return new DecimalFormat("#.#########################", otherSymbols);
+    }
+  };
+
+  private void points(final XMLStreamWriter writer, final Iterator<Point> itor, final boolean wrap)
+          throws XMLStreamException {
+
+    while (itor.hasNext()) {
+      final Point point = itor.next();
+
+      if (wrap) {
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POINT, Constants.NS_GML);
+      }
+
+      writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POS, Constants.NS_GML);
+      writer.writeCharacters(DOUBLE_FORMAT.get().format(point.getX()) + " " + DOUBLE_FORMAT.get().format(point.getY()));
+      writer.writeEndElement();
+
+      if (wrap) {
+        writer.writeEndElement();
+      }
+    }
+  }
+
+  private void lineStrings(final XMLStreamWriter writer, final Iterator<LineString> itor, final boolean wrap)
+          throws XMLStreamException {
+
+    while (itor.hasNext()) {
+      final LineString lineString = itor.next();
+
+      if (wrap) {
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_LINESTRING, Constants.NS_GML);
+      }
+
+      points(writer, lineString.iterator(), false);
+
+      if (wrap) {
+        writer.writeEndElement();
+      }
+    }
+  }
+
+  private void polygons(final XMLStreamWriter writer, final Iterator<Polygon> itor, final boolean wrap)
+          throws XMLStreamException {
+
+    while (itor.hasNext()) {
+      final Polygon polygon = itor.next();
+
+      if (wrap) {
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON, Constants.NS_GML);
+      }
+
+      if (!polygon.getExterior().isEmpty()) {
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_EXTERIOR, Constants.NS_GML);
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_LINEARRING, Constants.NS_GML);
+
+        points(writer, polygon.getExterior().iterator(), false);
+
+        writer.writeEndElement();
+        writer.writeEndElement();
+      }
+      if (!polygon.getInterior().isEmpty()) {
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_INTERIOR, Constants.NS_GML);
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON_LINEARRING, Constants.NS_GML);
+
+        points(writer, polygon.getInterior().iterator(), false);
+
+        writer.writeEndElement();
+        writer.writeEndElement();
+      }
+
+      if (wrap) {
+        writer.writeEndElement();
+      }
+    }
+  }
+
+  private void writeSrsName(final XMLStreamWriter writer, final Geospatial value) throws XMLStreamException {
+    if (value.getCrs() != null) {
+      writer.writeAttribute(Constants.PREFIX_GML, Constants.NS_GML, Constants.ATTR_SRSNAME,
+              Constants.SRS_URLPREFIX + value.getCrs());
+    }
+  }
+
+  public void serialize(final XMLStreamWriter writer, final Geospatial value) throws XMLStreamException {
+    switch (value.getEdmSimpleType()) {
+      case GeographyPoint:
+      case GeometryPoint:
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POINT, Constants.NS_GML);
+        writeSrsName(writer, value);
+
+        points(writer, Collections.singleton((Point) value).iterator(), false);
+
+        writer.writeEndElement();
+        break;
+
+      case GeometryMultiPoint:
+      case GeographyMultiPoint:
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_MULTIPOINT, Constants.NS_GML);
+        writeSrsName(writer, value);
+
+        if (!((MultiPoint) value).isEmpty()) {
+          writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POINTMEMBERS, Constants.NS_GML);
+          points(writer, ((MultiPoint) value).iterator(), true);
+          writer.writeEndElement();
+        }
+
+        writer.writeEndElement();
+        break;
+
+      case GeometryLineString:
+      case GeographyLineString:
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_LINESTRING, Constants.NS_GML);
+        writeSrsName(writer, value);
+
+        lineStrings(writer, Collections.singleton((LineString) value).iterator(), false);
+
+        writer.writeEndElement();
+        break;
+
+      case GeometryMultiLineString:
+      case GeographyMultiLineString:
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_MULTILINESTRING, Constants.NS_GML);
+        writeSrsName(writer, value);
+
+        if (!((MultiLineString) value).isEmpty()) {
+          writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_LINESTRINGMEMBERS, Constants.NS_GML);
+          lineStrings(writer, ((MultiLineString) value).iterator(), true);
+          writer.writeEndElement();
+        }
+
+        writer.writeEndElement();
+        break;
+
+      case GeographyPolygon:
+      case GeometryPolygon:
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_POLYGON, Constants.NS_GML);
+        writeSrsName(writer, value);
+
+        polygons(writer, Collections.singleton(((Polygon) value)).iterator(), false);
+
+        writer.writeEndElement();
+        break;
+
+      case GeographyMultiPolygon:
+      case GeometryMultiPolygon:
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_MULTIPOLYGON, Constants.NS_GML);
+        writeSrsName(writer, value);
+
+        if (!((MultiPolygon) value).isEmpty()) {
+          writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_SURFACEMEMBERS, Constants.NS_GML);
+          polygons(writer, ((MultiPolygon) value).iterator(), true);
+          writer.writeEndElement();
+        }
+
+        writer.writeEndElement();
+        break;
+
+      case GeographyCollection:
+      case GeometryCollection:
+        writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_GEOCOLLECTION, Constants.NS_GML);
+        writeSrsName(writer, value);
+
+        if (!((GeospatialCollection) value).isEmpty()) {
+          writer.writeStartElement(Constants.PREFIX_GML, Constants.ELEM_GEOMEMBERS, Constants.NS_GML);
+          for (final Iterator<Geospatial> itor = ((GeospatialCollection) value).iterator(); itor.hasNext();) {
+            serialize(writer, itor.next());
+          }
+          writer.writeEndElement();
+        }
+
+        writer.writeEndElement();
+        break;
+
+      default:
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/381b4170/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomObject.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomObject.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomObject.java
deleted file mode 100644
index b0ecab9..0000000
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/AtomObject.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.client.core.data;
-
-import java.util.Date;
-
-/**
- * Common methods for <tt>AtomEntryImpl</tt> and <tt>AtomFeedImpl</tt>.
- *
- * @see AtomEntryImpl
- * @see AtomFeedImpl
- */
-public interface AtomObject {
-
-  void setBaseURI(String baseURI);
-
-  void setId(String id);
-
-  void setTitle(String title);
-
-  void setSummary(String summary);
-
-  void setUpdated(Date updated);
-
-}