[OLINGO-832] New ODataContent for streamed and basic content
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/31dea712 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/31dea712 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/31dea712 Branch: refs/heads/OLINGO-856_ODataHandlerInAPI Commit: 31dea712ef703672a20e650b8185855f1af8b4a2 Parents: 18a7898 Author: mibo <[email protected]> Authored: Mon Feb 8 15:25:45 2016 +0100 Committer: mibo <[email protected]> Committed: Mon Feb 8 16:06:01 2016 +0100 ---------------------------------------------------------------------- .../apache/olingo/server/api/ODataContent.java | 32 ++++ .../apache/olingo/server/api/ODataResponse.java | 11 +- .../server/api/WriteContentErrorCallback.java | 25 +++ .../server/api/serializer/SerializerResult.java | 8 +- .../server/core/ODataHttpHandlerImpl.java | 17 +- .../serializer/ChannelSerializerResult.java | 26 ++- .../core/serializer/SerializerResultImpl.java | 40 ++-- .../core/serializer/StreamSerializerResult.java | 187 ------------------- .../processor/TechnicalEntityProcessor.java | 2 +- 9 files changed, 118 insertions(+), 230 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/31dea712/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataContent.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataContent.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataContent.java new file mode 100644 index 0000000..a3147f6 --- /dev/null +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataContent.java @@ -0,0 +1,32 @@ +/* + * 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.api; + +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; + +public interface ODataContent { + ReadableByteChannel getChannel(); + + void write(WritableByteChannel channel); + + void write(WritableByteChannel channel, WriteContentErrorCallback callback); + + boolean isWriteSupported(); +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/31dea712/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java index 5e2bad6..39c9452 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java @@ -19,7 +19,6 @@ package org.apache.olingo.server.api; import org.apache.olingo.commons.api.http.HttpStatusCode; -import org.apache.olingo.server.api.serializer.SerializerResult; import java.io.InputStream; import java.util.List; @@ -132,13 +131,13 @@ public class ODataResponse { return content; } - private SerializerResult serializerResult; + private ODataContent odataContent; - public void setSerializerResult(SerializerResult result) { - serializerResult = result; + public void setODataContent(ODataContent result) { + odataContent = result; } - public SerializerResult getSerializerResult() { - return serializerResult; + public ODataContent getODataContent() { + return odataContent; } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/31dea712/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 new file mode 100644 index 0000000..4219b8f --- /dev/null +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/WriteContentErrorCallback.java @@ -0,0 +1,25 @@ +/* + * 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.api; + +import java.nio.channels.WritableByteChannel; + +public interface WriteContentErrorCallback { + void handleError(ODataContent content, WritableByteChannel channel); +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/31dea712/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerResult.java ---------------------------------------------------------------------- diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerResult.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerResult.java index d1e76e4..c3206d6 100644 --- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerResult.java +++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerResult.java @@ -18,6 +18,8 @@ */ package org.apache.olingo.server.api.serializer; +import org.apache.olingo.server.api.ODataContent; + import java.io.InputStream; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; @@ -32,9 +34,5 @@ public interface SerializerResult { */ InputStream getContent(); - ReadableByteChannel getChannel(); - - void writeContent(WritableByteChannel channel); - - boolean isWriteSupported(); + ODataContent getODataContent(); } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/31dea712/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java index 418234f..dfd4a75 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java @@ -20,7 +20,6 @@ package org.apache.olingo.server.core; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.Channel; import java.nio.channels.Channels; @@ -40,6 +39,7 @@ import org.apache.olingo.commons.api.ex.ODataRuntimeException; import org.apache.olingo.commons.api.http.HttpHeader; import org.apache.olingo.commons.api.http.HttpMethod; import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataContent; import org.apache.olingo.server.api.ODataHttpHandler; import org.apache.olingo.server.api.ODataLibraryException; import org.apache.olingo.server.api.ODataRequest; @@ -51,7 +51,6 @@ import org.apache.olingo.server.api.deserializer.DeserializerException; import org.apache.olingo.server.api.etag.CustomETagSupport; import org.apache.olingo.server.api.processor.Processor; import org.apache.olingo.server.api.serializer.CustomContentTypeSupport; -import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.core.debug.ServerCoreDebugger; public class ODataHttpHandlerImpl implements ODataHttpHandler { @@ -154,18 +153,18 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { if (odResponse.getContent() != null ) { copyContent(odResponse.getContent(), response); - } else if(odResponse.getSerializerResult() != null) { + } else if(odResponse.getODataContent() != null) { writeContent(odResponse, response); } } static void writeContent(final ODataResponse odataResponse, final HttpServletResponse servletResponse) { try { - SerializerResult res = odataResponse.getSerializerResult(); + ODataContent res = odataResponse.getODataContent(); if(res.isWriteSupported()) { - res.writeContent(Channels.newChannel(servletResponse.getOutputStream())); + res.write(Channels.newChannel(servletResponse.getOutputStream())); } else { - copyContent(res.getContent(), servletResponse); + copyContent(res.getChannel(), servletResponse); } } catch (IOException e) { throw new ODataRuntimeException("Error on reading request content", e); @@ -173,12 +172,14 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler { } static void copyContent(final InputStream inputStream, final HttpServletResponse servletResponse) { - ReadableByteChannel input = null; + copyContent(Channels.newChannel(inputStream), servletResponse); + } + + static void copyContent(final ReadableByteChannel input, final HttpServletResponse servletResponse) { WritableByteChannel output = null; try { ByteBuffer inBuffer = ByteBuffer.allocate(COPY_BUFFER_SIZE); output = Channels.newChannel(servletResponse.getOutputStream()); - input = Channels.newChannel(inputStream); while (input.read(inBuffer) > 0) { inBuffer.flip(); output.write(inBuffer); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/31dea712/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ChannelSerializerResult.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ChannelSerializerResult.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ChannelSerializerResult.java index 1b48814..1e97731 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ChannelSerializerResult.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ChannelSerializerResult.java @@ -24,7 +24,9 @@ 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; +import org.apache.olingo.server.api.ODataContent; import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.WriteContentErrorCallback; import org.apache.olingo.server.api.serializer.EntitySerializerOptions; import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; @@ -40,7 +42,7 @@ import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.nio.charset.Charset; -public class ChannelSerializerResult implements SerializerResult { +public class ChannelSerializerResult implements ODataContent { private StreamChannel channel; private static class StreamChannel implements ReadableByteChannel { @@ -182,10 +184,10 @@ public class ChannelSerializerResult implements SerializerResult { } } - @Override - public InputStream getContent() { - return Channels.newInputStream(this.channel); - } +// @Override +// public InputStream getContent() { +// return Channels.newInputStream(this.channel); +// } @Override public ReadableByteChannel getChannel() { @@ -198,7 +200,7 @@ public class ChannelSerializerResult implements SerializerResult { } @Override - public void writeContent(WritableByteChannel writeChannel) { + public void write(WritableByteChannel writeChannel) { try { boolean contentAvailable = true; while(contentAvailable) { @@ -209,6 +211,12 @@ public class ChannelSerializerResult implements SerializerResult { } } + @Override + public void write(WritableByteChannel channel, WriteContentErrorCallback callback) { + // TODO: implement error handling + throw new ODataRuntimeException("error handling not yet supported"); + } + private ChannelSerializerResult(StreamChannel channel) { this.channel = channel; } @@ -248,9 +256,13 @@ public class ChannelSerializerResult implements SerializerResult { return this; } - public SerializerResult build() { + public ODataContent buildContent() { StreamChannel input = new StreamChannel(coll, entityType, head, jsonSerializer, metadata, options, tail); return new ChannelSerializerResult(input); } + public SerializerResult build() { + StreamChannel input = new StreamChannel(coll, entityType, head, jsonSerializer, metadata, options, tail); + return SerializerResultImpl.with().content(new ChannelSerializerResult(input)).build(); + } } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/31dea712/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerResultImpl.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerResultImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerResultImpl.java index 4adc142..310cc5d 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerResultImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/SerializerResultImpl.java @@ -18,6 +18,7 @@ */ package org.apache.olingo.server.core.serializer; +import org.apache.olingo.server.api.ODataContent; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.core.serializer.utils.ResultHelper; @@ -28,6 +29,7 @@ import java.nio.channels.WritableByteChannel; public class SerializerResultImpl implements SerializerResult { private InputStream content; + private ODataContent oDataContent; @Override public InputStream getContent() { @@ -35,37 +37,43 @@ public class SerializerResultImpl implements SerializerResult { } @Override - public ReadableByteChannel getChannel() { - return Channels.newChannel(getContent()); + public ODataContent getODataContent() { + return oDataContent; } - @Override - public void writeContent(WritableByteChannel channel) { - ResultHelper.copy(Channels.newChannel(content), channel); - } - - @Override - public boolean isWriteSupported() { - return false; - } + // @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(); } public static class SerializerResultBuilder { - private InputStream content; + private SerializerResultImpl result = new SerializerResultImpl(); public SerializerResultBuilder content(final InputStream input) { - content = input; + result.content = input; + return this; + } + public SerializerResultBuilder content(final ODataContent input) { + result.oDataContent = input; return this; } public SerializerResult build() { - SerializerResultImpl result = new SerializerResultImpl(); - result.content = content; - return result; } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/31dea712/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 deleted file mode 100644 index 9a9283f..0000000 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/StreamSerializerResult.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.olingo.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.EntityIterator; -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 org.apache.olingo.server.core.serializer.utils.ResultHelper; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.WritableByteChannel; - -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 EntityIterator coll; - private ServiceMetadata metadata; - private EdmEntityType entityType; - private EntitySerializerOptions options; - - public StreamInputStream(EntityIterator 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.next()); - 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; - } - - @Override - public ReadableByteChannel getChannel() { - return Channels.newChannel(getContent()); - } - - @Override - public void writeContent(WritableByteChannel channel) { - ResultHelper.copy(getChannel(), channel); - } - - @Override - public boolean isWriteSupported() { - return true; - } - - private StreamSerializerResult(InputStream content) { - this.content = content; - } - - public static SerializerResultBuilder with(EntityIterator 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 EntityIterator coll; - private ServiceMetadata metadata; - private EdmEntityType entityType; - private EntitySerializerOptions options; - private String head; - private String tail; - - public SerializerResultBuilder(EntityIterator 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/31dea712/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 4987ba3..2c3c766 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 @@ -541,7 +541,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor // } else { // response.setContent(serializerResult.getContent()); // } - response.setSerializerResult(serializerResult); + response.setODataContent(serializerResult.getODataContent()); // response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
