Repository: olingo-odata4
Updated Branches:
  refs/heads/OLINGO-832_StreamSerializerPoC [created] f4ad8892a


[OLINGO-832] First idea of PoC


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/f4ad8892
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/f4ad8892
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/f4ad8892

Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: f4ad8892adf11a91e99b7bc555f6c765140d5bc9
Parents: d88913f
Author: Michael Bolz <[email protected]>
Authored: Tue Dec 8 14:49:26 2015 +0100
Committer: Michael Bolz <[email protected]>
Committed: Mon Dec 14 09:12:03 2015 +0100

----------------------------------------------------------------------
 .../api/data/EntityStreamCollection.java        |  28 +++
 .../apache/olingo/server/core/ODataImpl.java    |   4 +-
 .../core/serializer/StreamSerializerResult.java | 166 +++++++++++++++++
 .../serializer/json/ODataJsonSerializer.java    |  10 +-
 .../json/ODataJsonStreamSerializer.java         | 183 +++++++++++++++++++
 .../processor/TechnicalEntityProcessor.java     | 116 +++++++++++-
 6 files changed, 500 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f4ad8892/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityStreamCollection.java
----------------------------------------------------------------------
diff --git 
a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityStreamCollection.java
 
b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityStreamCollection.java
new file mode 100644
index 0000000..9eae442
--- /dev/null
+++ 
b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityStreamCollection.java
@@ -0,0 +1,28 @@
+/*
+ * 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.commons.api.data;
+
+/**
+ * Data representation for a collection of single entities.
+ */
+public abstract class EntityStreamCollection extends EntityCollection {
+
+  public abstract boolean hasNext();
+  public abstract Entity nextEntity();
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f4ad8892/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
index ad7d410..df6c7df 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
@@ -49,6 +49,7 @@ import org.apache.olingo.server.core.etag.ETagHelperImpl;
 import org.apache.olingo.server.core.prefer.PreferencesImpl;
 import org.apache.olingo.server.core.serializer.FixedFormatSerializerImpl;
 import org.apache.olingo.server.core.serializer.json.ODataJsonSerializer;
+import org.apache.olingo.server.core.serializer.json.ODataJsonStreamSerializer;
 import org.apache.olingo.server.core.serializer.xml.ODataXmlSerializer;
 import org.apache.olingo.server.core.uri.UriHelperImpl;
 
@@ -63,7 +64,8 @@ public class ODataImpl extends OData {
       if (metadata == null
           || ContentType.VALUE_ODATA_METADATA_MINIMAL.equals(metadata)
           || ContentType.VALUE_ODATA_METADATA_NONE.equals(metadata)) {
-        serializer = new ODataJsonSerializer(contentType);
+//        serializer = new ODataJsonSerializer(contentType);
+        serializer = new ODataJsonStreamSerializer(contentType);
       }
     } else if (contentType.isCompatible(ContentType.APPLICATION_XML)
         || contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f4ad8892/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/StreamSerializerResult.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/StreamSerializerResult.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/StreamSerializerResult.java
new file mode 100644
index 0000000..d45c594
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/StreamSerializerResult.java
@@ -0,0 +1,166 @@
+/*
+ * 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.server.core.serializer;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityStreamCollection;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.core.serializer.json.ODataJsonStreamSerializer;
+import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class StreamSerializerResult implements SerializerResult {
+  private InputStream content;
+
+  private static class StreamInputStream extends InputStream {
+    private String head;
+    private String tail;
+    private int tailCount = 0;
+    private int headCount = 0;
+    private int entityCount = 0;
+    private InputStream inputStream = null;
+    private ODataJsonStreamSerializer jsonSerializer;
+    private EntityStreamCollection coll;
+    private ServiceMetadata metadata;
+    private EdmEntityType entityType;
+    private EntitySerializerOptions options;
+
+    public StreamInputStream(EntityStreamCollection coll, EdmEntityType 
entityType, String head,
+        ODataJsonStreamSerializer jsonSerializer, ServiceMetadata metadata,
+        EntitySerializerOptions options, String tail) {
+      this.coll = coll;
+      this.entityType = entityType;
+      this.head = head;
+      this.jsonSerializer = jsonSerializer;
+      this.metadata = metadata;
+      this.options = options;
+      this.tail = tail;
+    }
+
+    @Override
+    public int read() throws IOException {
+      if (headCount < head.length()) {
+        return head.charAt(headCount++);
+      }
+      if (inputStream == null && coll.hasNext()) {
+        try {
+          inputStream = serEntity(coll.nextEntity());
+          entityCount++;
+          if (entityCount > 1) {
+            return (int) ',';
+          }
+        } catch (SerializerException e) {
+          inputStream = null;
+          return read();
+        }
+      }
+      if (inputStream != null) {
+        int read = inputStream.read();
+        if (read == -1) {
+          inputStream = null;
+          return read();
+        }
+        return read;
+      }
+      if (tailCount < tail.length()) {
+        return tail.charAt(tailCount++);
+      }
+      return -1;
+    }
+
+    private InputStream serEntity(Entity entity) throws SerializerException {
+      try {
+        CircleStreamBuffer buffer = new CircleStreamBuffer();
+        OutputStream outputStream = buffer.getOutputStream();
+        JsonGenerator json = new JsonFactory().createGenerator(outputStream);
+        jsonSerializer.writeEntity(metadata, entityType, entity, null,
+            options == null ? null : options.getExpand(),
+            options == null ? null : options.getSelect(),
+            options != null && options.getWriteOnlyReferences(),
+            json);
+
+        json.close();
+        outputStream.close();
+        return buffer.getInputStream();
+      } catch (final IOException e) {
+        return new ByteArrayInputStream(("ERROR" + e.getMessage()).getBytes());
+//      } catch (SerializerException e) {
+//        return new ByteArrayInputStream(("ERROR" + 
e.getMessage()).getBytes());
+      }
+    }
+  }
+
+  @Override
+  public InputStream getContent() {
+    return content;
+  }
+
+  private StreamSerializerResult(InputStream content) {
+    this.content = content;
+  }
+
+  public static SerializerResultBuilder with(EntityStreamCollection coll, 
EdmEntityType entityType,
+      ODataJsonStreamSerializer jsonSerializer, ServiceMetadata metadata, 
EntitySerializerOptions options) {
+    return new SerializerResultBuilder(coll, entityType, jsonSerializer, 
metadata, options);
+  }
+
+  public static class SerializerResultBuilder {
+    private ODataJsonStreamSerializer jsonSerializer;
+    private EntityStreamCollection coll;
+    private ServiceMetadata metadata;
+    private EdmEntityType entityType;
+    private EntitySerializerOptions options;
+    private String head;
+    private String tail;
+
+    public SerializerResultBuilder(EntityStreamCollection coll, EdmEntityType 
entityType,
+        ODataJsonStreamSerializer jsonSerializer, ServiceMetadata metadata, 
EntitySerializerOptions options) {
+      this.coll = coll;
+      this.entityType = entityType;
+      this.jsonSerializer = jsonSerializer;
+      this.metadata = metadata;
+      this.options = options;
+    }
+
+    public SerializerResultBuilder addHead(String head) {
+      this.head = head;
+      return this;
+    }
+
+    public SerializerResultBuilder addTail(String tail) {
+      this.tail = tail;
+      return this;
+    }
+
+    public SerializerResult build() {
+      InputStream input = new StreamInputStream(coll, entityType, head, 
jsonSerializer, metadata, options, tail);
+      return new StreamSerializerResult(input);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f4ad8892/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
index b5a2c6a..4a1a528 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
@@ -203,7 +203,7 @@ public class ODataJsonSerializer extends 
AbstractODataSerializer {
     }
   }
 
-  private ContextURL checkContextURL(final ContextURL contextURL) throws 
SerializerException {
+  ContextURL checkContextURL(final ContextURL contextURL) throws 
SerializerException {
     if (isODataMetadataNone) {
       return null;
     } else if (contextURL == null) {
@@ -767,13 +767,13 @@ public class ODataJsonSerializer extends 
AbstractODataSerializer {
 
   }
 
-  private void writeContextURL(final ContextURL contextURL, JsonGenerator 
json) throws IOException {
+  void writeContextURL(final ContextURL contextURL, JsonGenerator json) throws 
IOException {
     if (!isODataMetadataNone && contextURL != null) {
       json.writeStringField(Constants.JSON_CONTEXT, 
ContextURLBuilder.create(contextURL).toASCIIString());
     }
   }
 
-  private void writeMetadataETag(final ServiceMetadata metadata, JsonGenerator 
json) throws IOException {
+  void writeMetadataETag(final ServiceMetadata metadata, JsonGenerator json) 
throws IOException {
     if (!isODataMetadataNone
         && metadata != null
         && metadata.getServiceMetadataETagSupport() != null
@@ -783,7 +783,7 @@ public class ODataJsonSerializer extends 
AbstractODataSerializer {
     }
   }
 
-  private void writeCount(final EntityCollection entityCollection, 
JsonGenerator json) throws IOException {
+  void writeCount(final EntityCollection entityCollection, JsonGenerator json) 
throws IOException {
     if (entityCollection.getCount() != null) {
       if (isIEEE754Compatible) {
         json.writeStringField(Constants.JSON_COUNT, 
entityCollection.getCount().toString());
@@ -793,7 +793,7 @@ public class ODataJsonSerializer extends 
AbstractODataSerializer {
     }
   }
 
-  private void writeNextLink(final EntityCollection entitySet, JsonGenerator 
json) throws IOException {
+  void writeNextLink(final EntityCollection entitySet, JsonGenerator json) 
throws IOException {
     if (entitySet.getNext() != null) {
       json.writeStringField(Constants.JSON_NEXT_LINK, 
entitySet.getNext().toASCIIString());
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f4ad8892/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonStreamSerializer.java
----------------------------------------------------------------------
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonStreamSerializer.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonStreamSerializer.java
new file mode 100644
index 0000000..08a30c6
--- /dev/null
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonStreamSerializer.java
@@ -0,0 +1,183 @@
+/*
+ * 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.server.core.serializer.json;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.data.ComplexValue;
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.data.EntityStreamCollection;
+import org.apache.olingo.commons.api.data.Link;
+import org.apache.olingo.commons.api.data.Linked;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
+import org.apache.olingo.commons.api.edm.EdmType;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
+import org.apache.olingo.commons.api.format.ContentType;
+import 
org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
+import org.apache.olingo.server.api.ODataServerError;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
+import 
org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
+import 
org.apache.olingo.server.api.serializer.ReferenceCollectionSerializerOptions;
+import org.apache.olingo.server.api.serializer.ReferenceSerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.api.uri.UriHelper;
+import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
+import org.apache.olingo.server.core.serializer.AbstractODataSerializer;
+import org.apache.olingo.server.core.serializer.SerializerResultImpl;
+import org.apache.olingo.server.core.serializer.StreamSerializerResult;
+import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
+import org.apache.olingo.server.core.serializer.utils.ContentTypeHelper;
+import org.apache.olingo.server.core.serializer.utils.ContextURLBuilder;
+import org.apache.olingo.server.core.serializer.utils.ExpandSelectHelper;
+import org.apache.olingo.server.core.uri.UriHelperImpl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class ODataJsonStreamSerializer extends ODataJsonSerializer {
+
+  private final ODataJsonSerializer serializer;
+
+  public ODataJsonStreamSerializer(final ContentType contentType) {
+    super(contentType);
+    this.serializer = new ODataJsonSerializer(contentType);
+  }
+
+  @Override
+  public SerializerResult entityCollection(final ServiceMetadata metadata,
+      final EdmEntityType entityType, final EntityCollection entitySet,
+      final EntityCollectionSerializerOptions options) throws 
SerializerException {
+
+    EntityStreamCollection coll;
+    if(entitySet instanceof EntityStreamCollection) {
+      coll = (EntityStreamCollection) entitySet;
+    } else {
+      return serializer.entityCollection(metadata, entityType, entitySet, 
options);
+    }
+
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    SerializerException cachedException = null;
+    try {
+      JsonGenerator json = new JsonFactory().createGenerator(outputStream);
+      json.writeStartObject();
+
+      final ContextURL contextURL = serializer.checkContextURL(options == null 
? null : options.getContextURL());
+      serializer.writeContextURL(contextURL, json);
+
+      serializer.writeMetadataETag(metadata, json);
+
+      if (options != null && options.getCount() != null && 
options.getCount().getValue()) {
+        serializer.writeCount(entitySet, json);
+      }
+      json.writeFieldName(Constants.VALUE);
+      json.writeStartArray();
+      json.close();
+      outputStream.close();
+      String temp = new String(outputStream.toByteArray(), 
Charset.forName("UTF-8"));
+      String head = temp.substring(0, temp.length()-2);
+      //      if (options == null) {
+//        writeEntitySet(metadata, entityType, entitySet, null, null, false, 
json);
+//      } else {
+//        writeEntitySet(metadata, entityType, entitySet,
+//            options.getExpand(), options.getSelect(), 
options.getWriteOnlyReferences(), json);
+//      }
+
+      outputStream = new ByteArrayOutputStream();
+      outputStream.write(']');
+      outputStream.write('}');
+      outputStream.close();
+      String tail = new String(outputStream.toByteArray(), 
Charset.forName("UTF-8"));
+
+      EntitySerializerOptions.Builder opt = EntitySerializerOptions.with();
+      if(options != null) {
+        opt.expand(options.getExpand()).select(options
+            
.getSelect()).writeOnlyReferences(options.getWriteOnlyReferences());
+      }
+      return StreamSerializerResult.with(coll, entityType, this, metadata, 
opt.build())
+          .addHead(head).addTail(tail).build();
+    } catch (final IOException e) {
+      cachedException =
+          new SerializerException(IO_EXCEPTION_TEXT, e, 
SerializerException.MessageKeys.IO_EXCEPTION);
+      throw cachedException;
+    } finally {
+      closeCircleStreamBufferOutput(outputStream, cachedException);
+    }
+  }
+
+  @Override
+  public void writeEntity(final ServiceMetadata metadata, final EdmEntityType 
entityType,
+      final Entity entity, final ContextURL contextURL, final ExpandOption 
expand,
+      final SelectOption select, final boolean onlyReference, final 
JsonGenerator json)
+      throws IOException, SerializerException {
+    serializer.writeEntity(metadata, entityType, entity, contextURL, expand, 
select, onlyReference, json);
+  }
+
+//  @Override
+//  public SerializerResult entity(final ServiceMetadata metadata, final 
EdmEntityType entityType,
+//      final Entity entity, final EntitySerializerOptions options) throws 
SerializerException {
+//    return serializer.entity(metadata, entityType, entity, options);
+//  }
+
+//  protected void writeEntitySet(final ServiceMetadata metadata, final 
EdmEntityType entityType,
+//      final EntityCollection entitySet, final ExpandOption expand, final 
SelectOption select,
+//      final boolean onlyReference, final JsonGenerator json) throws 
IOException,
+//      SerializerException {
+//
+//        json.writeStartArray();
+//        json.writeEndArray();
+//
+    //    json.writeStartArray();
+//    for (final Entity entity : entitySet.getEntities()) {
+//      if (onlyReference) {
+//        json.writeStartObject();
+//        json.writeStringField(Constants.JSON_ID, 
entity.getId().toASCIIString());
+//        json.writeEndObject();
+//      } else {
+//        serializer.writeEntity(metadata, entityType, entity, null, expand, 
select, false, json);
+//      }
+//    }
+//    json.writeEndArray();
+//  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f4ad8892/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git 
a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
 
b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index 6d7c41e..6644f1e 100644
--- 
a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ 
b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -18,13 +18,20 @@
  */
 package org.apache.olingo.server.tecsvc.processor;
 
+import java.util.Iterator;
+import java.util.List;
 import java.util.Locale;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.olingo.commons.api.data.ContextURL;
 import org.apache.olingo.commons.api.data.ContextURL.Builder;
 import org.apache.olingo.commons.api.data.ContextURL.Suffix;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.data.EntityStreamCollection;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ValueType;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.format.ContentType;
@@ -520,11 +527,17 @@ public class TechnicalEntityProcessor extends 
TechnicalProcessor
     }
 
     // Serialize
+//    final SerializerResult serializerResult = (isReference) ?
+//        serializeReferenceCollection(entitySetSerialization, edmEntitySet, 
requestedContentType, countOption) :
+//        serializeEntityCollection(request, entitySetSerialization, 
edmEntitySet, edmEntityType, requestedContentType,
+//            expand, select, countOption, id);
     final SerializerResult serializerResult = (isReference) ?
         serializeReferenceCollection(entitySetSerialization, edmEntitySet, 
requestedContentType, countOption) :
-        serializeEntityCollection(request, entitySetSerialization, 
edmEntitySet, edmEntityType, requestedContentType,
+        serializeEntityStreamCollectionFixed(request,
+            entitySetSerialization, edmEntitySet, edmEntityType, 
requestedContentType,
             expand, select, countOption, id);
     response.setContent(serializerResult.getContent());
+
     response.setStatusCode(HttpStatusCode.OK.getStatusCode());
     response.setHeader(HttpHeader.CONTENT_TYPE, 
requestedContentType.toContentTypeString());
     if (pageSize != null) {
@@ -533,6 +546,107 @@ public class TechnicalEntityProcessor extends 
TechnicalProcessor
     }
   }
 
+  // just for demonstration
+  private SerializerResult serializeEntityStreamCollectionFixed(final 
ODataRequest request,
+      final EntityCollection entityCollection, final EdmEntitySet edmEntitySet,
+      final EdmEntityType edmEntityType,
+      final ContentType requestedFormat, final ExpandOption expand, final 
SelectOption select,
+      final CountOption countOption, final String id) throws 
ODataLibraryException {
+
+    EntityStreamCollection streamCollection = new EntityStreamCollection() {
+      Iterator<Entity> entityIterator = 
entityCollection.getEntities().iterator();
+
+      @Override
+      public boolean hasNext() {
+        return entityIterator.hasNext();
+      }
+
+      @Override
+      public Entity nextEntity() {
+        Entity next = entityIterator.next();
+        replacePrimitiveProperty(next, "PropertyString", generateData(28192));
+//        next.getProperties().remove(1);
+//        next.addProperty(new Property(null, "PropertyString", 
ValueType.PRIMITIVE, generateData(28192)));
+        try {
+          TimeUnit.MILLISECONDS.sleep(2500);
+        } catch (InterruptedException e) { }
+        return next;
+      }
+
+      @Override
+      public List<Entity> getEntities() {
+        return entityCollection.getEntities();
+      }
+
+      private void replacePrimitiveProperty(Entity entity, String name, Object 
data) {
+        List<Property> properties = entity.getProperties();
+        int pos = 0;
+        for (Property property : properties) {
+          if(name.equals(property.getName())) {
+            properties.remove(pos);
+            entity.addProperty(new Property(null, name, ValueType.PRIMITIVE, 
data));
+            break;
+          }
+          pos++;
+        }
+      }
+
+      private String generateData(final int len) {
+        Random random = new Random();
+        StringBuilder b = new StringBuilder(len);
+        for (int j = 0; j < len; j++) {
+          final char c = (char) ('A' + random.nextInt('Z' - 'A' + 1));
+          b.append(c);
+        }
+        return b.toString();
+      }
+
+    };
+
+    return odata.createSerializer(requestedFormat).entityCollection(
+        serviceMetadata,
+        edmEntityType,
+        streamCollection,
+        EntityCollectionSerializerOptions.with()
+            .contextURL(isODataMetadataNone(requestedFormat) ? null :
+                getContextUrl(request.getRawODataPath(), edmEntitySet, 
edmEntityType, false, expand, select))
+            .count(countOption)
+            .expand(expand).select(select)
+            .id(id)
+            .build());
+  }
+
+  private SerializerResult serializeEntityStreamCollection(final ODataRequest 
request,
+      final EntityCollection entityCollection, final EdmEntitySet edmEntitySet,
+      final EdmEntityType edmEntityType,
+      final ContentType requestedFormat, final ExpandOption expand, final 
SelectOption select,
+      final CountOption countOption, final String id) throws 
ODataLibraryException {
+
+    EntityStreamCollection streamCollection = new EntityStreamCollection() {
+      Iterator<Entity> test = entityCollection.getEntities().iterator();
+      @Override
+      public boolean hasNext() {
+        return test.hasNext();
+      }
+
+      @Override
+      public Entity nextEntity() {
+        return test.next();
+      }
+    };
+    return odata.createSerializer(requestedFormat).entityCollection(
+        serviceMetadata,
+        edmEntityType,
+        streamCollection,
+        EntityCollectionSerializerOptions.with()
+            .contextURL(isODataMetadataNone(requestedFormat) ? null :
+                getContextUrl(request.getRawODataPath(), edmEntitySet, 
edmEntityType, false, expand, select))
+            .count(countOption)
+            .expand(expand).select(select)
+            .id(id)
+            .build());
+  }
+
   private SerializerResult serializeEntityCollection(final ODataRequest 
request, final EntityCollection
       entityCollection, final EdmEntitySet edmEntitySet, final EdmEntityType 
edmEntityType,
       final ContentType requestedFormat, final ExpandOption expand, final 
SelectOption select,

Reply via email to