You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2013/07/26 13:22:19 UTC

[14/51] [partial] initial commit

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlCollectionEntityProducer.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlCollectionEntityProducer.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlCollectionEntityProducer.java
new file mode 100644
index 0000000..93beaa1
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlCollectionEntityProducer.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.ep.producer;
+
+import java.util.List;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
+import org.apache.olingo.odata2.core.ep.util.FormatXml;
+
+/**
+ * Provider for writing a collection of simple-type or complex-type instances
+ * @author SAP AG
+ */
+public class XmlCollectionEntityProducer {
+
+  public static void append(final XMLStreamWriter writer, final EntityPropertyInfo propertyInfo, final List<?> data) throws EntityProviderException {
+    try {
+      writer.writeStartElement(propertyInfo.getName());
+      writer.writeDefaultNamespace(Edm.NAMESPACE_D_2007_08);
+      if (propertyInfo.isComplex()) {
+        writer.writeNamespace(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08);
+      }
+      XmlPropertyEntityProducer provider = new XmlPropertyEntityProducer();
+      for (final Object propertyData : data) {
+        provider.append(writer, FormatXml.D_ELEMENT, propertyInfo, propertyData);
+      }
+      writer.writeEndElement();
+      writer.flush();
+    } catch (XMLStreamException e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorDocumentProducer.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorDocumentProducer.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorDocumentProducer.java
new file mode 100644
index 0000000..a94f395
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlErrorDocumentProducer.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.ep.producer;
+
+import java.util.Locale;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.core.ep.util.FormatXml;
+
+public class XmlErrorDocumentProducer {
+
+  public void writeErrorDocument(final XMLStreamWriter writer, final String errorCode, final String message, final Locale locale, final String innerError) throws XMLStreamException {
+    writer.writeStartDocument();
+    writer.writeStartElement(FormatXml.M_ERROR);
+    writer.writeDefaultNamespace(Edm.NAMESPACE_M_2007_08);
+    writer.writeStartElement(FormatXml.M_CODE);
+    if (errorCode != null) {
+      writer.writeCharacters(errorCode);
+    }
+    writer.writeEndElement();
+    writer.writeStartElement(FormatXml.M_MESSAGE);
+    if (locale != null) {
+      writer.writeAttribute(Edm.PREFIX_XML, Edm.NAMESPACE_XML_1998, FormatXml.XML_LANG, getLocale(locale));
+    } else {
+      writer.writeAttribute(Edm.PREFIX_XML, Edm.NAMESPACE_XML_1998, FormatXml.XML_LANG, "");
+    }
+    if (message != null) {
+      writer.writeCharacters(message);
+    }
+    writer.writeEndElement();
+
+    if (innerError != null) {
+      writer.writeStartElement(FormatXml.M_INNER_ERROR);
+      writer.writeCharacters(innerError);
+      writer.writeEndElement();
+    }
+
+    writer.writeEndDocument();
+  }
+
+  /**
+   * Gets language and country as defined in RFC 4646 based on {@link Locale}.
+   */
+  private String getLocale(final Locale locale) {
+    if (locale.getCountry().isEmpty()) {
+      return locale.getLanguage();
+    } else {
+      return locale.getLanguage() + "-" + locale.getCountry();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinkEntityProducer.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinkEntityProducer.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinkEntityProducer.java
new file mode 100644
index 0000000..b3d4b4d
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinkEntityProducer.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.ep.producer;
+
+import java.util.Map;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
+import org.apache.olingo.odata2.core.ep.util.FormatXml;
+
+/**
+ * Provider for writing a single link.
+ * @author SAP AG
+ */
+public class XmlLinkEntityProducer {
+
+  private final EntityProviderWriteProperties properties;
+
+  public XmlLinkEntityProducer(final EntityProviderWriteProperties properties) throws EntityProviderException {
+    this.properties = properties == null ? EntityProviderWriteProperties.serviceRoot(null).build() : properties;
+  }
+
+  public void append(final XMLStreamWriter writer, final EntityInfoAggregator entityInfo, final Map<String, Object> data, final boolean isRootElement) throws EntityProviderException {
+    try {
+      writer.writeStartElement(FormatXml.D_URI);
+      if (isRootElement) {
+        writer.writeDefaultNamespace(Edm.NAMESPACE_D_2007_08);
+      }
+      if (properties.getServiceRoot() != null) {
+        writer.writeCharacters(properties.getServiceRoot().toASCIIString());
+      }
+      writer.writeCharacters(AtomEntryEntityProducer.createSelfLink(entityInfo, data, null));
+      writer.writeEndElement();
+      writer.flush();
+    } catch (final XMLStreamException e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinksEntityProducer.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinksEntityProducer.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinksEntityProducer.java
new file mode 100644
index 0000000..f361718
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlLinksEntityProducer.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.ep.producer;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
+import org.apache.olingo.odata2.core.ep.util.FormatXml;
+
+/**
+ * Provider for writing a collection of links
+ * @author SAP AG
+ */
+public class XmlLinksEntityProducer {
+
+  private final EntityProviderWriteProperties properties;
+
+  public XmlLinksEntityProducer(final EntityProviderWriteProperties properties) throws EntityProviderException {
+    this.properties = properties == null ? EntityProviderWriteProperties.serviceRoot(null).build() : properties;
+  }
+
+  public void append(final XMLStreamWriter writer, final EntityInfoAggregator entityInfo, final List<Map<String, Object>> data) throws EntityProviderException {
+    try {
+      writer.writeStartElement(FormatXml.D_LINKS);
+      writer.writeDefaultNamespace(Edm.NAMESPACE_D_2007_08);
+      if (properties.getInlineCount() != null) {
+        writer.writeStartElement(Edm.PREFIX_M, FormatXml.M_COUNT, Edm.NAMESPACE_M_2007_08);
+        writer.writeNamespace(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08);
+        writer.writeCharacters(properties.getInlineCount().toString());
+        writer.writeEndElement();
+      }
+      XmlLinkEntityProducer provider = new XmlLinkEntityProducer(properties);
+      for (final Map<String, Object> entityData : data) {
+        provider.append(writer, entityInfo, entityData, false);
+      }
+      writer.writeEndElement();
+      writer.flush();
+    } catch (final XMLStreamException e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducer.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducer.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducer.java
new file mode 100644
index 0000000..265c092
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlMetadataProducer.java
@@ -0,0 +1,591 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.ep.producer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.xml.stream.FactoryConfigurationError;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationAttribute;
+import org.apache.olingo.odata2.api.edm.provider.AnnotationElement;
+import org.apache.olingo.odata2.api.edm.provider.Association;
+import org.apache.olingo.odata2.api.edm.provider.AssociationEnd;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSet;
+import org.apache.olingo.odata2.api.edm.provider.AssociationSetEnd;
+import org.apache.olingo.odata2.api.edm.provider.ComplexProperty;
+import org.apache.olingo.odata2.api.edm.provider.ComplexType;
+import org.apache.olingo.odata2.api.edm.provider.CustomizableFeedMappings;
+import org.apache.olingo.odata2.api.edm.provider.DataServices;
+import org.apache.olingo.odata2.api.edm.provider.Documentation;
+import org.apache.olingo.odata2.api.edm.provider.EntityContainer;
+import org.apache.olingo.odata2.api.edm.provider.EntitySet;
+import org.apache.olingo.odata2.api.edm.provider.EntityType;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImport;
+import org.apache.olingo.odata2.api.edm.provider.FunctionImportParameter;
+import org.apache.olingo.odata2.api.edm.provider.Key;
+import org.apache.olingo.odata2.api.edm.provider.NavigationProperty;
+import org.apache.olingo.odata2.api.edm.provider.OnDelete;
+import org.apache.olingo.odata2.api.edm.provider.Property;
+import org.apache.olingo.odata2.api.edm.provider.PropertyRef;
+import org.apache.olingo.odata2.api.edm.provider.ReferentialConstraint;
+import org.apache.olingo.odata2.api.edm.provider.ReferentialConstraintRole;
+import org.apache.olingo.odata2.api.edm.provider.Schema;
+import org.apache.olingo.odata2.api.edm.provider.SimpleProperty;
+import org.apache.olingo.odata2.api.edm.provider.Using;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.core.exception.ODataRuntimeException;
+
+public class XmlMetadataProducer {
+
+  public static void writeMetadata(final DataServices metadata, final XMLStreamWriter xmlStreamWriter, Map<String, String> predefinedNamespaces) throws EntityProviderException {
+
+    try {
+      xmlStreamWriter.writeStartDocument();
+      xmlStreamWriter.setPrefix(Edm.PREFIX_EDMX, Edm.NAMESPACE_EDMX_2007_06);
+      xmlStreamWriter.setPrefix(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08);
+      xmlStreamWriter.setDefaultNamespace(Edm.NAMESPACE_EDM_2008_09);
+
+      xmlStreamWriter.writeStartElement(Edm.NAMESPACE_EDMX_2007_06, "Edmx");
+      xmlStreamWriter.writeAttribute("Version", "1.0");
+      xmlStreamWriter.writeNamespace(Edm.PREFIX_EDMX, Edm.NAMESPACE_EDMX_2007_06);
+
+      xmlStreamWriter.writeStartElement(Edm.NAMESPACE_EDMX_2007_06, "DataServices");
+      xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "DataServiceVersion", metadata.getDataServiceVersion());
+      xmlStreamWriter.writeNamespace(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08);
+
+      if (predefinedNamespaces != null) {
+        for (Map.Entry<String, String> entry : predefinedNamespaces.entrySet()) {
+          xmlStreamWriter.writeNamespace(entry.getKey(), entry.getValue());
+        }
+      } else {
+        predefinedNamespaces = new HashMap<String, String>();
+      }
+
+      Collection<Schema> schemas = metadata.getSchemas();
+      if (schemas != null) {
+        for (Schema schema : schemas) {
+          xmlStreamWriter.writeStartElement("Schema");
+          if (schema.getAlias() != null) {
+            xmlStreamWriter.writeAttribute("Alias", schema.getAlias());
+          }
+          xmlStreamWriter.writeAttribute("Namespace", schema.getNamespace());
+          xmlStreamWriter.writeDefaultNamespace(Edm.NAMESPACE_EDM_2008_09);
+
+          writeAnnotationAttributes(schema.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+          Collection<Using> usings = schema.getUsings();
+          if (usings != null) {
+            for (Using using : usings) {
+              xmlStreamWriter.writeStartElement("Using");
+              xmlStreamWriter.writeAttribute("Namespace", using.getNamespace());
+              xmlStreamWriter.writeAttribute("Alias", using.getAlias());
+              writeAnnotationAttributes(using.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+              writeDocumentation(using.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+              writeAnnotationElements(using.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+              xmlStreamWriter.writeEndElement();
+            }
+          }
+
+          Collection<EntityType> entityTypes = schema.getEntityTypes();
+          if (entityTypes != null) {
+            for (EntityType entityType : entityTypes) {
+              xmlStreamWriter.writeStartElement("EntityType");
+              xmlStreamWriter.writeAttribute("Name", entityType.getName());
+              if (entityType.getBaseType() != null) {
+                xmlStreamWriter.writeAttribute("BaseType", entityType.getBaseType().toString());
+              }
+              if (entityType.isAbstract()) {
+                xmlStreamWriter.writeAttribute("Abstract", "true");
+              }
+              if (entityType.isHasStream()) {
+                xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "HasStream", "true");
+              }
+
+              writeCustomizableFeedMappings(entityType.getCustomizableFeedMappings(), xmlStreamWriter);
+
+              writeAnnotationAttributes(entityType.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+              writeDocumentation(entityType.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+              Key key = entityType.getKey();
+              if (key != null) {
+                xmlStreamWriter.writeStartElement("Key");
+
+                writeAnnotationAttributes(key.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+                Collection<PropertyRef> propertyRefs = entityType.getKey().getKeys();
+                for (PropertyRef propertyRef : propertyRefs) {
+                  xmlStreamWriter.writeStartElement("PropertyRef");
+
+                  writeAnnotationAttributes(propertyRef.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+                  xmlStreamWriter.writeAttribute("Name", propertyRef.getName());
+
+                  writeAnnotationElements(propertyRef.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+                  xmlStreamWriter.writeEndElement();
+                }
+
+                writeAnnotationElements(key.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+                xmlStreamWriter.writeEndElement();
+              }
+
+              Collection<Property> properties = entityType.getProperties();
+              if (properties != null) {
+                writeProperties(properties, predefinedNamespaces, xmlStreamWriter);
+              }
+
+              Collection<NavigationProperty> navigationProperties = entityType.getNavigationProperties();
+              if (navigationProperties != null) {
+                for (NavigationProperty navigationProperty : navigationProperties) {
+                  xmlStreamWriter.writeStartElement("NavigationProperty");
+                  xmlStreamWriter.writeAttribute("Name", navigationProperty.getName());
+                  xmlStreamWriter.writeAttribute("Relationship", navigationProperty.getRelationship().toString());
+                  xmlStreamWriter.writeAttribute("FromRole", navigationProperty.getFromRole());
+                  xmlStreamWriter.writeAttribute("ToRole", navigationProperty.getToRole());
+
+                  writeAnnotationAttributes(navigationProperty.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+                  writeDocumentation(navigationProperty.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+                  writeAnnotationElements(navigationProperty.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+                  xmlStreamWriter.writeEndElement();
+                }
+              }
+
+              writeAnnotationElements(entityType.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+              xmlStreamWriter.writeEndElement();
+            }
+          }
+
+          Collection<ComplexType> complexTypes = schema.getComplexTypes();
+          if (complexTypes != null) {
+            for (ComplexType complexType : complexTypes) {
+              xmlStreamWriter.writeStartElement("ComplexType");
+              xmlStreamWriter.writeAttribute("Name", complexType.getName());
+              if (complexType.getBaseType() != null) {
+                xmlStreamWriter.writeAttribute("BaseType", complexType.getBaseType().toString());
+              }
+              if (complexType.isAbstract()) {
+                xmlStreamWriter.writeAttribute("Abstract", "true");
+              }
+
+              writeAnnotationAttributes(complexType.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+              writeDocumentation(complexType.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+              Collection<Property> properties = complexType.getProperties();
+              if (properties != null) {
+                writeProperties(properties, predefinedNamespaces, xmlStreamWriter);
+              }
+
+              writeAnnotationElements(complexType.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+              xmlStreamWriter.writeEndElement();
+            }
+          }
+
+          Collection<Association> associations = schema.getAssociations();
+          if (associations != null) {
+            for (Association association : associations) {
+              xmlStreamWriter.writeStartElement("Association");
+              xmlStreamWriter.writeAttribute("Name", association.getName());
+
+              writeAnnotationAttributes(association.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+              writeDocumentation(association.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+              writeAssociationEnd(association.getEnd1(), predefinedNamespaces, xmlStreamWriter);
+              writeAssociationEnd(association.getEnd2(), predefinedNamespaces, xmlStreamWriter);
+
+              ReferentialConstraint referentialConstraint = association.getReferentialConstraint();
+              if (referentialConstraint != null) {
+                xmlStreamWriter.writeStartElement("ReferentialConstraint");
+                writeAnnotationAttributes(referentialConstraint.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+                writeDocumentation(referentialConstraint.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+                ReferentialConstraintRole principal = referentialConstraint.getPrincipal();
+                xmlStreamWriter.writeStartElement("Principal");
+                xmlStreamWriter.writeAttribute("Role", principal.getRole());
+                writeAnnotationAttributes(principal.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+                for (PropertyRef propertyRef : principal.getPropertyRefs()) {
+                  xmlStreamWriter.writeStartElement("PropertyRef");
+                  xmlStreamWriter.writeAttribute("Name", propertyRef.getName());
+                  xmlStreamWriter.writeEndElement();
+                }
+                writeAnnotationElements(principal.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+                xmlStreamWriter.writeEndElement();
+
+                ReferentialConstraintRole dependent = referentialConstraint.getDependent();
+                xmlStreamWriter.writeStartElement("Dependent");
+                xmlStreamWriter.writeAttribute("Role", dependent.getRole());
+                writeAnnotationAttributes(dependent.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+                for (PropertyRef propertyRef : dependent.getPropertyRefs()) {
+                  xmlStreamWriter.writeStartElement("PropertyRef");
+                  xmlStreamWriter.writeAttribute("Name", propertyRef.getName());
+                  xmlStreamWriter.writeEndElement();
+                }
+                writeAnnotationElements(dependent.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+                xmlStreamWriter.writeEndElement();
+
+                writeAnnotationElements(referentialConstraint.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+                xmlStreamWriter.writeEndElement();
+              }
+
+              writeAnnotationElements(association.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+              xmlStreamWriter.writeEndElement();
+            }
+          }
+
+          Collection<EntityContainer> entityContainers = schema.getEntityContainers();
+          if (entityContainers != null) {
+            for (EntityContainer entityContainer : entityContainers) {
+              xmlStreamWriter.writeStartElement("EntityContainer");
+              xmlStreamWriter.writeAttribute("Name", entityContainer.getName());
+              if (entityContainer.getExtendz() != null) {
+                xmlStreamWriter.writeAttribute("Extends", entityContainer.getExtendz());
+              }
+              if (entityContainer.isDefaultEntityContainer()) {
+                xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "IsDefaultEntityContainer", "true");
+              }
+
+              writeAnnotationAttributes(entityContainer.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+              writeDocumentation(entityContainer.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+              Collection<EntitySet> entitySets = entityContainer.getEntitySets();
+              if (entitySets != null) {
+                for (EntitySet entitySet : entitySets) {
+                  xmlStreamWriter.writeStartElement("EntitySet");
+                  xmlStreamWriter.writeAttribute("Name", entitySet.getName());
+                  xmlStreamWriter.writeAttribute("EntityType", entitySet.getEntityType().toString());
+
+                  writeAnnotationAttributes(entitySet.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+                  writeDocumentation(entitySet.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+                  writeAnnotationElements(entitySet.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+                  xmlStreamWriter.writeEndElement();
+                }
+              }
+
+              Collection<AssociationSet> associationSets = entityContainer.getAssociationSets();
+              if (associationSets != null) {
+                for (AssociationSet associationSet : associationSets) {
+                  xmlStreamWriter.writeStartElement("AssociationSet");
+                  xmlStreamWriter.writeAttribute("Name", associationSet.getName());
+                  xmlStreamWriter.writeAttribute("Association", associationSet.getAssociation().toString());
+
+                  writeAnnotationAttributes(associationSet.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+                  writeDocumentation(associationSet.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+                  writeAssociationSetEnd(associationSet.getEnd1(), predefinedNamespaces, xmlStreamWriter);
+                  writeAssociationSetEnd(associationSet.getEnd2(), predefinedNamespaces, xmlStreamWriter);
+
+                  writeAnnotationElements(associationSet.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+                  xmlStreamWriter.writeEndElement();
+                }
+              }
+
+              Collection<FunctionImport> functionImports = entityContainer.getFunctionImports();
+              if (functionImports != null) {
+                for (FunctionImport functionImport : functionImports) {
+                  xmlStreamWriter.writeStartElement("FunctionImport");
+                  xmlStreamWriter.writeAttribute("Name", functionImport.getName());
+                  if (functionImport.getReturnType() != null) {
+                    xmlStreamWriter.writeAttribute("ReturnType", functionImport.getReturnType().toString());
+                  }
+                  if (functionImport.getEntitySet() != null) {
+                    xmlStreamWriter.writeAttribute("EntitySet", functionImport.getEntitySet());
+                  }
+                  if (functionImport.getHttpMethod() != null) {
+                    xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "HttpMethod", functionImport.getHttpMethod());
+                  }
+
+                  writeAnnotationAttributes(functionImport.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+                  writeDocumentation(functionImport.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+                  Collection<FunctionImportParameter> functionImportParameters = functionImport.getParameters();
+                  if (functionImportParameters != null) {
+                    for (FunctionImportParameter functionImportParameter : functionImportParameters) {
+                      xmlStreamWriter.writeStartElement("Parameter");
+                      xmlStreamWriter.writeAttribute("Name", functionImportParameter.getName());
+                      xmlStreamWriter.writeAttribute("Type", functionImportParameter.getType().getFullQualifiedName().toString());
+                      if (functionImportParameter.getMode() != null) {
+                        xmlStreamWriter.writeAttribute("Mode", functionImportParameter.getMode());
+                      }
+
+                      writeFacets(xmlStreamWriter, functionImportParameter.getFacets());
+
+                      writeAnnotationAttributes(functionImportParameter.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+                      writeDocumentation(functionImportParameter.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+                      writeAnnotationElements(functionImportParameter.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+                      xmlStreamWriter.writeEndElement();
+                    }
+                  }
+
+                  writeAnnotationElements(functionImport.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+                  xmlStreamWriter.writeEndElement();
+                }
+              }
+
+              writeAnnotationElements(entityContainer.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+              xmlStreamWriter.writeEndElement();
+            }
+          }
+
+          writeAnnotationElements(schema.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+          xmlStreamWriter.writeEndElement();
+        }
+      }
+
+      xmlStreamWriter.writeEndElement();
+      xmlStreamWriter.writeEndElement();
+      xmlStreamWriter.writeEndDocument();
+
+      xmlStreamWriter.flush();
+    } catch (XMLStreamException e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    } catch (FactoryConfigurationError e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    }
+  }
+
+  private static void writeCustomizableFeedMappings(final CustomizableFeedMappings customizableFeedMappings, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException {
+    if (customizableFeedMappings != null) {
+      if (customizableFeedMappings.getFcKeepInContent() != null) {
+        xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "FC_KeepInContent", customizableFeedMappings.getFcKeepInContent().toString().toLowerCase(Locale.ROOT));
+      }
+      if (customizableFeedMappings.getFcContentKind() != null) {
+        xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "FC_ContentKind", customizableFeedMappings.getFcContentKind().toString());
+      }
+      if (customizableFeedMappings.getFcNsPrefix() != null) {
+        xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "FC_NsPrefix", customizableFeedMappings.getFcNsPrefix());
+      }
+      if (customizableFeedMappings.getFcNsUri() != null) {
+        xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "FC_NsUri", customizableFeedMappings.getFcNsUri());
+      }
+      if (customizableFeedMappings.getFcSourcePath() != null) {
+        xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "FC_SourcePath", customizableFeedMappings.getFcSourcePath());
+      }
+      if (customizableFeedMappings.getFcTargetPath() != null) {
+        xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "FC_TargetPath", customizableFeedMappings.getFcTargetPath().toString());
+      }
+    }
+  }
+
+  private static void writeProperties(final Collection<Property> properties, final Map<String, String> predefinedNamespaces, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException {
+    for (Property property : properties) {
+      xmlStreamWriter.writeStartElement("Property");
+      xmlStreamWriter.writeAttribute("Name", property.getName());
+      if (property instanceof SimpleProperty) {
+        xmlStreamWriter.writeAttribute("Type", ((SimpleProperty) property).getType().getFullQualifiedName().toString());
+      } else if (property instanceof ComplexProperty) {
+        xmlStreamWriter.writeAttribute("Type", ((ComplexProperty) property).getType().toString());
+      } else {
+        throw new ODataRuntimeException();
+      }
+
+      writeFacets(xmlStreamWriter, property.getFacets());
+
+      if (property.getMimeType() != null) {
+        xmlStreamWriter.writeAttribute(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08, "MimeType", property.getMimeType());
+      }
+
+      writeCustomizableFeedMappings(property.getCustomizableFeedMappings(), xmlStreamWriter);
+
+      writeAnnotationAttributes(property.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+      writeDocumentation(property.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+      writeAnnotationElements(property.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+      xmlStreamWriter.writeEndElement();
+    }
+  }
+
+  private static void writeFacets(final XMLStreamWriter xmlStreamWriter, final EdmFacets facets) throws XMLStreamException {
+    if (facets != null) {
+      if (facets.isNullable() != null) {
+        xmlStreamWriter.writeAttribute("Nullable", facets.isNullable().toString().toLowerCase(Locale.ROOT));
+      }
+      if (facets.getDefaultValue() != null) {
+        xmlStreamWriter.writeAttribute("DefaultValue", facets.getDefaultValue());
+      }
+      if (facets.getMaxLength() != null) {
+        xmlStreamWriter.writeAttribute("MaxLength", facets.getMaxLength().toString());
+      }
+      if (facets.isFixedLength() != null) {
+        xmlStreamWriter.writeAttribute("FixedLength", facets.isFixedLength().toString().toLowerCase(Locale.ROOT));
+      }
+      if (facets.getPrecision() != null) {
+        xmlStreamWriter.writeAttribute("Precision", facets.getPrecision().toString());
+      }
+      if (facets.getScale() != null) {
+        xmlStreamWriter.writeAttribute("Scale", facets.getScale().toString());
+      }
+      if (facets.isUnicode() != null) {
+        xmlStreamWriter.writeAttribute("Unicode", facets.isUnicode().toString());
+      }
+      if (facets.getCollation() != null) {
+        xmlStreamWriter.writeAttribute("Collation", facets.getCollation());
+      }
+      if (facets.getConcurrencyMode() != null) {
+        xmlStreamWriter.writeAttribute("ConcurrencyMode", facets.getConcurrencyMode().toString());
+      }
+    }
+  }
+
+  private static void writeAssociationEnd(final AssociationEnd end, final Map<String, String> predefinedNamespaces, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException {
+    xmlStreamWriter.writeStartElement("End");
+    xmlStreamWriter.writeAttribute("Type", end.getType().toString());
+    xmlStreamWriter.writeAttribute("Multiplicity", end.getMultiplicity().toString());
+    if (end.getRole() != null) {
+      xmlStreamWriter.writeAttribute("Role", end.getRole());
+    }
+
+    writeAnnotationAttributes(end.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+    writeDocumentation(end.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+
+    OnDelete onDelete = end.getOnDelete();
+    if (onDelete != null) {
+      xmlStreamWriter.writeStartElement("OnDelete");
+      xmlStreamWriter.writeAttribute("Action", onDelete.getAction().toString());
+      writeAnnotationAttributes(onDelete.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+      writeDocumentation(onDelete.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+      writeAnnotationElements(onDelete.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+      xmlStreamWriter.writeEndElement();
+    }
+
+    writeAnnotationElements(end.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+
+    xmlStreamWriter.writeEndElement();
+  }
+
+  private static void writeAssociationSetEnd(final AssociationSetEnd end, final Map<String, String> predefinedNamespaces, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException {
+    xmlStreamWriter.writeStartElement("End");
+    xmlStreamWriter.writeAttribute("EntitySet", end.getEntitySet().toString());
+    if (end.getRole() != null) {
+      xmlStreamWriter.writeAttribute("Role", end.getRole());
+    }
+    writeAnnotationAttributes(end.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+    writeDocumentation(end.getDocumentation(), predefinedNamespaces, xmlStreamWriter);
+    writeAnnotationElements(end.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+    xmlStreamWriter.writeEndElement();
+  }
+
+  private static void writeDocumentation(final Documentation documentation, final Map<String, String> predefinedNamespaces, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException {
+    if (documentation != null) {
+      xmlStreamWriter.writeStartElement("Documentation");
+      writeAnnotationAttributes(documentation.getAnnotationAttributes(), predefinedNamespaces, null, xmlStreamWriter);
+
+      xmlStreamWriter.writeStartElement("Summary");
+      xmlStreamWriter.writeCharacters(documentation.getSummary());
+      xmlStreamWriter.writeEndElement();
+
+      xmlStreamWriter.writeStartElement("LongDescription");
+      xmlStreamWriter.writeCharacters(documentation.getLongDescription());
+      xmlStreamWriter.writeEndElement();
+
+      writeAnnotationElements(documentation.getAnnotationElements(), predefinedNamespaces, xmlStreamWriter);
+      xmlStreamWriter.writeEndElement();
+    }
+  }
+
+  private static void writeAnnotationAttributes(final Collection<AnnotationAttribute> annotationAttributes, final Map<String, String> predefinedNamespaces, ArrayList<String> setNamespaces, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException {
+    if (annotationAttributes != null) {
+      if (setNamespaces == null) {
+        setNamespaces = new ArrayList<String>();
+      }
+      for (AnnotationAttribute annotationAttribute : annotationAttributes) {
+        if (annotationAttribute.getNamespace() != null) {
+          xmlStreamWriter.writeAttribute(annotationAttribute.getPrefix(), annotationAttribute.getNamespace(), annotationAttribute.getName(), annotationAttribute.getText());
+          if (setNamespaces.contains(annotationAttribute.getNamespace()) == false && predefinedNamespaces.containsValue(annotationAttribute.getNamespace()) == false) {
+            xmlStreamWriter.writeNamespace(annotationAttribute.getPrefix(), annotationAttribute.getNamespace());
+            setNamespaces.add(annotationAttribute.getNamespace());
+          }
+        } else {
+          xmlStreamWriter.writeAttribute(annotationAttribute.getName(), annotationAttribute.getText());
+        }
+      }
+    }
+  }
+
+  private static void writeAnnotationElements(final Collection<AnnotationElement> annotationElements, final Map<String, String> predefinedNamespaces, final XMLStreamWriter xmlStreamWriter) throws XMLStreamException {
+    if (annotationElements != null) {
+      for (AnnotationElement annotationElement : annotationElements) {
+        ArrayList<String> setNamespaces = new ArrayList<String>();
+        if (annotationElement.getNamespace() != null) {
+          if (annotationElement.getPrefix() != null) {
+            xmlStreamWriter.writeStartElement(annotationElement.getPrefix(), annotationElement.getName(), annotationElement.getNamespace());
+            if (!predefinedNamespaces.containsValue(annotationElement.getNamespace())) {
+              xmlStreamWriter.writeNamespace(annotationElement.getPrefix(), annotationElement.getNamespace());
+              setNamespaces.add(annotationElement.getNamespace());
+            }
+          } else {
+            xmlStreamWriter.writeStartElement("", annotationElement.getName(), annotationElement.getNamespace());
+            if (!predefinedNamespaces.containsValue(annotationElement.getNamespace())) {
+              xmlStreamWriter.writeNamespace("", annotationElement.getNamespace());
+              setNamespaces.add(annotationElement.getNamespace());
+            }
+          }
+        } else {
+          xmlStreamWriter.writeStartElement(annotationElement.getName());
+        }
+
+        writeAnnotationAttributes(annotationElement.getAttributes(), predefinedNamespaces, setNamespaces, xmlStreamWriter);
+
+        if (annotationElement.getChildElements() != null) {
+          writeAnnotationElements(annotationElement.getChildElements(), predefinedNamespaces, xmlStreamWriter);
+        } else {
+          if (annotationElement.getText() != null) {
+            xmlStreamWriter.writeCharacters(annotationElement.getText());
+          }
+        }
+
+        xmlStreamWriter.writeEndElement();
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlPropertyEntityProducer.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlPropertyEntityProducer.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlPropertyEntityProducer.java
new file mode 100644
index 0000000..930f2f6
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/XmlPropertyEntityProducer.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.ep.producer;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmCustomizableFeedMappings;
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
+import org.apache.olingo.odata2.api.edm.EdmSimpleType;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityComplexPropertyInfo;
+import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
+import org.apache.olingo.odata2.core.ep.util.FormatXml;
+
+/**
+ * Internal EntityProvider for simple and complex EDM properties which are pre-analyzed as {@link EntityPropertyInfo}.
+ * @author SAP AG
+ */
+public class XmlPropertyEntityProducer {
+
+  /**
+   * Append {@link Object} <code>value</code> based on {@link EntityPropertyInfo} to {@link XMLStreamWriter}
+   * in an already existing XML structure inside the d namespace.
+   * 
+   * @param writer
+   * @param name  Name of the outer XML tag
+   * @param propertyInfo
+   * @param value
+   * @throws EntityProviderException
+   */
+  public void append(final XMLStreamWriter writer, final String name, final EntityPropertyInfo propertyInfo, final Object value) throws EntityProviderException {
+    try {
+      writer.writeStartElement(Edm.NAMESPACE_D_2007_08, name);
+
+      if (propertyInfo.isComplex()) {
+        appendProperty(writer, (EntityComplexPropertyInfo) propertyInfo, value);
+      } else {
+        appendProperty(writer, propertyInfo, value);
+      }
+
+      writer.writeEndElement();
+    } catch (XMLStreamException e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    } catch (EdmException e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    }
+  }
+
+  public void appendCustomProperty(final XMLStreamWriter writer, final String name, final EntityPropertyInfo propertyInfo, final Object value) throws EntityProviderException {
+    try {
+      if (!propertyInfo.isComplex()) {
+        writeStartElementWithCustomNamespace(writer, propertyInfo, name);
+        appendProperty(writer, propertyInfo, value);
+        writer.writeEndElement();
+      }
+    } catch (XMLStreamException e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    } catch (EdmException e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    }
+  }
+
+  /**
+   * Append {@link Object} <code>value</code> based on {@link EntityPropertyInfo} to {@link XMLStreamWriter}
+   * as a stand-alone XML structure, including writing of default namespace declarations.
+   * The name of the outermost XML element comes from the {@link EntityPropertyInfo}.
+   * 
+   * @param writer
+   * @param propertyInfo
+   * @param value
+   * @throws EntityProviderException
+   */
+  public void append(final XMLStreamWriter writer, final EntityPropertyInfo propertyInfo, final Object value) throws EntityProviderException {
+    try {
+      writer.writeStartElement(propertyInfo.getName());
+      writer.writeDefaultNamespace(Edm.NAMESPACE_D_2007_08);
+      writer.writeNamespace(Edm.PREFIX_M, Edm.NAMESPACE_M_2007_08);
+
+      if (propertyInfo.isComplex()) {
+        appendProperty(writer, (EntityComplexPropertyInfo) propertyInfo, value);
+      } else {
+        appendProperty(writer, propertyInfo, value);
+      }
+
+      writer.writeEndElement();
+    } catch (XMLStreamException e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    } catch (EdmException e) {
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    }
+  }
+
+  /**
+   * 
+   * @param writer
+   * @param propertyInfo
+   * @param value
+   * @throws XMLStreamException
+   * @throws EdmException
+   * @throws EntityProviderException
+   */
+  private void appendProperty(final XMLStreamWriter writer, final EntityComplexPropertyInfo propertyInfo, final Object value) throws XMLStreamException, EdmException, EntityProviderException {
+
+    if (value == null) {
+      writer.writeAttribute(Edm.NAMESPACE_M_2007_08, FormatXml.ATOM_NULL, FormatXml.ATOM_VALUE_TRUE);
+    } else {
+      writer.writeAttribute(Edm.NAMESPACE_M_2007_08, FormatXml.ATOM_TYPE, getFqnTypeName(propertyInfo));
+      List<EntityPropertyInfo> propertyInfos = propertyInfo.getPropertyInfos();
+      for (EntityPropertyInfo childPropertyInfo : propertyInfos) {
+        Object childValue = extractChildValue(value, childPropertyInfo.getName());
+        append(writer, childPropertyInfo.getName(), childPropertyInfo, childValue);
+      }
+    }
+  }
+
+  /**
+   * Returns full qualified name of a type of a given PropertyInfo.
+   * @return Full qualified name
+   */
+  private String getFqnTypeName(final EntityComplexPropertyInfo propertyInfo) throws EdmException {
+    return propertyInfo.getType().getNamespace() + Edm.DELIMITER + propertyInfo.getType().getName();
+  }
+
+  /**
+   * If <code>value</code> is a {@link Map} the element with given <code>name</code> as key is returned.
+   * If <code>value</code> is NOT a {@link Map} its {@link String#valueOf(Object)} result is returned.
+   * 
+   * @param value
+   * @param name
+   * @return name or result (see above)
+   */
+  private Object extractChildValue(final Object value, final String name) {
+    if (value instanceof Map) {
+      Map<?, ?> map = (Map<?, ?>) value;
+      return map.get(name);
+    }
+    return String.valueOf(value);
+  }
+
+  /**
+   * Appends a simple-property value to the XML stream.
+   * @param writer the XML stream writer
+   * @param prop property informations
+   * @param value the value of the property
+   * @throws XMLStreamException
+   * @throws EdmException
+   */
+  private void appendProperty(final XMLStreamWriter writer, final EntityPropertyInfo prop, final Object value) throws XMLStreamException, EdmException {
+    Object contentValue = value;
+    String mimeType = null;
+    if (prop.getMimeType() != null) {
+      mimeType = prop.getMimeType();
+    } else if (prop.getMapping() != null && prop.getMapping().getMimeType() != null) {
+      mimeType = (String) extractChildValue(value, prop.getMapping().getMimeType());
+      contentValue = extractChildValue(value, prop.getName());
+    }
+
+    if (mimeType != null) {
+      writer.writeAttribute(Edm.NAMESPACE_M_2007_08, FormatXml.M_MIME_TYPE, mimeType);
+    }
+
+    final EdmSimpleType type = (EdmSimpleType) prop.getType();
+    final String valueAsString = type.valueToString(contentValue, EdmLiteralKind.DEFAULT, prop.getFacets());
+    if (valueAsString == null) {
+      writer.writeAttribute(Edm.NAMESPACE_M_2007_08, FormatXml.ATOM_NULL, FormatXml.ATOM_VALUE_TRUE);
+    } else {
+      writer.writeCharacters(valueAsString);
+    }
+  }
+
+  /**
+   * 
+   * @param writer
+   * @param prop
+   * @param name
+   * @throws XMLStreamException
+   * @throws EntityProviderException
+   */
+  private void writeStartElementWithCustomNamespace(final XMLStreamWriter writer, final EntityPropertyInfo prop, final String name) throws XMLStreamException, EntityProviderException {
+    EdmCustomizableFeedMappings mapping = prop.getCustomMapping();
+    String nsPrefix = mapping.getFcNsPrefix();
+    String nsUri = mapping.getFcNsUri();
+    if (nsUri == null || nsPrefix == null) {
+      throw new EntityProviderException(EntityProviderException.INVALID_NAMESPACE.addContent(name));
+    }
+    writer.writeStartElement(nsPrefix, name, nsUri);
+    writer.writeNamespace(nsPrefix, nsUri);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/CircleStreamBuffer.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/CircleStreamBuffer.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/CircleStreamBuffer.java
new file mode 100644
index 0000000..759b374
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/CircleStreamBuffer.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.core.ep.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.Queue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Circular stream buffer to write/read into/from one single buffer.
+ * With support of {@link InputStream} and {@link OutputStream} access to buffered data.
+ * 
+ * @author SAP AG
+ */
+public class CircleStreamBuffer {
+
+  private static final int NEW_BUFFER_RESIZE_FACTOR = 2;
+  private static final int READ_EOF = -1;
+  private static final int DEFAULT_CAPACITY = 8192;
+  private static final int MAX_CAPACITY = DEFAULT_CAPACITY * 32;
+
+  private int currentAllocateCapacity = DEFAULT_CAPACITY;
+
+  private boolean writeMode = true;
+  private boolean writeClosed = false;
+  private boolean readClosed = false;
+
+  private Queue<ByteBuffer> bufferQueue = new LinkedBlockingQueue<ByteBuffer>();
+  private ByteBuffer currentWriteBuffer;
+
+  private InternalInputStream inStream;
+  private InternalOutputStream outStream;
+
+  /**
+   * Creates a {@link CircleStreamBuffer} with default buffer size.
+   */
+  public CircleStreamBuffer() {
+    this(DEFAULT_CAPACITY);
+  }
+
+  /**
+   * Create a {@link CircleStreamBuffer} with given buffer size in bytes.
+   * 
+   * @param bufferSize
+   */
+  public CircleStreamBuffer(final int bufferSize) {
+    currentAllocateCapacity = bufferSize;
+    createNewWriteBuffer();
+    inStream = new InternalInputStream(this);
+    outStream = new InternalOutputStream(this);
+  }
+
+  /**
+   * Get {@link InputStream} for data read access.
+   * 
+   * @return the stream
+   */
+  public InputStream getInputStream() {
+    return inStream;
+  }
+
+  /**
+   * Get {@link OutputStream} for write data.
+   * 
+   * @return the stream
+   */
+  public OutputStream getOutputStream() {
+    return outStream;
+  }
+
+  // #############################################
+  // #
+  // # Common parts
+  // #
+  // #############################################
+
+  /**
+   * Closes the write (input) part of the {@link CircleStreamBuffer}.
+   * After this call the buffer can only be read out.
+   */
+  public void closeWrite() {
+    writeClosed = true;
+  }
+
+  /**
+   * Closes the read (output) part of the {@link CircleStreamBuffer}.
+   * After this call it is possible to write into the buffer (but can never be read out).
+   */
+  public void closeRead() {
+    readClosed = true;
+    // clear references to byte buffers
+    ByteBuffer buffer = bufferQueue.poll();
+    while (buffer != null) {
+      buffer.clear();
+      buffer = bufferQueue.poll();
+    }
+  }
+
+  /**
+   * Closes write and read part (and hence the complete buffer).
+   */
+  public void close() {
+    closeWrite();
+    closeRead();
+  }
+
+  private int remaining() throws IOException {
+    if (writeMode) {
+      return currentWriteBuffer.remaining();
+    } else {
+      ByteBuffer toRead = getReadBuffer();
+      if (toRead == null) {
+        return 0;
+      }
+      return toRead.remaining();
+    }
+  }
+
+  // #############################################
+  // #
+  // # Reading parts
+  // #
+  // #############################################
+
+  private ByteBuffer getReadBuffer() throws IOException {
+    if (readClosed) {
+      throw new IOException("Tried to read from closed stream.");
+    }
+
+    boolean next = false;
+    ByteBuffer tmp = null;
+    if (writeMode) {
+      writeMode = false;
+      next = true;
+    } else {
+      tmp = bufferQueue.peek();
+      if (tmp != null && !tmp.hasRemaining()) {
+        tmp = bufferQueue.poll();
+        next = true;
+      }
+    }
+
+    if (next) {
+      tmp = bufferQueue.peek();
+      if (tmp != null) {
+        tmp.flip();
+      }
+      tmp = getReadBuffer();
+    }
+
+    return tmp;
+  }
+
+  private int read(final byte[] b, final int off, final int len) throws IOException {
+    ByteBuffer readBuffer = getReadBuffer();
+    if (readBuffer == null) {
+      return READ_EOF;
+    }
+
+    int toReadLength = readBuffer.remaining();
+    if (len < toReadLength) {
+      toReadLength = len;
+    }
+    readBuffer.get(b, off, toReadLength);
+    return toReadLength;
+  }
+
+  private int read() throws IOException {
+    ByteBuffer readBuffer = getReadBuffer();
+    if (readBuffer == null) {
+      return READ_EOF;
+    }
+
+    return readBuffer.get();
+  }
+
+  // #############################################
+  // #
+  // # Writing parts
+  // #
+  // #############################################
+
+  private void write(final byte[] data, final int off, final int len) throws IOException {
+    ByteBuffer writeBuffer = getWriteBuffer(len);
+    writeBuffer.put(data, off, len);
+  }
+
+  private ByteBuffer getWriteBuffer(final int size) throws IOException {
+    if (writeClosed) {
+      throw new IOException("Tried to write into closed stream.");
+    }
+
+    if (writeMode) {
+      if (remaining() < size) {
+        createNewWriteBuffer(size);
+      }
+    } else {
+      writeMode = true;
+      createNewWriteBuffer();
+    }
+
+    return currentWriteBuffer;
+  }
+
+  private void write(final int b) throws IOException {
+    ByteBuffer writeBuffer = getWriteBuffer(1);
+    writeBuffer.put((byte) b);
+  }
+
+  private void createNewWriteBuffer() {
+    createNewWriteBuffer(currentAllocateCapacity);
+  }
+
+  /**
+   * Creates a new buffer (per {@link #allocateBuffer(int)}) with the requested capacity as minimum capacity, add the new allocated
+   * buffer to the {@link #bufferQueue} and set it as {@link #currentWriteBuffer}.
+   * 
+   * @param requestedCapacity minimum capacity for new allocated buffer
+   */
+  private void createNewWriteBuffer(final int requestedCapacity) {
+    ByteBuffer b = allocateBuffer(requestedCapacity);
+    bufferQueue.add(b);
+    currentWriteBuffer = b;
+  }
+
+  /**
+   * 
+   * @param requestedCapacity
+   * @return the buffer
+   */
+  private ByteBuffer allocateBuffer(final int requestedCapacity) {
+    int allocateCapacity = requestedCapacity;
+    if (allocateCapacity < currentAllocateCapacity) {
+      allocateCapacity = currentAllocateCapacity * NEW_BUFFER_RESIZE_FACTOR;
+    }
+    if (allocateCapacity > MAX_CAPACITY) {
+      allocateCapacity = MAX_CAPACITY;
+    }
+    // update current
+    currentAllocateCapacity = allocateCapacity;
+    return ByteBuffer.allocate(allocateCapacity);
+  }
+
+  // #############################################
+  // #
+  // # Inner classes (streams)
+  // #
+  // #############################################
+
+  /**
+   * 
+   */
+  private static class InternalInputStream extends InputStream {
+
+    private final CircleStreamBuffer inBuffer;
+
+    public InternalInputStream(final CircleStreamBuffer csBuffer) {
+      inBuffer = csBuffer;
+    }
+
+    @Override
+    public int available() throws IOException {
+      return inBuffer.remaining();
+    }
+
+    @Override
+    public int read() throws IOException {
+      return inBuffer.read();
+    }
+
+    @Override
+    public int read(final byte[] b, final int off, final int len) throws IOException {
+      return inBuffer.read(b, off, len);
+    }
+
+    @Override
+    public void close() throws IOException {
+      inBuffer.closeRead();
+    }
+  }
+
+  /**
+   * 
+   */
+  private static class InternalOutputStream extends OutputStream {
+    private final CircleStreamBuffer outBuffer;
+
+    public InternalOutputStream(final CircleStreamBuffer csBuffer) {
+      outBuffer = csBuffer;
+    }
+
+    @Override
+    public void write(final int b) throws IOException {
+      outBuffer.write(b);
+    }
+
+    @Override
+    public void write(final byte[] b, final int off, final int len) throws IOException {
+      outBuffer.write(b, off, len);
+    }
+
+    @Override
+    public void close() throws IOException {
+      outBuffer.closeWrite();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatJson.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatJson.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatJson.java
new file mode 100644
index 0000000..f1a3d67
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatJson.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.ep.util;
+
+/**
+ * String constants for formatting and parsing of JSON.
+ * @author SAP AG
+ */
+public class FormatJson {
+
+  public static final String D = "d";
+  public static final String RESULTS = "results";
+  public static final String COUNT = "__count";
+  public static final String METADATA = "__metadata";
+  public static final String DEFERRED = "__deferred";
+  public static final String ID = "id";
+  public static final String CONTENT_TYPE = "content_type";
+  public static final String MEDIA_SRC = "media_src";
+  public static final String MEDIA_ETAG = "media_etag";
+  public static final String EDIT_MEDIA = "edit_media";
+  public static final String PROPERTIES = "properties";
+  public static final String URI = "uri";
+  public static final String NULL = "null";
+  public static final String TRUE = "true";
+  public static final String FALSE = "false";
+  public static final String TYPE = "type";
+  public static final String ETAG = "etag";
+  public static final String ENTITY_SETS = "EntitySets";
+  public static final String NEXT = "__next";
+  public static final String ERROR = "error";
+  public static final String CODE = "code";
+  public static final String MESSAGE = "message";
+  public static final String LANG = "lang";
+  public static final String VALUE = "value";
+  public static final String INNER_ERROR = "innererror";
+  public static final String DELTA = "__delta";
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.java
new file mode 100644
index 0000000..52ee8d1
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/FormatXml.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.odata2.core.ep.util;
+
+/**
+ * String constants for formatting and parsing of XML.
+ * @author SAP AG
+ */
+public class FormatXml {
+
+  public static final String XML_HEADER_NO = "no";
+  public static final String XML_HEADER_FULL = "full";
+  public static final String XML_HEADER_WITHOUT_ENCODING = "without encoding";
+  public static final String XML_BASE = "base";
+  public static final String XML_LANG = "lang";
+
+  public static final String M_PROPERTIES = "properties";
+  public static final String M_MIME_TYPE = "MimeType";
+
+  public static final String M_ETAG = "etag";
+  public static final String M_COUNT = "count";
+  public static final String M_TYPE = "type";
+  public static final String M_NULL = "null";
+  public static final String M_INLINE = "inline";
+
+  public static final String M_ERROR = "error";
+  public static final String M_CODE = "code";
+  public static final String M_MESSAGE = "message";
+  public static final String M_INNER_ERROR = "innererror";
+
+  public static final String D_ELEMENT = "element";
+  public static final String D_LINKS = "links";
+  public static final String D_URI = "uri";
+
+  public static final String APP_SERVICE = "service";
+  public static final String APP_WORKSPACE = "workspace";
+  public static final String APP_COLLECTION = "collection";
+  public static final String APP_ACCEPT = "accept";
+  public static final String APP_CATEGORIES = "categories";
+  public static final String APP_CATEGORIES_FIXED = "fixed";
+  public static final String APP_CATEGORIES_SCHEME = "scheme";
+
+  public static final String ATOM_FEED = "feed";
+  public static final String ATOM_ENTRY = "entry";
+  public static final String ATOM_LINK = "link";
+  public static final String ATOM_REL = "rel";
+  public static final String ATOM_HREF = "href";
+  public static final String ATOM_SRC = "src";
+  public static final String ATOM_TITLE = "title";
+  public static final String ATOM_TITLE_DEFAULT = "Default";
+  public static final String ATOM_TEXT = "text";
+  public static final String ATOM_TYPE = "type";
+  public static final String ATOM_UPDATED = "updated";
+  public static final String ATOM_ID = "id";
+  public static final String ATOM_AUTHOR = "author";
+  public static final String ATOM_AUTHOR_NAME = "name";
+  public static final String ATOM_AUTHOR_EMAIL = "email";
+  public static final String ATOM_AUTHOR_URI = "uri";
+  public static final String ATOM_SUMMARY = "summary";
+  public static final String ATOM_CONTRIBUTOR = "contributor";
+  public static final String ATOM_CONTRIBUTOR_NAME = "name";
+  public static final String ATOM_CONTRIBUTOR_EMAIL = "email";
+  public static final String ATOM_CONTRIBUTOR_URI = "uri";
+  public static final String ATOM_PUBLISHED = "published";
+  public static final String ATOM_RIGHTS = "rights";
+  public static final String ATOM_CATEGORY = "category";
+  public static final String ATOM_CATEGORY_TERM = "term";
+  public static final String ATOM_CATEGORY_SCHEME = "scheme";
+  public static final String ATOM_CATEGORY_LABEL = "label";
+  public static final String ATOM_CONTENT = "content";
+  public static final String ATOM_NULL = "null";
+  public static final String ATOM_VALUE_TRUE = "true";
+  public static final String ATOM_NEXT_LINK = "next";
+  public static final String ATOM_DELTA_LINK = "delta";
+  public static final String ATOM_TOMBSTONE_REF = "ref";
+  public static final String ATOM_TOMBSTONE_WHEN = "when";
+  public static final String ATOM_TOMBSTONE_DELETED_ENTRY = "deleted-entry";
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/JsonStreamWriter.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/JsonStreamWriter.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/JsonStreamWriter.java
new file mode 100644
index 0000000..185d32a
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/JsonStreamWriter.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.ep.util;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * Writes JSON output.
+ * @author SAP AG
+ */
+public class JsonStreamWriter {
+  private final Writer writer;
+
+  public JsonStreamWriter(final Writer writer) {
+    this.writer = writer;
+  }
+
+  public JsonStreamWriter beginObject() throws IOException {
+    writer.append('{');
+    return this;
+  }
+
+  public JsonStreamWriter endObject() throws IOException {
+    writer.append('}');
+    return this;
+  }
+
+  public JsonStreamWriter beginArray() throws IOException {
+    writer.append('[');
+    return this;
+  }
+
+  public JsonStreamWriter endArray() throws IOException {
+    writer.append(']');
+    return this;
+  }
+
+  public JsonStreamWriter name(final String name) throws IOException {
+    writer.append('"').append(name).append('"').append(':');
+    return this;
+  }
+
+  public JsonStreamWriter unquotedValue(final String value) throws IOException {
+    writer.append(value == null ? FormatJson.NULL : value);
+    return this;
+  }
+
+  public JsonStreamWriter stringValueRaw(final String value) throws IOException {
+    if (value == null) {
+      writer.append(FormatJson.NULL);
+    } else {
+      writer.append('"').append(value).append('"');
+    }
+    return this;
+  }
+
+  public JsonStreamWriter stringValue(final String value) throws IOException {
+    if (value == null) {
+      writer.append(FormatJson.NULL);
+    } else {
+      writer.append('"');
+      escape(value);
+      writer.append('"');
+    }
+    return this;
+  }
+
+  public JsonStreamWriter namedStringValueRaw(final String name, final String value) throws IOException {
+    name(name);
+    stringValueRaw(value);
+    return this;
+  }
+
+  public JsonStreamWriter namedStringValue(final String name, final String value) throws IOException {
+    name(name);
+    stringValue(value);
+    return this;
+  }
+
+  public JsonStreamWriter separator() throws IOException {
+    writer.append(',');
+    return this;
+  }
+
+  /**
+   * Writes the JSON-escaped form of a Java String value according to RFC 4627.
+   * @param value the Java String
+   * @throws IOException if an I/O error occurs
+   */
+  protected void escape(final String value) throws IOException {
+    // RFC 4627 says: "All Unicode characters may be placed within the
+    // quotation marks except for the characters that must be escaped:
+    // quotation mark, reverse solidus, and the control characters
+    // (U+0000 through U+001F)."
+    // All output here is done on character basis which should be faster
+    // than writing Strings.
+    for (int i = 0; i < value.length(); i++) {
+      final char c = value.charAt(i);
+      switch (c) {
+      case '\\':
+        writer.append('\\').append(c);
+        break;
+      case '"':
+        writer.append('\\').append(c);
+        break;
+      case '\b':
+        writer.append('\\').append('b');
+        break;
+      case '\t':
+        writer.append('\\').append('t');
+        break;
+      case '\n':
+        writer.append('\\').append('n');
+        break;
+      case '\f':
+        writer.append('\\').append('f');
+        break;
+      case '\r':
+        writer.append('\\').append('r');
+        break;
+      case '\u0000':
+      case '\u0001':
+      case '\u0002':
+      case '\u0003':
+      case '\u0004':
+      case '\u0005':
+      case '\u0006':
+      case '\u0007':
+      case '\u000B':
+      case '\u000E':
+      case '\u000F':
+      case '\u0010':
+      case '\u0011':
+      case '\u0012':
+      case '\u0013':
+      case '\u0014':
+      case '\u0015':
+      case '\u0016':
+      case '\u0017':
+      case '\u0018':
+      case '\u0019':
+      case '\u001A':
+      case '\u001B':
+      case '\u001C':
+      case '\u001D':
+      case '\u001E':
+      case '\u001F':
+        final int lastHexDigit = c % 0x10;
+        writer.append('\\').append('u').append('0').append('0')
+            .append(c >= '\u0010' ? '1' : '0')
+            .append((char) ((lastHexDigit > 9 ? 'A' : '0') + lastHexDigit % 10));
+        break;
+      default:
+        writer.append(c);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/JsonUtils.java
----------------------------------------------------------------------
diff --git a/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/JsonUtils.java b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/JsonUtils.java
new file mode 100644
index 0000000..53542ab
--- /dev/null
+++ b/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/util/JsonUtils.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *        or more contributor license agreements.  See the NOTICE file
+ *        distributed with this work for additional information
+ *        regarding copyright ownership.  The ASF licenses this file
+ *        to you under the Apache License, Version 2.0 (the
+ *        "License"); you may not use this file except in compliance
+ *        with the License.  You may obtain a copy of the License at
+ * 
+ *          http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *        Unless required by applicable law or agreed to in writing,
+ *        software distributed under the License is distributed on an
+ *        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *        KIND, either express or implied.  See the License for the
+ *        specific language governing permissions and limitations
+ *        under the License.
+ ******************************************************************************/
+package org.apache.olingo.odata2.core.ep.util;
+
+import java.io.IOException;
+
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import org.apache.olingo.odata2.api.ep.EntityProviderException;
+
+public class JsonUtils {
+
+  public static int startJson(final JsonReader reader) throws EntityProviderException {
+    //The enclosing "d" and "results" are optional - so we cannot check for the presence
+    //but we have to read over them in case they are present.
+    JsonToken token;
+    try {
+      token = reader.peek();
+      int openJsonObjects = 0;
+      if (JsonToken.BEGIN_OBJECT == token) {
+        reader.beginObject();
+        openJsonObjects++;
+        token = reader.peek();
+        if (JsonToken.NAME == token) {
+          String name = reader.nextName();
+          if (!("d".equals(name) ^ "results".equals(name))) {
+            //TODO I18N
+            throw new EntityProviderException(EntityProviderException.COMMON, name + " not expected, only d or results");
+          }
+        }
+
+        token = reader.peek();
+        if (JsonToken.BEGIN_OBJECT == token) {
+          reader.beginObject();
+          openJsonObjects++;
+        } else if (JsonToken.BEGIN_ARRAY == token) {
+          //TODO I18N
+          throw new EntityProviderException(EntityProviderException.COMMON, "Array not expected");
+        }
+      }
+
+      return openJsonObjects;
+    } catch (IOException e) {
+      //TODO I18N
+      throw new EntityProviderException(EntityProviderException.COMMON, e);
+    }
+  }
+
+  public static boolean endJson(final JsonReader reader, final int openJsonObjects) throws IOException, EntityProviderException {
+
+    for (int closedJsonObjects = 0; closedJsonObjects < openJsonObjects; closedJsonObjects++) {
+      reader.endObject();
+    }
+    return reader.peek() == JsonToken.END_DOCUMENT;
+  }
+}