You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2016/02/19 21:57:41 UTC
olingo-odata4 git commit: [OlINGO-832] Clean up and basic IT test
Repository: olingo-odata4
Updated Branches:
refs/heads/OLINGO-832_StreamSerializerPoC 4aa1277a1 -> 09fd6d9b4
[OlINGO-832] Clean up and basic IT test
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/09fd6d9b
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/09fd6d9b
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/09fd6d9b
Branch: refs/heads/OLINGO-832_StreamSerializerPoC
Commit: 09fd6d9b48dd0b833176dbe0b2864c5065b99ee0
Parents: 4aa1277
Author: Michael Bolz <mi...@sap.com>
Authored: Fri Feb 19 21:57:31 2016 +0100
Committer: Michael Bolz <mi...@sap.com>
Committed: Fri Feb 19 21:57:31 2016 +0100
----------------------------------------------------------------------
.../fit/tecsvc/http/BasicStreamITCase.java | 66 ++++++
.../server/api/WriteContentErrorCallback.java | 5 +
.../server/api/WriteContentErrorContext.java | 4 +-
.../server/core/ODataWritableContent.java | 235 +++++--------------
.../serializer/SerializerStreamResultImpl.java | 19 --
.../core/serializer/xml/ODataXmlSerializer.java | 62 ++++-
.../processor/TechnicalEntityProcessor.java | 52 +++-
7 files changed, 247 insertions(+), 196 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/09fd6d9b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java
new file mode 100644
index 0000000..1903d13
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicStreamITCase.java
@@ -0,0 +1,66 @@
+/*
+ * 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.fit.tecsvc.http;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.fit.AbstractBaseTestITCase;
+import org.apache.olingo.fit.tecsvc.TecSvcConst;
+import org.junit.Test;
+
+public class BasicStreamITCase extends AbstractBaseTestITCase {
+
+ private static final String SERVICE_URI = TecSvcConst.BASE_URI + "/";
+
+ @Test
+ public void streamAllPrim() throws Exception {
+ URL url = new URL(SERVICE_URI + "ESAllPrim?$format=json");
+
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.name());
+ connection.setRequestProperty("odata.streaming", "true");
+ connection.connect();
+
+ assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode());
+ assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE)));
+
+ final String content = IOUtils.toString(connection.getInputStream());
+
+ assertTrue(content.contains("\"PropertyString\":\"First Resource - positive values->streamed\""));
+ assertTrue(content.contains("\"PropertyString\":\"Second Resource - negative values->streamed\""));
+ assertTrue(content.contains("\"PropertyString\":\"->streamed\""));
+ }
+
+
+ @Override
+ protected ODataClient getClient() {
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/09fd6d9b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java
index abc500a..3132876 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java
@@ -18,8 +18,13 @@
*/
package org.apache.olingo.server.api;
+import java.io.OutputStream;
import java.nio.channels.WritableByteChannel;
+/**
+ * The WriteContentErrorCallback is called when during the {@link ODataContent#write(OutputStream)}
+ * or the {@link ODataContent#write(WritableByteChannel)} an error occurs.
+ */
public interface WriteContentErrorCallback {
void handleError(WriteContentErrorContext context, WritableByteChannel channel);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/09fd6d9b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorContext.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorContext.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorContext.java
index d773df1..837c184 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorContext.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorContext.java
@@ -18,8 +18,10 @@
*/
package org.apache.olingo.server.api;
+/**
+ * The WriteContentErrorErrorContext is the parameter for the WriteContentErrorCallback.
+ */
public interface WriteContentErrorContext {
Exception getException();
ODataLibraryException getODataLibraryException();
-// Object getParameter(String name);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/09fd6d9b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataWritableContent.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataWritableContent.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataWritableContent.java
index 904a6d0..7a7c142 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataWritableContent.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataWritableContent.java
@@ -20,15 +20,9 @@ package org.apache.olingo.server.core;
import java.io.IOException;
import java.io.OutputStream;
-import java.nio.ByteBuffer;
import java.nio.channels.Channels;
-import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.Map;
-import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityIterator;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
@@ -38,82 +32,60 @@ import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.WriteContentErrorCallback;
import org.apache.olingo.server.api.WriteContentErrorContext;
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.serializer.SerializerStreamResult;
import org.apache.olingo.server.core.serializer.SerializerStreamResultImpl;
import org.apache.olingo.server.core.serializer.json.ODataJsonSerializer;
-import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
-
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonGenerator;
+import org.apache.olingo.server.core.serializer.xml.ODataXmlSerializer;
public class ODataWritableContent implements ODataContent {
- private StreamChannel channel;
-
- private static class StreamChannel implements ReadableByteChannel {
- private static final Charset DEFAULT = Charset.forName("UTF-8");
- private ByteBuffer head;
- private ByteBuffer tail;
- private ODataJsonSerializer jsonSerializer;
- private EntityIterator coll;
- private ServiceMetadata metadata;
- private EdmEntityType entityType;
- private EntityCollectionSerializerOptions options;
-
- public StreamChannel(EntityIterator coll, EdmEntityType entityType, String head,
- ODataJsonSerializer jsonSerializer, ServiceMetadata metadata,
- EntityCollectionSerializerOptions options, String tail) {
- this.coll = coll;
+ private StreamContent streamContent;
+
+ private static abstract class StreamContent {
+ protected ODataSerializer serializer;
+ protected EntityIterator iterator;
+ protected ServiceMetadata metadata;
+ protected EdmEntityType entityType;
+ protected EntityCollectionSerializerOptions options;
+
+ public StreamContent(EntityIterator iterator, EdmEntityType entityType,
+ ODataSerializer serializer, ServiceMetadata metadata,
+ EntityCollectionSerializerOptions options) {
+ this.iterator = iterator;
this.entityType = entityType;
- this.head = head == null ? ByteBuffer.allocate(0) : ByteBuffer.wrap(head.getBytes(DEFAULT));
- this.jsonSerializer = jsonSerializer;
+ this.serializer = serializer;
this.metadata = metadata;
this.options = options;
- this.tail = tail == null ? ByteBuffer.allocate(0) : ByteBuffer.wrap(tail.getBytes(DEFAULT));
}
-// public boolean write(OutputStream out) throws IOException {
-// if(head.hasRemaining()) {
-// out.write(head.array());
-// head.flip();
-// return true;
-// }
-// if (coll.hasNext()) {
-// try {
-// writeEntity(coll.next(), out);
-// if(coll.hasNext()) {
-// out.write(",".getBytes(DEFAULT));
-// }
-// return true;
-// } catch (SerializerException e) {
-// final WriteContentErrorCallback errorCallback = options.getWriteContentErrorCallback();
-// if(errorCallback != null) {
-// final ErrorContext errorContext = new ErrorContext(e).setParameter("Sample", "Some exception happened.");
-// errorCallback.handleError(errorContext, Channels.newChannel(out));
-// }
-// }
-// } else if(tail.hasRemaining()) {
-// out.write(tail.array());
-// tail.flip();
-// return true;
-// }
-// return false;
-// }
+ protected abstract void writeEntity(EntityIterator entity, OutputStream outputStream) throws SerializerException;
public void write(OutputStream out) {
try {
- writeEntity(coll, out);
+ writeEntity(iterator, out);
} catch (SerializerException e) {
final WriteContentErrorCallback errorCallback = options.getWriteContentErrorCallback();
if(errorCallback != null) {
- final ErrorContext errorContext = new ErrorContext(e).setParameter("Sample", "Some exception happened.");
+ final ErrorContext errorContext = new ErrorContext(e);
errorCallback.handleError(errorContext, Channels.newChannel(out));
}
}
}
+ }
+
+ private static class StreamContentForJson extends StreamContent {
+ private ODataJsonSerializer jsonSerializer;
+ public StreamContentForJson(EntityIterator iterator, EdmEntityType entityType,
+ ODataJsonSerializer jsonSerializer, ServiceMetadata metadata,
+ EntityCollectionSerializerOptions options) {
+ super(iterator, entityType, jsonSerializer, metadata, options);
- private void writeEntity(EntityIterator entity, OutputStream outputStream) throws SerializerException {
+ this.jsonSerializer = jsonSerializer;
+ }
+
+ protected void writeEntity(EntityIterator entity, OutputStream outputStream) throws SerializerException {
try {
jsonSerializer.entityCollectionIntoStream(metadata, entityType, entity, options, outputStream);
outputStream.flush();
@@ -121,97 +93,32 @@ public class ODataWritableContent implements ODataContent {
throw new ODataRuntimeException("Failed entity serialization");
}
}
+ }
- @Override
- public int read(ByteBuffer dest) throws IOException {
- ByteBuffer buffer = getCurrentBuffer();
- if (buffer != null && buffer.hasRemaining()) {
- int r = buffer.remaining();
- if(r <= dest.remaining()) {
- dest.put(buffer);
- } else {
- r = dest.remaining();
- byte[] buf = new byte[dest.remaining()];
- buffer.get(buf);
- dest.put(buf);
- }
- return r;
- }
- return -1;
- }
+ private static class StreamContentForXml extends StreamContent {
+ private ODataXmlSerializer xmlSerializer;
- ByteBuffer currentBuffer;
+ public StreamContentForXml(EntityIterator iterator, EdmEntityType entityType,
+ ODataXmlSerializer xmlSerializer, ServiceMetadata metadata,
+ EntityCollectionSerializerOptions options) {
+ super(iterator, entityType, xmlSerializer, metadata, options);
- private ByteBuffer getCurrentBuffer() {
- if(currentBuffer == null) {
- currentBuffer = head;
- }
- if(!currentBuffer.hasRemaining()) {
- if (coll.hasNext()) {
- try {
- // FIXME: mibo_160108: Inefficient buffer handling, replace
- currentBuffer = serEntity(coll.next());
- if(coll.hasNext()) {
- ByteBuffer b = ByteBuffer.allocate(currentBuffer.position() + 1);
- currentBuffer.flip();
- b.put(currentBuffer).put(",".getBytes(DEFAULT));
- currentBuffer = b;
- }
- currentBuffer.flip();
- } catch (SerializerException e) {
- return getCurrentBuffer();
- }
- } else if(tail.hasRemaining()) {
- currentBuffer = tail;
- } else {
- return null;
- }
- }
- return currentBuffer;
+ this.xmlSerializer = xmlSerializer;
}
- private ByteBuffer serEntity(Entity entity) throws SerializerException {
+ protected void writeEntity(EntityIterator entity, OutputStream outputStream) 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.getBuffer();
+ xmlSerializer.entityCollectionIntoStream(metadata, entityType, entity, options, outputStream);
+ outputStream.flush();
} catch (final IOException e) {
- return ByteBuffer.wrap(("ERROR" + e.getMessage()).getBytes());
+ throw new ODataRuntimeException("Failed entity serialization");
}
}
-
-
- @Override
- public boolean isOpen() {
- return false;
- }
-
- @Override
- public void close() throws IOException {
-
- }
- }
-
- public ReadableByteChannel getChannel() {
- return this.channel;
- }
-
- public boolean isWriteSupported() {
- return true;
}
@Override
public void write(WritableByteChannel writeChannel) {
- this.channel.write(Channels.newOutputStream(writeChannel));
+ this.streamContent.write(Channels.newOutputStream(writeChannel));
}
@Override
@@ -219,20 +126,18 @@ public class ODataWritableContent implements ODataContent {
write(Channels.newChannel(stream));
}
- private ODataWritableContent(StreamChannel channel) {
- this.channel = channel;
+ private ODataWritableContent(StreamContent streamContent) {
+ this.streamContent = streamContent;
}
- public static ODataWritableContentBuilder with(EntityIterator coll, EdmEntityType entityType,
- ODataJsonSerializer jsonSerializer,
- ServiceMetadata metadata, EntityCollectionSerializerOptions options) {
- return new ODataWritableContentBuilder(coll, entityType, jsonSerializer, metadata, options);
+ public static ODataWritableContentBuilder with(EntityIterator iterator, EdmEntityType entityType,
+ ODataSerializer serializer, ServiceMetadata metadata,
+ EntityCollectionSerializerOptions options) {
+ return new ODataWritableContentBuilder(iterator, entityType, serializer, metadata, options);
}
public static class ErrorContext implements WriteContentErrorContext {
private ODataLibraryException exception;
- final private Map<String, Object> parameters = new HashMap<String, Object>();
-
public ErrorContext(ODataLibraryException exception) {
this.exception = exception;
}
@@ -245,50 +150,36 @@ public class ODataWritableContent implements ODataContent {
public ODataLibraryException getODataLibraryException() {
return exception;
}
-
- public ErrorContext setParameter(String name, Object value) {
- parameters.put(name, value);
- return this;
- }
-
-// @Override
- public Object getParameter(String name) {
- return parameters.get(name);
- }
}
public static class ODataWritableContentBuilder {
- private ODataJsonSerializer jsonSerializer;
+ private ODataSerializer serializer;
private EntityIterator entities;
private ServiceMetadata metadata;
private EdmEntityType entityType;
private EntityCollectionSerializerOptions options;
- private String head;
- private String tail;
public ODataWritableContentBuilder(EntityIterator entities, EdmEntityType entityType,
- ODataJsonSerializer jsonSerializer,
+ ODataSerializer serializer,
ServiceMetadata metadata, EntityCollectionSerializerOptions options) {
this.entities = entities;
this.entityType = entityType;
- this.jsonSerializer = jsonSerializer;
+ this.serializer = serializer;
this.metadata = metadata;
this.options = options;
}
- public ODataWritableContentBuilder addHead(String head) {
- this.head = head;
- return this;
- }
-
- public ODataWritableContentBuilder addTail(String tail) {
- this.tail = tail;
- return this;
- }
-
public ODataContent buildContent() {
- StreamChannel input = new StreamChannel(entities, entityType, head, jsonSerializer, metadata, options, tail);
- return new ODataWritableContent(input);
+ if(serializer instanceof ODataJsonSerializer) {
+ StreamContent input = new StreamContentForJson(entities, entityType,
+ (ODataJsonSerializer) serializer, metadata, options);
+ return new ODataWritableContent(input);
+ } else if(serializer instanceof ODataXmlSerializer) {
+ StreamContentForXml input = new StreamContentForXml(entities, entityType,
+ (ODataXmlSerializer) serializer, metadata, options);
+ return new ODataWritableContent(input);
+ }
+ throw new ODataRuntimeException("No suitable serializer found");
}
public SerializerStreamResult build() {
return SerializerStreamResultImpl.with().content(buildContent()).build();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/09fd6d9b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerStreamResultImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerStreamResultImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerStreamResultImpl.java
index 14fab97..a7c0efc 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerStreamResultImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerStreamResultImpl.java
@@ -18,14 +18,10 @@
*/
package org.apache.olingo.server.core.serializer;
-import java.io.InputStream;
-
import org.apache.olingo.server.api.ODataContent;
-import org.apache.olingo.server.api.serializer.SerializerResult;
import org.apache.olingo.server.api.serializer.SerializerStreamResult;
public class SerializerStreamResultImpl implements SerializerStreamResult {
- private InputStream content;
private ODataContent oDataContent;
@Override
@@ -33,21 +29,6 @@ public class SerializerStreamResultImpl implements SerializerStreamResult {
return oDataContent;
}
- // @Override
-// public ReadableByteChannel getChannel() {
-// return Channels.newChannel(getContent());
-// }
-//
-// @Override
-// public void write(WritableByteChannel channel) {
-// ResultHelper.copy(Channels.newChannel(content), channel);
-// }
-//
-// @Override
-// public boolean isWriteSupported() {
-// return false;
-// }
-
public static SerializerResultBuilder with() {
return new SerializerResultBuilder();
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/09fd6d9b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
index a42e3df..2fa16ea 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
@@ -70,6 +70,7 @@ import org.apache.olingo.server.api.serializer.SerializerStreamResult;
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.ODataWritableContent;
import org.apache.olingo.server.core.serializer.AbstractODataSerializer;
import org.apache.olingo.server.core.serializer.SerializerResultImpl;
import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
@@ -282,10 +283,67 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
}
}
+ public void entityCollectionIntoStream(ServiceMetadata metadata, EdmEntityType entityType, EntityIterator entitySet,
+ EntityCollectionSerializerOptions options, OutputStream outputStream) throws SerializerException {
+
+ final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
+// if (options != null && options.getWriteOnlyReferences()) {
+// ReferenceCollectionSerializerOptions rso = ReferenceCollectionSerializerOptions.with()
+// .contextURL(contextURL).build();
+// return entityReferenceCollection(entitySet, rso);
+// }
+
+ SerializerException cachedException = null;
+ try {
+ CircleStreamBuffer buffer = new CircleStreamBuffer();
+ outputStream = buffer.getOutputStream();
+ XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream, DEFAULT_CHARSET);
+ writer.writeStartDocument(DEFAULT_CHARSET, "1.0");
+ writer.writeStartElement(ATOM, Constants.ATOM_ELEM_FEED, NS_ATOM);
+ writer.writeNamespace(ATOM, NS_ATOM);
+ writer.writeNamespace(METADATA, NS_METADATA);
+ writer.writeNamespace(DATA, NS_DATA);
+
+ writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT,
+ ContextURLBuilder.create(contextURL).toASCIIString());
+ writeMetadataETag(metadata, writer);
+
+ if (options != null && options.getId() != null) {
+ writer.writeStartElement(ATOM, Constants.ATOM_ELEM_ID, NS_ATOM);
+ writer.writeCharacters(options.getId());
+ writer.writeEndElement();
+ }
+
+ if (options != null && options.getCount() != null && options.getCount().getValue()
+ && entitySet.getCount() != null) {
+ writeCount(entitySet, writer);
+ }
+ if (entitySet.getNext() != null) {
+ writeNextLink(entitySet, writer);
+ }
+
+ if (options == null) {
+ writeEntitySet(metadata, entityType, entitySet, null, null, null, writer);
+ } else {
+ writeEntitySet(metadata, entityType, entitySet,
+ options.getExpand(), options.getSelect(), options.xml10InvalidCharReplacement(), writer);
+ }
+
+ writer.writeEndElement();
+ writer.writeEndDocument();
+
+ writer.flush();
+ } catch (final XMLStreamException e) {
+ cachedException =
+ new SerializerException(IO_EXCEPTION_TEXT, e, SerializerException.MessageKeys.IO_EXCEPTION);
+ throw cachedException;
+ }
+ }
+
@Override
public SerializerStreamResult entityCollectionStreamed(ServiceMetadata metadata, EdmEntityType entityType,
EntityIterator entities, EntityCollectionSerializerOptions options) throws SerializerException {
- throw new ODataRuntimeException("entityCollectionStreamed for XML not supported (yet)");
+ return ODataWritableContent.with(entities, entityType, this, metadata, options).build();
}
@Override
@@ -1163,5 +1221,5 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
return value;
}
return result.toString();
- }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/09fd6d9b/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 28989d6..850867e 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
@@ -19,6 +19,7 @@
package org.apache.olingo.server.tecsvc.processor;
import java.util.Iterator;
+import java.util.List;
import java.util.Locale;
import org.apache.olingo.commons.api.data.ContextURL;
@@ -27,6 +28,8 @@ 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.EntityIterator;
+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;
@@ -526,13 +529,19 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
final SerializerResult serializerResult =
serializeReferenceCollection(entitySetSerialization, edmEntitySet, requestedContentType, countOption);
response.setContent(serializerResult.getContent());
- } else {
+ } else if(isOdataStreaming(request)) {
final SerializerStreamResult serializerResult =
serializeEntityCollectionStreamed(request,
entitySetSerialization, edmEntitySet, edmEntityType, requestedContentType,
expand, select, countOption, id);
response.setODataContent(serializerResult.getODataContent());
+ } else {
+ final SerializerResult serializerResult =
+ serializeEntityCollection(request,
+ entitySetSerialization, edmEntitySet, edmEntityType, requestedContentType,
+ expand, select, countOption, id);
+ response.setContent(serializerResult.getContent());
}
//
@@ -544,6 +553,29 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
}
}
+ private boolean isOdataStreaming(ODataRequest request) {
+ String odataStreaming = request.getHeader("odata.streaming");
+ return Boolean.parseBoolean(odataStreaming);
+ }
+
+ private SerializerResult serializeEntityCollection(final ODataRequest request, final EntityCollection
+ entityCollection, final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
+ final ContentType requestedFormat, final ExpandOption expand, final SelectOption select,
+ final CountOption countOption, String id) throws ODataLibraryException {
+
+ return odata.createSerializer(requestedFormat).entityCollection(
+ serviceMetadata,
+ edmEntityType,
+ entityCollection,
+ EntityCollectionSerializerOptions.with()
+ .contextURL(isODataMetadataNone(requestedFormat) ? null :
+ getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, false, expand, select))
+ .count(countOption)
+ .expand(expand).select(select)
+ .id(id)
+ .build());
+ }
+
// serialise as streamed collection
private SerializerStreamResult serializeEntityCollectionStreamed(final ODataRequest request,
final EntityCollection entityCollection, final EdmEntitySet edmEntitySet,
@@ -561,7 +593,23 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
@Override
public Entity next() {
- return entityIterator.next();
+ return addToPrimitiveProperty(entityIterator.next(), "PropertyString", "->streamed");
+ }
+
+ private Entity addToPrimitiveProperty(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);
+ final String old = property.getValue().toString();
+ String newValue = (old == null ? "": old) + data.toString();
+ entity.addProperty(new Property(null, name, ValueType.PRIMITIVE, newValue));
+ break;
+ }
+ pos++;
+ }
+ return entity;
}
};