package com.sap.core.odata.core.edm.provider;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sap.core.odata.api.edm.Edm;
import com.sap.core.odata.api.edm.EdmServiceMetadata;
import com.sap.core.odata.api.edm.provider.DataServices;
import com.sap.core.odata.api.edm.provider.EdmProvider;
import com.sap.core.odata.api.edm.provider.EntityType;
import com.sap.core.odata.api.edm.provider.Property;
import com.sap.core.odata.api.edm.provider.Schema;
import com.sap.core.odata.api.ep.EntityProviderException;
import com.sap.core.odata.api.exception.ODataException;

public class EdmServiceMetadataImplProv implements EdmServiceMetadata {

  private static final Logger LOG = LoggerFactory.getLogger(EdmServiceMetadataImplProv.class);

  private EdmProvider edmProvider;
  private String dataServiceVersion;
  private List<Schema> schemas;

  public EdmServiceMetadataImplProv(EdmProvider edmProvider) {
    this.edmProvider = edmProvider;
  }

  @Override
  public InputStream getMetadata() throws ODataException {
    if (schemas == null) {
      schemas = edmProvider.getSchemas();
    }

    OutputStreamWriter writer = null;

    try {
      DataServices metadata = new DataServices().setSchemas(schemas).setDataServiceVersion(getDataServiceVersion());
      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      writer = new OutputStreamWriter(outputStream, "UTF-8");
      EdmMetadata.writeMetadata(metadata, writer);
      return new ByteArrayInputStream(outputStream.toByteArray());
    } catch (UnsupportedEncodingException e) {
      throw new EntityProviderException(EntityProviderException.COMMON, e);
    } finally {
      if (writer != null) {
        try {
          writer.close();
        } catch (IOException e) {
          // don't throw in finally!  
          LOG.error(e.getLocalizedMessage(), e);
        }
      }
    }
  }

  @Override
  public String getDataServiceVersion() throws ODataException {
    if (schemas == null) {
      schemas = edmProvider.getSchemas();
    }

    if (dataServiceVersion == null) {
      dataServiceVersion = Edm.DATA_SERVICE_VERSION_10;

      if (schemas != null) {
        for (Schema schema : schemas) {
          List<EntityType> entityTypes = schema.getEntityTypes();
          if (entityTypes != null) {
            for (EntityType entityType : entityTypes) {
              List<Property> properties = entityType.getProperties();
              if (properties != null) {
                for (Property property : properties) {
                  if (property.getCustomizableFeedMappings() != null) {
                    if (property.getCustomizableFeedMappings().getFcKeepInContent() != null) {
                      if (!property.getCustomizableFeedMappings().getFcKeepInContent()) {
                        dataServiceVersion = Edm.DATA_SERVICE_VERSION_20;
                        return dataServiceVersion;
                      }
                    }
                  }
                }
                if (entityType.getCustomizableFeedMappings() != null) {
                  if (entityType.getCustomizableFeedMappings().getFcKeepInContent() != null) {
                    if (entityType.getCustomizableFeedMappings().getFcKeepInContent()) {
                      dataServiceVersion = Edm.DATA_SERVICE_VERSION_20;
                      return dataServiceVersion;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    return dataServiceVersion;
  }
}
@@ -44,83 +44,8 @@
 r;%0A%0A
-import java.io.ByteArrayInputStream;%0Aimport java.io.ByteArrayOutputStream;%0A
 impo
@@ -736,16 +736,75 @@
 ception;
+%0Aimport com.sap.core.odata.core.ep.util.CircleStreamBuffer;
 %0A%0Apublic
@@ -1360,16 +1360,75 @@
 = null;%0A
+    CircleStreamBuffer csb = new CircleStreamBuffer();%0A    
 %0A    try
@@ -1551,80 +1551,8 @@
 ));%0A
-      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();%0A
     
@@ -1585,17 +1585,24 @@
 mWriter(
-o
+csb.getO
 utputStr
@@ -1604,16 +1604,18 @@
 utStream
+()
 , %22UTF-8
@@ -1686,59 +1686,27 @@
 urn 
-new ByteArrayInputStream(outputStream.toByteArray()
+csb.getInputStream(
 );%0A 

Introduce circlestreambuffer for metadata serialization