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 2015/07/10 10:48:10 UTC

[1/5] olingo-odata4 git commit: [OLINGO-729] Better support of RFC1341 Multipart for

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 4baaf0d0b -> b484f7f64


[OLINGO-729] Better support of RFC1341 Multipart for


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

Branch: refs/heads/master
Commit: 925a86d963332a98b0fd891acad5933ea9b26f09
Parents: 3a103d5
Author: Michael Bolz <mi...@sap.com>
Authored: Tue Jul 7 22:43:18 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Tue Jul 7 22:43:18 2015 +0200

----------------------------------------------------------------------
 .../core/deserializer/batch/BatchParser.java    |   3 +-
 .../BufferedReaderIncludingLineEndings.java     | 102 ++++++----
 .../serializer/BatchResponseSerializer.java     | 153 +++++++++++----
 .../batchhandler/MockedBatchHandlerTest.java    |   9 +-
 .../BufferedReaderIncludingLineEndingsTest.java | 196 ++++---------------
 .../serializer/BatchResponseSerializerTest.java | 123 +++++++++++-
 6 files changed, 340 insertions(+), 246 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/925a86d9/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchParser.java
index 5d251ec..731437a 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchParser.java
@@ -20,7 +20,6 @@ package org.apache.olingo.server.core.deserializer.batch;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -74,7 +73,7 @@ public class BatchParser {
 
   private List<List<Line>> splitBodyParts(final InputStream in, final String boundary) throws IOException,
       BatchDeserializerException {
-    final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
+    final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(in);
     final List<Line> message = reader.toLineList();
     reader.close();
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/925a86d9/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndings.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndings.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndings.java
index 2268a1d..a36b86b 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndings.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndings.java
@@ -18,37 +18,41 @@
  */
 package org.apache.olingo.server.core.deserializer.batch;
 
+import org.apache.olingo.commons.api.format.ContentType;
+
 import java.io.IOException;
-import java.io.Reader;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 
-public class BufferedReaderIncludingLineEndings extends Reader {
-  private static final char CR = '\r';
-  private static final char LF = '\n';
+public class BufferedReaderIncludingLineEndings {
+  private static final byte CR = '\r';
+  private static final byte LF = '\n';
   private static final int EOF = -1;
   private static final int BUFFER_SIZE = 8192;
-  private Reader reader;
-  private char[] buffer;
+  public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
+  private InputStream reader;
+  private byte[] buffer;
   private int offset = 0;
   private int limit = 0;
 
-  public BufferedReaderIncludingLineEndings(final Reader reader) {
+  public BufferedReaderIncludingLineEndings(final InputStream reader) {
     this(reader, BUFFER_SIZE);
   }
 
-  public BufferedReaderIncludingLineEndings(final Reader reader, final int bufferSize) {
+  public BufferedReaderIncludingLineEndings(final InputStream reader, final int bufferSize) {
     if (bufferSize <= 0) {
       throw new IllegalArgumentException("Buffer size must be greater than zero.");
     }
 
     this.reader = reader;
-    buffer = new char[bufferSize];
+    buffer = new byte[bufferSize];
   }
 
-  @Override
-  public int read(final char[] charBuffer, final int bufferOffset, final int length) throws IOException {
-    if ((bufferOffset + length) > charBuffer.length) {
+  public int read(final byte[] byteBuffer, final int bufferOffset, final int length) throws IOException {
+    if ((bufferOffset + length) > byteBuffer.length) {
       throw new IndexOutOfBoundsException("Buffer is too small");
     }
 
@@ -86,7 +90,7 @@ public class BufferedReaderIncludingLineEndings extends Reader {
         bytesToRead -= readByte;
 
         for (int i = 0; i < readByte; i++) {
-          charBuffer[currentOutputOffset++] = buffer[offset++];
+          byteBuffer[currentOutputOffset++] = buffer[offset++];
         }
       }
     }
@@ -105,6 +109,27 @@ public class BufferedReaderIncludingLineEndings extends Reader {
     return result;
   }
 
+  private Charset currentCharset = DEFAULT_CHARSET;
+
+  private void updateCurrentCharset(String currentLine) {
+    if(currentLine != null) {
+      if(currentLine.startsWith("Content-Type:") && currentLine.contains(ContentType.PARAMETER_CHARSET)) {
+        currentLine = currentLine.substring(13, currentLine.length()-2).trim();
+        ContentType t = ContentType.parse(currentLine);
+        if(t != null) {
+          String charsetString = t.getParameter(ContentType.PARAMETER_CHARSET);
+          currentCharset = Charset.forName(charsetString);
+        }
+      } else if(isEndBoundary(currentLine)) {
+        currentCharset = Charset.forName("us-ascii");
+      }
+    }
+  }
+
+  private boolean isEndBoundary(String currentLine) {
+    return false;
+  }
+
   public List<Line> toLineList() throws IOException {
     final List<Line> result = new ArrayList<Line>();
     String currentLine;
@@ -122,7 +147,7 @@ public class BufferedReaderIncludingLineEndings extends Reader {
       return null;
     }
 
-    final StringBuilder stringBuffer = new StringBuilder();
+    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
     boolean foundLineEnd = false; // EOF will be considered as line ending
 
     while (!foundLineEnd) {
@@ -134,8 +159,14 @@ public class BufferedReaderIncludingLineEndings extends Reader {
       }
 
       if (!foundLineEnd) {
-        char currentChar = buffer[offset++];
-        stringBuffer.append(currentChar);
+        byte currentChar = this.buffer[offset++];
+        if(!buffer.hasRemaining()) {
+          buffer.flip();
+          ByteBuffer tmp = ByteBuffer.allocate(buffer.limit() *2);
+          tmp.put(buffer);
+          buffer = tmp;
+        }
+        buffer.put(currentChar);
 
         if (currentChar == LF) {
           foundLineEnd = true;
@@ -149,44 +180,27 @@ public class BufferedReaderIncludingLineEndings extends Reader {
           }
 
           // Check if there is at least one character
-          if (limit != EOF && buffer[offset] == LF) {
-            stringBuffer.append(LF);
+          if (limit != EOF && this.buffer[offset] == LF) {
+            buffer.put(LF);
             offset++;
           }
         }
       }
     }
 
-    return (stringBuffer.length() == 0) ? null : stringBuffer.toString();
+    if(buffer.position() == 0) {
+      return null;
+    } else {
+      String currentLine = new String(buffer.array(), 0, buffer.position(), getCurrentCharset());
+      updateCurrentCharset(currentLine);
+      return currentLine;
+    }
   }
 
-  @Override
   public void close() throws IOException {
     reader.close();
   }
 
-  @Override
-  public boolean ready() throws IOException {
-    // Not EOF and buffer refill is not required
-    return !isEOF() && !(limit == offset);
-  }
-
-  @Override
-  public void reset() throws IOException {
-    throw new IOException("Reset is not supported");
-  }
-
-  @Override
-  public void mark(final int readAheadLimit) throws IOException {
-    throw new IOException("Mark is not supported");
-  }
-
-  @Override
-  public boolean markSupported() {
-    return false;
-  }
-
-  @Override
   public long skip(final long n) throws IOException {
     if (n == 0) {
       return 0;
@@ -230,4 +244,8 @@ public class BufferedReaderIncludingLineEndings extends Reader {
 
     return limit;
   }
+
+  private Charset getCurrentCharset() {
+    return currentCharset;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/925a86d9/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
index 577f083..e277b59 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
@@ -22,11 +22,14 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
 import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.api.http.HttpContentType;
 import org.apache.olingo.commons.api.http.HttpHeader;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
@@ -45,14 +48,14 @@ public class BatchResponseSerializer {
 
   public InputStream serialize(final List<ODataResponsePart> responses, final String boundary)
       throws BatchSerializerException {
-    StringBuilder builder = createBody(responses, boundary);
+    BodyBuilder builder = createBody(responses, boundary);
 
-    return new ByteArrayInputStream(builder.toString().getBytes());
+    return new ByteArrayInputStream(builder.getContent());
   }
 
-  private StringBuilder createBody(final List<ODataResponsePart> batchResponses, final String boundary)
+  private BodyBuilder createBody(final List<ODataResponsePart> batchResponses, final String boundary)
       throws BatchSerializerException {
-    final StringBuilder builder = new StringBuilder();
+    final BodyBuilder builder = new BodyBuilder();
 
     for (final ODataResponsePart part : batchResponses) {
       builder.append(getDashBoundary(boundary));
@@ -68,7 +71,7 @@ public class BatchResponseSerializer {
     return builder;
   }
 
-  private void appendChangeSet(final ODataResponsePart part, final StringBuilder builder)
+  private void appendChangeSet(final ODataResponsePart part, final BodyBuilder builder)
       throws BatchSerializerException {
     final String changeSetBoundary = generateBoundary("changeset");
 
@@ -83,50 +86,27 @@ public class BatchResponseSerializer {
     builder.append(getCloseDelimiter(changeSetBoundary));
   }
 
-  private void appendBodyPart(final ODataResponse response, final StringBuilder builder, final boolean isChangeSet)
+  private void appendBodyPart(final ODataResponse response, final BodyBuilder builder, final boolean isChangeSet)
       throws BatchSerializerException {
-    byte[] body = getBody(response);
 
     appendBodyPartHeader(response, builder, isChangeSet);
     builder.append(CRLF);
 
     appendStatusLine(response, builder);
-    appendResponseHeader(response, body.length, builder);
+    Body body = new Body(response);
+    appendResponseHeader(response, body.getLength(), builder);
     builder.append(CRLF);
 
-    builder.append(new String(body));
+    builder.append(body);
     builder.append(CRLF);
   }
 
-  private byte[] getBody(final ODataResponse response) {
-    final InputStream content = response.getContent();
-    final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-    if (content != null) {
-      byte[] buffer = new byte[BUFFER_SIZE];
-      int n;
-
-      try {
-        while ((n = content.read(buffer, 0, buffer.length)) != -1) {
-          out.write(buffer, 0, n);
-        }
-        out.flush();
-      } catch (IOException e) {
-        throw new ODataRuntimeException(e);
-      }
-
-      return out.toByteArray();
-    } else {
-      return new byte[0];
-    }
-  }
-
-  private void appendChangeSetHeader(final StringBuilder builder, final String changeSetBoundary) {
+  private void appendChangeSetHeader(final BodyBuilder builder, final String changeSetBoundary) {
     appendHeader(HttpHeader.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + "; boundary="
         + changeSetBoundary, builder);
   }
 
-  private void appendHeader(final String name, final String value, final StringBuilder builder) {
+  private void appendHeader(final String name, final String value, final BodyBuilder builder) {
     builder.append(name)
         .append(COLON)
         .append(SP)
@@ -134,7 +114,7 @@ public class BatchResponseSerializer {
         .append(CRLF);
   }
 
-  private void appendStatusLine(final ODataResponse response, final StringBuilder builder) {
+  private void appendStatusLine(final ODataResponse response, final BodyBuilder builder) {
     builder.append("HTTP/1.1")
         .append(SP)
         .append(response.getStatusCode())
@@ -144,7 +124,7 @@ public class BatchResponseSerializer {
   }
 
   private void appendResponseHeader(final ODataResponse response, final int contentLength,
-      final StringBuilder builder) {
+      final BodyBuilder builder) {
     final Map<String, String> header = response.getHeaders();
 
     for (final String key : header.keySet()) {
@@ -157,7 +137,7 @@ public class BatchResponseSerializer {
     appendHeader(HttpHeader.CONTENT_LENGTH, "" + contentLength, builder);
   }
 
-  private void appendBodyPartHeader(final ODataResponse response, final StringBuilder builder,
+  private void appendBodyPartHeader(final ODataResponse response, final BodyBuilder builder,
       final boolean isChangeSet) throws BatchSerializerException {
     appendHeader(HttpHeader.CONTENT_TYPE, HttpContentType.APPLICATION_HTTP, builder);
     appendHeader(BatchParserCommon.CONTENT_TRANSFER_ENCODING, BatchParserCommon.BINARY_ENCODING, builder);
@@ -182,4 +162,103 @@ public class BatchResponseSerializer {
   private String generateBoundary(final String value) {
     return value + "_" + UUID.randomUUID().toString();
   }
+
+  private class BodyBuilder {
+    private final Charset CHARSET_UTF_8 = Charset.forName("utf-8");
+    private ByteBuffer buffer = ByteBuffer.allocate(8192);
+    private boolean isClosed = false;
+
+    public byte[] getContent() {
+      isClosed = true;
+      byte[] tmp = new byte[buffer.position()];
+      buffer.flip();
+      buffer.get(tmp, 0, buffer.limit());
+      return tmp;
+    }
+
+    public BodyBuilder append(String string) {
+      byte [] b = string.getBytes(CHARSET_UTF_8);
+      put(b);
+      return this;
+    }
+
+    private void put(byte[] b) {
+      if(isClosed) {
+        throw new RuntimeException("BodyBuilder is closed.");
+      }
+      if(buffer.remaining() < b.length) {
+        buffer.flip();
+        ByteBuffer tmp = ByteBuffer.allocate(buffer.limit() *2);
+        tmp.put(buffer);
+        buffer = tmp;
+      }
+      buffer.put(b);
+    }
+
+    public BodyBuilder append(int statusCode) {
+      return append(String.valueOf(statusCode));
+    }
+
+    public BodyBuilder append(Body body) {
+      put(body.getContent());
+      return this;
+    }
+
+    public String toString() {
+//      byte[] tmp = new byte[buffer.position()];
+//      buffer.get(tmp, 0, buffer.position());
+      return new String(buffer.array(), 0, buffer.position());
+    }
+  }
+
+  private class Body {
+    private final Charset CHARSET_DEFAULT = Charset.forName("utf-8");
+    private final byte[] content;
+    private Charset charset = CHARSET_DEFAULT;
+
+    public Body(ODataResponse response) {
+      this.content = getBody(response);
+      String contentType = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
+      if(contentType != null) {
+        ContentType ct = ContentType.create(contentType);
+        if(ct != null) {
+          String usedCharset = ct.getParameter(ContentType.PARAMETER_CHARSET);
+          if(usedCharset != null) {
+            this.charset = Charset.forName(usedCharset);
+          }
+        }
+      }
+    }
+
+    public int getLength() {
+      return content.length;
+    }
+
+    private byte[] getBody(final ODataResponse response) {
+      final InputStream content = response.getContent();
+      final ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+      if (content != null) {
+        byte[] buffer = new byte[BUFFER_SIZE];
+        int n;
+
+        try {
+          while ((n = content.read(buffer, 0, buffer.length)) != -1) {
+            out.write(buffer, 0, n);
+          }
+          out.flush();
+        } catch (IOException e) {
+          throw new ODataRuntimeException(e);
+        }
+
+        return out.toByteArray();
+      } else {
+        return new byte[0];
+      }
+    }
+
+    public byte[] getContent() {
+      return content;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/925a86d9/lib/server-core/src/test/java/org/apache/olingo/server/core/batchhandler/MockedBatchHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batchhandler/MockedBatchHandlerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batchhandler/MockedBatchHandlerTest.java
index 47f7b86..3e4e610 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batchhandler/MockedBatchHandlerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batchhandler/MockedBatchHandlerTest.java
@@ -26,7 +26,6 @@ import static org.mockito.Mockito.when;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -150,7 +149,7 @@ public class MockedBatchHandlerTest {
     batchHandler.process(request, response, true);
 
     BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
+        new BufferedReaderIncludingLineEndings(response.getContent());
 
     final List<String> responseContent = reader.toList();
     reader.close();
@@ -221,7 +220,7 @@ public class MockedBatchHandlerTest {
     batchHandler.process(request, response, true);
 
     BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
+        new BufferedReaderIncludingLineEndings(response.getContent());
 
     final List<String> responseContent = reader.toList();
     int line = 0;
@@ -300,7 +299,7 @@ public class MockedBatchHandlerTest {
     batchHandler.process(request, response, true);
 
     BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
+        new BufferedReaderIncludingLineEndings(response.getContent());
 
     final List<String> responseContent = reader.toList();
     reader.close();
@@ -418,7 +417,7 @@ public class MockedBatchHandlerTest {
     batchHandler.process(request, response, true);
 
     BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
+        new BufferedReaderIncludingLineEndings(response.getContent());
 
     final List<String> responseContent = reader.toList();
     reader.close();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/925a86d9/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndingsTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndingsTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndingsTest.java
index 4a41dc6..d0d2fa8 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndingsTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndingsTest.java
@@ -24,7 +24,6 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
-import java.io.InputStreamReader;
 import java.util.List;
 
 import org.junit.Test;
@@ -71,7 +70,7 @@ public class BufferedReaderIncludingLineEndingsTest {
   @Test
   public void testNoBytes() throws Exception {
     BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(new InputStreamReader(new ByteArrayInputStream(new byte[0])));
+        new BufferedReaderIncludingLineEndings(new ByteArrayInputStream(new byte[0]));
 
     assertNull(reader.readLine());
     assertNull(reader.readLine());
@@ -246,7 +245,7 @@ public class BufferedReaderIncludingLineEndingsTest {
   @Test
   public void testReadMoreBufferCapacityThanCharacterAvailable() throws Exception {
     final String TEXT = "Foo";
-    char[] buffer = new char[20];
+    byte[] buffer = new byte[20];
 
     BufferedReaderIncludingLineEndings reader = create(TEXT);
     assertEquals(3, reader.read(buffer, 0, 20));
@@ -274,109 +273,15 @@ public class BufferedReaderIncludingLineEndingsTest {
     reader.close();
   }
 
-  @Test
-  public void testSkipToMuch() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
-
-    assertEquals(8, reader.skip(10)); // Test\r
-    assertEquals(null, reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testReadBufferOne() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL, 1);
-
-    assertEquals('T', reader.read());
-    assertEquals('e', reader.read());
-    assertEquals('s', reader.read());
-    assertEquals('t', reader.read());
-    assertEquals('\r', reader.read());
-    assertEquals('1', reader.read());
-    assertEquals('2', reader.read());
-    assertEquals('3', reader.read());
-    assertEquals(-1, reader.read());
-    assertEquals(-1, reader.read());
-  }
-
-  @Test
-  public void testReadZeroBytes() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL, 1);
-
-    char[] buffer = new char[3];
-    assertEquals(0, reader.read(buffer, 0, 0));
-    assertEquals('T', reader.read());
-    assertEquals(0, reader.read(buffer, 0, 0));
-    assertEquals("est\r", reader.readLine());
-    assertEquals("123", reader.readLine());
-
-    reader.close();
-  }
-
-  @Test
-  public void testRead() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
-
-    assertEquals('T', reader.read());
-    assertEquals('e', reader.read());
-    assertEquals('s', reader.read());
-    assertEquals('t', reader.read());
-    assertEquals('\r', reader.read());
-    assertEquals('1', reader.read());
-    assertEquals('2', reader.read());
-    assertEquals('3', reader.read());
-    assertEquals(-1, reader.read());
-    assertEquals(-1, reader.read());
-  }
-
-  @Test(expected = IndexOutOfBoundsException.class)
-  public void testFailReadBufferAndOffsetBiggerThanBuffer() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create("");
-
-    final char[] buffer = new char[3];
-    reader.read(buffer, 1, 3);
-  }
-
-  @Test(expected = IndexOutOfBoundsException.class)
-  public void testFailLengthNegative() throws Exception {
-    final char[] buffer = new char[3];
-    BufferedReaderIncludingLineEndings reader = create("123");
-
-    reader.read(buffer, 1, -2);
-    reader.close();
-  }
-
-  @Test(expected = IndexOutOfBoundsException.class)
-  public void testFailOffsetNegative() throws Exception {
-    final char[] buffer = new char[3];
-    BufferedReaderIncludingLineEndings reader = create("123");
-
-    reader.read(buffer, -1, 2);
-    reader.close();
-  }
-
-  @Test
-  public void testReadAndReadLine() throws Exception {
-    final String TEXT = "Test\r" +
-        "bar\n" +
-        "123\r\n" +
-        "foo";
-
-    BufferedReaderIncludingLineEndings reader = create(TEXT);
-
-    assertEquals('T', reader.read());
-    assertEquals('e', reader.read());
-    assertEquals('s', reader.read());
-    assertEquals('t', reader.read());
-    assertEquals("\r", reader.readLine());
-    assertEquals("bar\n", reader.readLine());
-    assertEquals('1', reader.read());
-    assertEquals('2', reader.read());
-    assertEquals("3\r\n", reader.readLine());
-    assertEquals("foo", reader.readLine());
-    assertEquals(null, reader.readLine());
-    assertEquals(-1, reader.read());
-  }
+//  @Test
+//  public void testSkipToMuch() throws Exception {
+//    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
+//
+//    assertEquals(8, reader.skip(10)); // Test\r
+//    assertEquals(null, reader.readLine());
+//    reader.close();
+//  }
+//
 
   @Test
   public void testLineEqualsAndHashCode() {
@@ -389,11 +294,11 @@ public class BufferedReaderIncludingLineEndingsTest {
     assertTrue(l1.hashCode() != l3.hashCode());
   }
 
-  @Test(expected = IllegalArgumentException.class)
-  public void testSkipNegative() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create("123");
-    reader.skip(-1);
-  }
+//  @Test(expected = IllegalArgumentException.class)
+//  public void testSkipNegative() throws Exception {
+//    BufferedReaderIncludingLineEndings reader = create("123");
+//    reader.skip(-1);
+//  }
 
   @Test(expected = IllegalArgumentException.class)
   public void testFailBufferSizeZero() throws Exception {
@@ -401,52 +306,33 @@ public class BufferedReaderIncludingLineEndingsTest {
     reader.close();
   }
 
-  @Test(expected = NullPointerException.class)
-  public void testInputStreamIsNull() throws Exception {
-    // Same behaviour like BufferedReader
-    BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(null);
-    reader.close();
-  }
-
   @Test(expected = IllegalArgumentException.class)
   public void testFailBufferSizeNegative() throws Exception {
     BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY, -1);
     reader.close();
   }
 
-  @Test
-  public void testMarkSupoorted() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY);
-
-    assertEquals(false, reader.markSupported());
-    reader.close();
-  }
-
-  @Test(expected = Exception.class)
-  public void testFailMark() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create("123");
-
-    reader.mark(1);
-  }
-
-  @Test(expected = Exception.class)
-  public void testFailReset() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create("123");
-
-    reader.reset();
-  }
-
-  @Test
-  public void testReady() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create("123\r123");
-    assertEquals(false, reader.ready());
-    assertEquals("123\r", reader.readLine());
-    assertEquals(true, reader.ready());
-    assertEquals("123", reader.readLine());
-    assertEquals(false, reader.ready());
-
-    reader.close();
-  }
+//  @Test
+//  public void testMarkSupoorted() throws Exception {
+//    BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY);
+//
+//    assertEquals(false, reader.markSupported());
+//    reader.close();
+//  }
+
+//  @Test(expected = Exception.class)
+//  public void testFailMark() throws Exception {
+//    BufferedReaderIncludingLineEndings reader = create("123");
+//
+//    reader.mark(1);
+//  }
+//
+//  @Test(expected = Exception.class)
+//  public void testFailReset() throws Exception {
+//    BufferedReaderIncludingLineEndings reader = create("123");
+//
+//    reader.reset();
+//  }
 
   @Test
   public void testToList() throws Exception {
@@ -469,13 +355,13 @@ public class BufferedReaderIncludingLineEndingsTest {
   }
 
   private BufferedReaderIncludingLineEndings create(final String inputString) throws Exception {
-    return new BufferedReaderIncludingLineEndings(new InputStreamReader(new ByteArrayInputStream(inputString
-        .getBytes("UTF-8"))));
+    return new BufferedReaderIncludingLineEndings(new ByteArrayInputStream(inputString
+        .getBytes("UTF-8")));
   }
 
   private BufferedReaderIncludingLineEndings create(final String inputString, final int bufferSize) throws Exception {
-    return new BufferedReaderIncludingLineEndings(new InputStreamReader(new ByteArrayInputStream(inputString
-        .getBytes("UTF-8"))), bufferSize);
+    return new BufferedReaderIncludingLineEndings(new ByteArrayInputStream(inputString
+        .getBytes("UTF-8")), bufferSize);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/925a86d9/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
index c5d0653..29d0329 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
@@ -22,8 +22,8 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
@@ -64,7 +64,7 @@ public class BatchResponseSerializerTest {
     final InputStream content = serializer.serialize(parts, BOUNDARY);
     assertNotNull(content);
     final BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(new InputStreamReader(content));
+        new BufferedReaderIncludingLineEndings(content);
     final List<String> body = reader.toList();
     reader.close();
 
@@ -97,6 +97,119 @@ public class BatchResponseSerializerTest {
   }
 
   @Test
+  public void testBatchResponseUmlauteUtf8() throws Exception {
+    final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
+    ODataResponse response = new ODataResponse();
+    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+    response.setHeader(HttpHeader.CONTENT_TYPE,
+            ContentType.APPLICATION_JSON.toContentTypeString() + "; charset=UTF-8");
+    response.setContent(IOUtils.toInputStream("Wälter Winter" + CRLF));
+
+    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+    responses.add(response);
+    parts.add(new ODataResponsePart(responses, false));
+
+    ODataResponse changeSetResponse = new ODataResponse();
+    changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    changeSetResponse.setHeader(HttpHeader.CONTENT_ID, "1");
+    responses = new ArrayList<ODataResponse>(1);
+    responses.add(changeSetResponse);
+    parts.add(new ODataResponsePart(responses, true));
+
+    BatchResponseSerializer serializer = new BatchResponseSerializer();
+    final InputStream content = serializer.serialize(parts, BOUNDARY);
+    assertNotNull(content);
+    final BufferedReaderIncludingLineEndings reader =
+            new BufferedReaderIncludingLineEndings(content);
+    final List<String> body = reader.toList();
+    reader.close();
+
+    int line = 0;
+    assertEquals(24, body.size());
+    assertTrue(body.get(line++).contains("--batch_"));
+    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
+    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals("HTTP/1.1 200 OK" + CRLF, body.get(line++));
+    assertEquals("Content-Type: application/json; charset=UTF-8" + CRLF, body.get(line++));
+    assertEquals("Content-Length: 16" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals("Wälter Winter" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertTrue(body.get(line++).contains("--batch_"));
+    assertTrue(body.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
+    assertEquals(CRLF, body.get(line++));
+    assertTrue(body.get(line++).contains("--changeset_"));
+    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
+    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
+    assertEquals("Content-ID: 1" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals("HTTP/1.1 204 No Content" + CRLF, body.get(line++));
+    assertEquals("Content-Length: 0" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertTrue(body.get(line++).contains("--changeset_"));
+    assertTrue(body.get(line++).contains("--batch_"));
+  }
+
+  @Test
+  public void testBatchResponseUmlauteIso() throws Exception {
+    final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
+    ODataResponse response = new ODataResponse();
+    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+    response.setHeader(HttpHeader.CONTENT_TYPE,
+            ContentType.APPLICATION_JSON.toContentTypeString() + "; charset=iso-8859-1");
+    byte[] payload = ("Wälter Winter" + CRLF).getBytes("iso-8859-1");
+    response.setContent(new ByteArrayInputStream(payload));
+
+    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+    responses.add(response);
+    parts.add(new ODataResponsePart(responses, false));
+
+    ODataResponse changeSetResponse = new ODataResponse();
+    changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    changeSetResponse.setHeader(HttpHeader.CONTENT_ID, "1");
+    responses = new ArrayList<ODataResponse>(1);
+    responses.add(changeSetResponse);
+    parts.add(new ODataResponsePart(responses, true));
+
+    BatchResponseSerializer serializer = new BatchResponseSerializer();
+    final InputStream content = serializer.serialize(parts, BOUNDARY);
+    assertNotNull(content);
+    final BufferedReaderIncludingLineEndings reader =
+            new BufferedReaderIncludingLineEndings(content);
+    final List<String> body = reader.toList();
+    reader.close();
+
+    int line = 0;
+    assertEquals(24, body.size());
+    assertTrue(body.get(line++).contains("--batch_"));
+    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
+    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals("HTTP/1.1 200 OK" + CRLF, body.get(line++));
+    assertEquals("Content-Type: application/json; charset=iso-8859-1" + CRLF, body.get(line++));
+    assertEquals("Content-Length: 15" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals("Wälter Winter" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertTrue(body.get(line++).contains("--batch_"));
+    assertTrue(body.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
+    assertEquals(CRLF, body.get(line++));
+    assertTrue(body.get(line++).contains("--changeset_"));
+    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
+    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
+    assertEquals("Content-ID: 1" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals("HTTP/1.1 204 No Content" + CRLF, body.get(line++));
+    assertEquals("Content-Length: 0" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertTrue(body.get(line++).contains("--changeset_"));
+    assertTrue(body.get(line++).contains("--batch_"));
+  }
+
+  @Test
   public void testBatchResponseWithEndingCRLF() throws Exception {
     final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
     ODataResponse response = new ODataResponse();
@@ -119,7 +232,7 @@ public class BatchResponseSerializerTest {
     final InputStream content = serializer.serialize(parts, BOUNDARY);
     assertNotNull(content);
     final BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(new InputStreamReader(content));
+        new BufferedReaderIncludingLineEndings(content);
     final List<String> body = reader.toList();
     reader.close();
 
@@ -167,7 +280,7 @@ public class BatchResponseSerializerTest {
 
     assertNotNull(content);
     final BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(new InputStreamReader(content));
+        new BufferedReaderIncludingLineEndings(content);
     final List<String> body = reader.toList();
     reader.close();
 
@@ -202,7 +315,7 @@ public class BatchResponseSerializerTest {
     assertNotNull(content);
 
     final BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(new InputStreamReader(content));
+        new BufferedReaderIncludingLineEndings(content);
     final List<String> body = reader.toList();
     reader.close();
 


[5/5] olingo-odata4 git commit: [OLINGO-729] More tests and clean up

Posted by mi...@apache.org.
[OLINGO-729] More tests and clean up


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

Branch: refs/heads/master
Commit: b484f7f64809fd62a0cfc7cf5cd98eb2f0f1abe6
Parents: 594ad4a
Author: Michael Bolz <mi...@sap.com>
Authored: Fri Jul 10 09:27:56 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Fri Jul 10 09:39:25 2015 +0200

----------------------------------------------------------------------
 .../deserializer/batch/BatchLineReader.java     | 100 +++---------------
 .../serializer/BatchResponseSerializer.java     |   3 +-
 .../deserializer/batch/BatchLineReaderTest.java | 103 ++-----------------
 .../serializer/BatchResponseSerializerTest.java |  60 ++---------
 4 files changed, 31 insertions(+), 235 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b484f7f6/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
index 150d318..bd71d93 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
@@ -28,29 +28,19 @@ import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * Read batch content and split it into lines.
- * This class is not thread safe.
- */
 public class BatchLineReader {
-  private static final byte CR_BYTE = '\r';
-  private static final byte LF_BYTE = '\n';
+  private static final byte CR = '\r';
+  private static final byte LF = '\n';
   private static final int EOF = -1;
   private static final int BUFFER_SIZE = 8192;
   private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
   private static final Charset CS_ISO_8859_1 = Charset.forName("iso-8859-1");
-  private static final String BOUNDARY = "boundary";
-  private static final String DOUBLE_DASH = "--";
-  private static final String CR = "\r";
-  private static final String LF = "\n";
-  private static final String CRLF = "\r\n";
-  // length of the Content-Type Header field including the ':'
-  // "Content-Type:" => 13
-  private static final int CONTENT_TYPE_LENGTH = 13;
-
-  private final ReadState readState = new ReadState();
+  public static final String BOUNDARY = "boundary";
+  public static final String DOUBLE_DASH = "--";
+  public static final String CRLF = "\r\n";
   private Charset currentCharset = DEFAULT_CHARSET;
   private String currentBoundary = null;
+  private ReadState readState = new ReadState();
   private InputStream reader;
   private byte[] buffer;
   private int offset = 0;
@@ -103,57 +93,11 @@ public class BatchLineReader {
     return result;
   }
 
-  int read(final byte[] byteBuffer, final int bufferOffset, final int length) throws IOException {
-    if ((bufferOffset + length) > byteBuffer.length) {
-      throw new IndexOutOfBoundsException("Buffer is too small");
-    }
-
-    if (length < 0 || bufferOffset < 0) {
-      throw new IndexOutOfBoundsException("Offset and length must be greater than zero");
-    }
-
-    // Check if buffer is filled. Return if EOF is reached
-    // Is buffer refill required
-    if (limit == offset || isEOF()) {
-      fillBuffer();
-
-      if (isEOF()) {
-        return EOF;
-      }
-    }
-
-    int bytesRead = 0;
-    int bytesToRead = length;
-    int currentOutputOffset = bufferOffset;
-
-    while (bytesToRead != 0) {
-      // Is buffer refill required?
-      if (limit == offset) {
-        fillBuffer();
-
-        if (isEOF()) {
-          bytesToRead = 0;
-        }
-      }
-
-      if (bytesToRead > 0) {
-        int readByte = Math.min(limit - offset, bytesToRead);
-        bytesRead += readByte;
-        bytesToRead -= readByte;
-
-        for (int i = 0; i < readByte; i++) {
-          byteBuffer[currentOutputOffset++] = buffer[offset++];
-        }
-      }
-    }
-
-    return bytesRead;
-  }
-
   private void updateCurrentCharset(String currentLine) {
     if(currentLine != null) {
       if(currentLine.startsWith(HttpHeader.CONTENT_TYPE)) {
-        ContentType ct = parseContentType(currentLine);
+        currentLine = currentLine.substring(13, currentLine.length() - 2).trim();
+        ContentType ct = ContentType.parse(currentLine);
         if (ct != null) {
           String charsetString = ct.getParameter(ContentType.PARAMETER_CHARSET);
           if (charsetString != null) {
@@ -167,7 +111,7 @@ public class BatchLineReader {
             currentBoundary = DOUBLE_DASH + boundary;
           }
         }
-      } else if(isLinebreak(currentLine)) {
+      } else if(CRLF.equals(currentLine)) {
         readState.foundLinebreak();
       } else if(isBoundary(currentLine)) {
         readState.foundBoundary();
@@ -175,18 +119,6 @@ public class BatchLineReader {
     }
   }
 
-  private ContentType parseContentType(String currentLine) {
-    currentLine = currentLine.substring(CONTENT_TYPE_LENGTH, currentLine.length()).trim();
-    return ContentType.parse(currentLine);
-  }
-
-  private boolean isLinebreak(String currentLine) {
-    if(currentLine.length() > 2) {
-      return false;
-    }
-    return CR.equals(currentLine) || LF.equals(currentLine) || CRLF.equals(currentLine);
-  }
-
   private boolean isBoundary(String currentLine) {
     if((currentBoundary + CRLF).equals(currentLine)) {
       return true;
@@ -222,20 +154,20 @@ public class BatchLineReader {
         }
         buffer.put(currentChar);
 
-        if (currentChar == LF_BYTE) {
+        if (currentChar == LF) {
           foundLineEnd = true;
-        } else if (currentChar == CR_BYTE) {
+        } else if (currentChar == CR) {
           foundLineEnd = true;
 
-          // Check next char. Consume \n if available
+          // Check next byte. Consume \n if available
           // Is buffer refill required?
           if (limit == offset) {
             fillBuffer();
           }
 
           // Check if there is at least one character
-          if (limit != EOF && this.buffer[offset] == LF_BYTE) {
-            buffer.put(LF_BYTE);
+          if (limit != EOF && this.buffer[offset] == LF) {
+            buffer.put(LF);
             offset++;
           }
         }
@@ -256,10 +188,6 @@ public class BatchLineReader {
     }
   }
 
-  private boolean isEOF() {
-    return limit == EOF;
-  }
-
   private int fillBuffer() throws IOException {
     limit = reader.read(buffer, 0, buffer.length);
     offset = 0;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b484f7f6/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
index 21474dd..377c5e1 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
@@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.nio.ByteBuffer;
 import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
@@ -193,7 +194,7 @@ public class BatchResponseSerializer {
       }
       if(buffer.remaining() < b.length) {
         buffer.flip();
-        ByteBuffer tmp = ByteBuffer.allocate(b.length + BUFFER_SIZE);
+        ByteBuffer tmp = ByteBuffer.allocate(buffer.limit() *2);
         tmp.put(buffer);
         buffer = tmp;
       }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b484f7f6/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
index afb51f0..9861b7f 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
@@ -24,20 +24,8 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-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.List;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.olingo.commons.api.ODataRuntimeException;
-import org.apache.olingo.server.api.ODataResponse;
 import org.junit.Test;
 
 public class BatchLineReaderTest {
@@ -55,7 +43,6 @@ public class BatchLineReaderTest {
       "\n";
 
   private static final String TEXT_EMPTY = "";
-  private static final String LF = "\n";
 
   @Test
   public void testSimpleText() throws Exception {
@@ -216,22 +203,6 @@ public class BatchLineReaderTest {
   }
 
   @Test
-  public void testReadMoreBufferCapacityThanCharacterAvailable() throws Exception {
-    final String TEXT = "Foo";
-    byte[] buffer = new byte[20];
-
-    BatchLineReader reader = create(TEXT);
-    assertEquals(3, reader.read(buffer, 0, 20));
-    assertEquals(-1, reader.read(buffer, 0, 20));
-    reader.close();
-
-    BatchLineReader readerBufferOne = create(TEXT, 1);
-    assertEquals(3, readerBufferOne.read(buffer, 0, 20));
-    assertEquals(-1, readerBufferOne.read(buffer, 0, 20));
-    readerBufferOne.close();
-  }
-
-  @Test
   public void testLineEqualsAndHashCode() {
     Line l1 = new Line("The first line", 1);
     Line l2 = new Line("The first line", 1);
@@ -242,28 +213,20 @@ public class BatchLineReaderTest {
     assertTrue(l1.hashCode() != l3.hashCode());
   }
 
-  @Test
-  public void testToList() throws Exception {
-    BatchLineReader reader = create(TEXT_COMBINED);
-    List<String> stringList = reader.toList();
+  @Test(expected = IllegalArgumentException.class)
+  public void testFailBufferSizeZero() throws Exception {
+    BatchLineReader reader = create(TEXT_EMPTY, 0);
+    reader.close();
+  }
 
-    assertEquals(11, stringList.size());
-    assertEquals("Test\r", stringList.get(0));
-    assertEquals("Test2\r\n", stringList.get(1));
-    assertEquals("Test3\n", stringList.get(2));
-    assertEquals("Test4\r", stringList.get(3));
-    assertEquals("\r", stringList.get(4));
-    assertEquals("\r\n", stringList.get(5));
-    assertEquals("\r\n", stringList.get(6));
-    assertEquals("Test5\n", stringList.get(7));
-    assertEquals("Test6\r\n", stringList.get(8));
-    assertEquals("Test7\n", stringList.get(9));
-    assertEquals("\n", stringList.get(10));
+  @Test(expected = IllegalArgumentException.class)
+  public void testFailBufferSizeNegative() throws Exception {
+    BatchLineReader reader = create(TEXT_EMPTY, -1);
     reader.close();
   }
 
   @Test
-  public void testToLineList() throws Exception {
+  public void testToList() throws Exception {
     BatchLineReader reader = create(TEXT_COMBINED);
     List<Line> stringList = reader.toLineList();
 
@@ -282,53 +245,6 @@ public class BatchLineReaderTest {
     reader.close();
   }
 
-  @Test
-  public void testBatchContent() throws Exception {
-    String batchContent = getFileContent("/batchLarge.batch", "utf-8");
-    BatchLineReader reader = create(batchContent);
-
-    List<String> lines = reader.toList();
-    assertEquals(2422, lines.size());
-    assertEquals("--batch_8194-cf13-1f56\n", lines.get(0));
-    assertEquals("              <d:City m:type=\"RefScenario.c_City\">\n", lines.get(1402));
-    assertEquals("\n", lines.get(1903));
-    assertEquals("--batch_8194-cf13-1f56--", lines.get(2421));
-  }
-
-  private String getFileContent(String fileName, String charset) throws IOException {
-    byte[] content = getFileContent(fileName);
-    return new String(content, Charset.forName(charset));
-  }
-
-  private byte[] getFileContent(String fileName) throws IOException {
-    final InputStream input = ClassLoader.class.getResourceAsStream(fileName);
-    if (input == null) {
-      throw new IOException("Requested file '" + fileName + "' was not found.");
-    }
-      ByteArrayOutputStream output = new ByteArrayOutputStream();
-      ByteBuffer inBuffer = ByteBuffer.allocate(8192);
-      ReadableByteChannel ic = Channels.newChannel(input);
-      WritableByteChannel oc = Channels.newChannel(output);
-      while (ic.read(inBuffer) > 0) {
-        inBuffer.flip();
-        oc.write(inBuffer);
-        inBuffer.rewind();
-      }
-      return output.toByteArray();
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testFailBufferSizeZero() throws Exception {
-    BatchLineReader reader = create(TEXT_EMPTY, 0);
-    reader.close();
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testFailBufferSizeNegative() throws Exception {
-    BatchLineReader reader = create(TEXT_EMPTY, -1);
-    reader.close();
-  }
-
   private BatchLineReader create(final String inputString) throws Exception {
     return new BatchLineReader(new ByteArrayInputStream(inputString
         .getBytes("UTF-8")));
@@ -338,5 +254,4 @@ public class BatchLineReaderTest {
     return new BatchLineReader(new ByteArrayInputStream(inputString
         .getBytes("UTF-8")), bufferSize);
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b484f7f6/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
index 9570d35..f73479b 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
@@ -27,7 +27,6 @@ import java.io.InputStream;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Random;
 import java.util.UUID;
 
 import org.apache.commons.io.IOUtils;
@@ -97,7 +96,7 @@ public class BatchResponseSerializerTest {
     assertEquals(CRLF, body.get(line++));
     assertEquals(CRLF, body.get(line++));
     assertTrue(body.get(line++).contains("--changeset_"));
-    assertTrue(body.get(line).contains("--batch_"));
+    assertTrue(body.get(line++).contains("--batch_"));
   }
 
   @Test
@@ -153,7 +152,7 @@ public class BatchResponseSerializerTest {
     assertEquals(CRLF, body.get(line++));
     assertEquals(CRLF, body.get(line++));
     assertTrue(body.get(line++).contains("--changeset_"));
-    assertTrue(body.get(line).contains("--batch_"));
+    assertTrue(body.get(line++).contains("--batch_"));
   }
 
   @Test
@@ -213,7 +212,7 @@ public class BatchResponseSerializerTest {
     assertEquals(CRLF, body.get(line++));
     assertEquals(CRLF, body.get(line++));
     assertTrue(body.get(line++).contains("--changeset_"));
-    assertTrue(body.get(line).contains("--batch_"));
+    assertTrue(body.get(line++).contains("--batch_"));
   }
 
   @Test
@@ -309,7 +308,7 @@ public class BatchResponseSerializerTest {
     assertEquals(CRLF, body.get(line++));
     assertEquals(CRLF, body.get(line++));
     assertTrue(body.get(line++).contains("--changeset_"));
-    assertTrue(body.get(line).contains("--batch_"));
+    assertTrue(body.get(line++).contains("--batch_"));
   }
 
   @Test
@@ -363,7 +362,7 @@ public class BatchResponseSerializerTest {
     assertEquals(CRLF, body.get(line++));
     assertEquals(CRLF, body.get(line++));
     assertTrue(body.get(line++).contains("--changeset_"));
-    assertTrue(body.get(line).contains("--batch_"));
+    assertTrue(body.get(line++).contains("--batch_"));
   }
 
   @Test
@@ -398,54 +397,7 @@ public class BatchResponseSerializerTest {
     assertEquals("Content-Length: 13" + CRLF, body.get(line++));
     assertEquals(CRLF, body.get(line++));
     assertEquals("Walter Winter" + CRLF, body.get(line++));
-    assertTrue(body.get(line).contains("--batch_"));
-  }
-
-  @Test
-  public void testResponseVeryLargeHeader() throws Exception {
-    List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
-    ODataResponse response = new ODataResponse();
-    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-    response.setHeader(HttpHeader.CONTENT_TYPE, "application/json");
-    final String chValue = generateTestData(20000);
-    response.setHeader("Custom-Header", chValue);
-    response.setContent(IOUtils.toInputStream("Walter Winter"));
-
-    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
-    responses.add(response);
-    parts.add(new ODataResponsePart(responses, false));
-
-    final BatchResponseSerializer serializer = new BatchResponseSerializer();
-    final InputStream content = serializer.serialize(parts, BOUNDARY);
-
-    assertNotNull(content);
-    final BatchLineReader reader =
-            new BatchLineReader(content);
-    final List<String> body = reader.toList();
-    reader.close();
-
-    int line = 0;
-    assertEquals(11, body.size());
     assertTrue(body.get(line++).contains("--batch_"));
-    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
-    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
-    assertEquals(CRLF, body.get(line++));
-    assertEquals("HTTP/1.1 200 OK" + CRLF, body.get(line++));
-    assertEquals("Custom-Header: " + chValue + CRLF, body.get(line++));
-    assertEquals("Content-Type: application/json" + CRLF, body.get(line++));
-    assertEquals("Content-Length: 13" + CRLF, body.get(line++));
-    assertEquals(CRLF, body.get(line++));
-    assertEquals("Walter Winter" + CRLF, body.get(line++));
-    assertTrue(body.get(line).contains("--batch_"));
-  }
-
-  private String generateTestData(int amount) {
-    StringBuilder sb = new StringBuilder();
-    Random r = new Random();
-    for (int j = 0; j < amount; j++) {
-      sb.append((char)(65 + r.nextInt(25)));
-    }
-    return sb.toString();
   }
 
   @Test
@@ -484,6 +436,6 @@ public class BatchResponseSerializerTest {
     assertEquals(CRLF, body.get(line++));
     assertEquals(CRLF, body.get(line++));
     assertTrue(body.get(line++).contains("--changeset_"));
-    assertTrue(body.get(line).contains("--batch_"));
+    assertTrue(body.get(line++).contains("--batch_"));
   }
 }


[4/5] olingo-odata4 git commit: [OLINGO-729] Merge branch 'master' into OLINGO-729_BatchDeSerializer

Posted by mi...@apache.org.
[OLINGO-729] Merge branch 'master' into OLINGO-729_BatchDeSerializer


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

Branch: refs/heads/master
Commit: 594ad4ab45b6e4d2033361d16931a66a77aa0918
Parents: 3c591da 4baaf0d
Author: Michael Bolz <mi...@sap.com>
Authored: Fri Jul 10 08:19:25 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Fri Jul 10 09:24:45 2015 +0200

----------------------------------------------------------------------
 .../apache/olingo/fit/v4/BatchTestITCase.java   |   2 -
 .../org/apache/olingo/server/api/OData.java     |   9 ++
 .../olingo/server/api/ODataHttpHandler.java     |   7 ++
 .../server/api/debug/DebugResponseHelper.java   |  38 ++++++
 .../olingo/server/api/debug/DebugSupport.java   |  49 ++++++++
 .../server/api/debug/DefaultDebugSupport.java   |  52 ++++++++
 .../server/core/ODataHttpHandlerImpl.java       |  33 ++++-
 .../apache/olingo/server/core/ODataImpl.java    |   9 ++
 .../core/debug/DebugResponseHelperImpl.java     |  33 +++++
 .../deserializer/batch/BatchLineReader.java     |  50 +++++---
 .../serializer/BatchResponseSerializer.java     |   3 +-
 .../serializer/json/ODataJsonSerializer.java    |   1 -
 .../deserializer/batch/BatchLineReaderTest.java |  92 +++++++++++---
 .../serializer/BatchResponseSerializerTest.java |  60 ++++++++-
 .../olingo/server/tecsvc/TechnicalServlet.java  |   5 +
 pom.xml                                         |   1 +
 .../myservice/mynamespace/data/Storage.java     |  92 +++++++-------
 .../mynamespace/service/DemoEdmProvider.java    |  43 +++----
 .../service/DemoEntityCollectionProcessor.java  |  47 ++++---
 .../service/DemoEntityProcessor.java            |  64 ++++------
 .../service/DemoPrimitiveProcessor.java         |  42 +++----
 .../java/myservice/mynamespace/util/Util.java   | 126 ++++++++++---------
 .../myservice/mynamespace/web/DemoServlet.java  |  17 ++-
 23 files changed, 600 insertions(+), 275 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/594ad4ab/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
----------------------------------------------------------------------
diff --cc lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
index d96a5f5,0000000..150d318
mode 100644,000000..100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
@@@ -1,275 -1,0 +1,295 @@@
 +/*
 + * 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.deserializer.batch;
 +
 +import org.apache.olingo.commons.api.format.ContentType;
 +import org.apache.olingo.commons.api.http.HttpHeader;
 +
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.nio.ByteBuffer;
 +import java.nio.charset.Charset;
 +import java.util.ArrayList;
 +import java.util.List;
 +
++/**
++ * Read batch content and split it into lines.
++ * This class is not thread safe.
++ */
 +public class BatchLineReader {
-   private static final byte CR = '\r';
-   private static final byte LF = '\n';
++  private static final byte CR_BYTE = '\r';
++  private static final byte LF_BYTE = '\n';
 +  private static final int EOF = -1;
 +  private static final int BUFFER_SIZE = 8192;
 +  private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
 +  private static final Charset CS_ISO_8859_1 = Charset.forName("iso-8859-1");
-   public static final String BOUNDARY = "boundary";
-   public static final String DOUBLE_DASH = "--";
-   public static final String CRLF = "\r\n";
++  private static final String BOUNDARY = "boundary";
++  private static final String DOUBLE_DASH = "--";
++  private static final String CR = "\r";
++  private static final String LF = "\n";
++  private static final String CRLF = "\r\n";
++  // length of the Content-Type Header field including the ':'
++  // "Content-Type:" => 13
++  private static final int CONTENT_TYPE_LENGTH = 13;
++
++  private final ReadState readState = new ReadState();
 +  private Charset currentCharset = DEFAULT_CHARSET;
 +  private String currentBoundary = null;
-   private ReadState readState = new ReadState();
 +  private InputStream reader;
 +  private byte[] buffer;
 +  private int offset = 0;
 +  private int limit = 0;
 +
 +  public BatchLineReader(final InputStream reader) {
 +    this(reader, BUFFER_SIZE);
 +  }
 +
 +  public BatchLineReader(final InputStream reader, final int bufferSize) {
 +    if (bufferSize <= 0) {
 +      throw new IllegalArgumentException("Buffer size must be greater than zero.");
 +    }
 +
 +    this.reader = reader;
 +    buffer = new byte[bufferSize];
 +  }
 +
 +  public void close() throws IOException {
 +    reader.close();
 +  }
 +
 +  public List<String> toList() throws IOException {
 +    final List<String> result = new ArrayList<String>();
 +    String currentLine = readLine();
 +    if(currentLine != null) {
 +      currentBoundary = currentLine.trim();
 +      result.add(currentLine);
 +
 +      while ((currentLine = readLine()) != null) {
 +        result.add(currentLine);
 +      }
 +    }
 +    return result;
 +  }
 +
 +  public List<Line> toLineList() throws IOException {
 +    final List<Line> result = new ArrayList<Line>();
 +    String currentLine = readLine();
 +    if(currentLine != null) {
 +      currentBoundary = currentLine.trim();
 +      int counter = 1;
 +      result.add(new Line(currentLine, counter++));
 +
 +      while ((currentLine = readLine()) != null) {
 +        result.add(new Line(currentLine, counter++));
 +      }
 +    }
 +
 +    return result;
 +  }
 +
 +  int read(final byte[] byteBuffer, final int bufferOffset, final int length) throws IOException {
 +    if ((bufferOffset + length) > byteBuffer.length) {
 +      throw new IndexOutOfBoundsException("Buffer is too small");
 +    }
 +
 +    if (length < 0 || bufferOffset < 0) {
-       throw new IndexOutOfBoundsException("Offset and length must be grater than zero");
++      throw new IndexOutOfBoundsException("Offset and length must be greater than zero");
 +    }
 +
 +    // Check if buffer is filled. Return if EOF is reached
 +    // Is buffer refill required
 +    if (limit == offset || isEOF()) {
 +      fillBuffer();
 +
 +      if (isEOF()) {
 +        return EOF;
 +      }
 +    }
 +
 +    int bytesRead = 0;
 +    int bytesToRead = length;
 +    int currentOutputOffset = bufferOffset;
 +
 +    while (bytesToRead != 0) {
 +      // Is buffer refill required?
 +      if (limit == offset) {
 +        fillBuffer();
 +
 +        if (isEOF()) {
 +          bytesToRead = 0;
 +        }
 +      }
 +
 +      if (bytesToRead > 0) {
 +        int readByte = Math.min(limit - offset, bytesToRead);
 +        bytesRead += readByte;
 +        bytesToRead -= readByte;
 +
 +        for (int i = 0; i < readByte; i++) {
 +          byteBuffer[currentOutputOffset++] = buffer[offset++];
 +        }
 +      }
 +    }
 +
 +    return bytesRead;
 +  }
 +
 +  private void updateCurrentCharset(String currentLine) {
-     // TODO: mibo: Improve this method
 +    if(currentLine != null) {
 +      if(currentLine.startsWith(HttpHeader.CONTENT_TYPE)) {
-         currentLine = currentLine.substring(13, currentLine.length() - 2).trim();
-         ContentType ct = ContentType.parse(currentLine);
++        ContentType ct = parseContentType(currentLine);
 +        if (ct != null) {
 +          String charsetString = ct.getParameter(ContentType.PARAMETER_CHARSET);
 +          if (charsetString != null) {
 +            currentCharset = Charset.forName(charsetString);
 +          } else {
 +            currentCharset = DEFAULT_CHARSET;
 +          }
 +          // boundary
 +          String boundary = ct.getParameter(BOUNDARY);
 +          if (boundary != null) {
 +            currentBoundary = DOUBLE_DASH + boundary;
 +          }
 +        }
-       } else if(CRLF.equals(currentLine)) {
++      } else if(isLinebreak(currentLine)) {
 +        readState.foundLinebreak();
 +      } else if(isBoundary(currentLine)) {
 +        readState.foundBoundary();
 +      }
 +    }
 +  }
 +
++  private ContentType parseContentType(String currentLine) {
++    currentLine = currentLine.substring(CONTENT_TYPE_LENGTH, currentLine.length()).trim();
++    return ContentType.parse(currentLine);
++  }
++
++  private boolean isLinebreak(String currentLine) {
++    if(currentLine.length() > 2) {
++      return false;
++    }
++    return CR.equals(currentLine) || LF.equals(currentLine) || CRLF.equals(currentLine);
++  }
++
 +  private boolean isBoundary(String currentLine) {
 +    if((currentBoundary + CRLF).equals(currentLine)) {
 +      return true;
 +    } else if((currentBoundary + DOUBLE_DASH + CRLF).equals(currentLine)) {
 +      return true;
 +    }
 +    return false;
 +  }
 +
 +  String readLine() throws IOException {
 +    if (limit == EOF) {
 +      return null;
 +    }
 +
 +    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
 +    boolean foundLineEnd = false; // EOF will be considered as line ending
 +
 +    while (!foundLineEnd) {
 +      // Is buffer refill required?
 +      if (limit == offset) {
 +        if (fillBuffer() == EOF) {
 +          foundLineEnd = true;
 +        }
 +      }
 +
 +      if (!foundLineEnd) {
 +        byte currentChar = this.buffer[offset++];
 +        if(!buffer.hasRemaining()) {
 +          buffer.flip();
 +          ByteBuffer tmp = ByteBuffer.allocate(buffer.limit() *2);
 +          tmp.put(buffer);
 +          buffer = tmp;
 +        }
 +        buffer.put(currentChar);
 +
-         if (currentChar == LF) {
++        if (currentChar == LF_BYTE) {
 +          foundLineEnd = true;
-         } else if (currentChar == CR) {
++        } else if (currentChar == CR_BYTE) {
 +          foundLineEnd = true;
 +
 +          // Check next char. Consume \n if available
 +          // Is buffer refill required?
 +          if (limit == offset) {
 +            fillBuffer();
 +          }
 +
 +          // Check if there is at least one character
-           if (limit != EOF && this.buffer[offset] == LF) {
-             buffer.put(LF);
++          if (limit != EOF && this.buffer[offset] == LF_BYTE) {
++            buffer.put(LF_BYTE);
 +            offset++;
 +          }
 +        }
 +      }
 +    }
 +
 +    if(buffer.position() == 0) {
 +      return null;
 +    } else {
 +      String currentLine;
 +      if(readState.isReadBody()) {
 +        currentLine = new String(buffer.array(), 0, buffer.position(), getCurrentCharset());
 +      } else {
 +        currentLine = new String(buffer.array(), 0, buffer.position(), CS_ISO_8859_1);
 +      }
 +      updateCurrentCharset(currentLine);
 +      return currentLine;
 +    }
 +  }
 +
 +  private boolean isEOF() {
 +    return limit == EOF;
 +  }
 +
 +  private int fillBuffer() throws IOException {
 +    limit = reader.read(buffer, 0, buffer.length);
 +    offset = 0;
 +
 +    return limit;
 +  }
 +
 +  private Charset getCurrentCharset() {
 +    return currentCharset;
 +  }
 +
 +  /**
 +   * Read state indicator (whether currently the <code>body</code> or <code>header</code> part is read).
 +   */
 +  private class ReadState {
 +    private int state = 0;
 +
 +    public void foundLinebreak() {
 +      state++;
 +    }
 +    public void foundBoundary() {
 +      state = 0;
 +    }
 +    public boolean isReadBody() {
 +      return state >= 2;
 +    }
 +
 +    @Override
 +    public String toString() {
 +      return String.valueOf(state);
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/594ad4ab/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
----------------------------------------------------------------------
diff --cc lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
index 377c5e1,577f083..21474dd
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
@@@ -22,12 -22,6 +22,11 @@@ import java.io.ByteArrayInputStream
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
- 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.List;
  import java.util.Map;
  import java.util.UUID;
@@@ -165,93 -182,4 +164,93 @@@ public class BatchResponseSerializer 
    private String generateBoundary(final String value) {
      return value + "_" + UUID.randomUUID().toString();
    }
 -}
 +
 +  /**
 +   * Builder class to create the body and the header.
 +   */
 +  private class BodyBuilder {
 +    private final Charset CHARSET_ISO_8859_1 = Charset.forName("iso-8859-1");
 +    private ByteBuffer buffer = ByteBuffer.allocate(8192);
 +    private boolean isClosed = false;
 +
 +    public byte[] getContent() {
 +      isClosed = true;
 +      byte[] tmp = new byte[buffer.position()];
 +      buffer.flip();
 +      buffer.get(tmp, 0, buffer.limit());
 +      return tmp;
 +    }
 +
 +    public BodyBuilder append(String string) {
 +      byte [] b = string.getBytes(CHARSET_ISO_8859_1);
 +      put(b);
 +      return this;
 +    }
 +
 +    private void put(byte[] b) {
 +      if(isClosed) {
 +        throw new RuntimeException("BodyBuilder is closed.");
 +      }
 +      if(buffer.remaining() < b.length) {
 +        buffer.flip();
-         ByteBuffer tmp = ByteBuffer.allocate(buffer.limit() *2);
++        ByteBuffer tmp = ByteBuffer.allocate(b.length + BUFFER_SIZE);
 +        tmp.put(buffer);
 +        buffer = tmp;
 +      }
 +      buffer.put(b);
 +    }
 +
 +    public BodyBuilder append(int statusCode) {
 +      return append(String.valueOf(statusCode));
 +    }
 +
 +    public BodyBuilder append(Body body) {
 +      put(body.getContent());
 +      return this;
 +    }
 +
 +    public String toString() {
 +      return new String(buffer.array(), 0, buffer.position());
 +    }
 +  }
 +
 +  /**
 +   * Body part which is read and stored as bytes (no charset conversion).
 +   */
 +  private class Body {
 +    private final byte[] content;
 +
 +    public Body(ODataResponse response) {
 +      this.content = getBody(response);
 +    }
 +
 +    public int getLength() {
 +      return content.length;
 +    }
 +
 +    public byte[] getContent() {
 +      return content;
 +    }
 +
 +    private byte[] getBody(final ODataResponse response) {
 +      if (response == null || response.getContent() == null) {
 +        return new byte[0];
 +      }
 +
 +      try {
 +        ByteArrayOutputStream output = new ByteArrayOutputStream();
 +        ByteBuffer inBuffer = ByteBuffer.allocate(BUFFER_SIZE);
 +        ReadableByteChannel ic = Channels.newChannel(response.getContent());
 +        WritableByteChannel oc = Channels.newChannel(output);
 +        while (ic.read(inBuffer) > 0) {
 +          inBuffer.flip();
 +          oc.write(inBuffer);
 +          inBuffer.rewind();
 +        }
 +        return output.toByteArray();
 +      } catch (IOException e) {
 +        throw new ODataRuntimeException("Error on reading request content");
 +      }
 +    }
 +  }
 +}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/594ad4ab/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
----------------------------------------------------------------------
diff --cc lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
index 3d2507c,0000000..afb51f0
mode 100644,000000..100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
@@@ -1,280 -1,0 +1,342 @@@
 +/*
 + * 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.deserializer.batch;
 +
 +import static org.junit.Assert.assertEquals;
 +import static org.junit.Assert.assertFalse;
 +import static org.junit.Assert.assertNull;
 +import static org.junit.Assert.assertTrue;
 +
 +import java.io.ByteArrayInputStream;
++import java.io.ByteArrayOutputStream;
++import java.io.IOException;
++import java.io.InputStream;
++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.List;
 +
++import org.apache.commons.io.IOUtils;
++import org.apache.commons.lang3.StringUtils;
++import org.apache.olingo.commons.api.ODataRuntimeException;
++import org.apache.olingo.server.api.ODataResponse;
 +import org.junit.Test;
 +
 +public class BatchLineReaderTest {
 +
 +  private static final String TEXT_COMBINED = "Test\r" +
 +      "Test2\r\n" +
 +      "Test3\n" +
 +      "Test4\r" +
 +      "\r" +
 +      "\r\n" +
 +      "\r\n" +
 +      "Test5\n" +
 +      "Test6\r\n" +
 +      "Test7\n" +
 +      "\n";
 +
 +  private static final String TEXT_EMPTY = "";
++  private static final String LF = "\n";
 +
 +  @Test
 +  public void testSimpleText() throws Exception {
 +    final String TEXT = "Test";
 +    BatchLineReader reader = create(TEXT);
 +
 +    assertEquals(TEXT, reader.readLine());
 +    assertNull(reader.readLine());
 +    assertNull(reader.readLine());
 +    reader.close();
 +  }
 +
 +  @Test
 +  public void testNoText() throws Exception {
 +    final String TEXT = "";
 +    BatchLineReader reader = create(TEXT);
 +
 +    assertNull(reader.readLine());
 +    assertNull(reader.readLine());
 +    reader.close();
 +  }
 +
 +  @Test
 +  public void testNoBytes() throws Exception {
 +    BatchLineReader reader =
 +        new BatchLineReader(new ByteArrayInputStream(new byte[0]));
 +
 +    assertNull(reader.readLine());
 +    assertNull(reader.readLine());
 +    reader.close();
 +  }
 +
 +  @Test
 +  public void testCRLF() throws Exception {
 +    final String TEXT = "Test\r\n" +
 +        "Test2";
 +
 +    BatchLineReader reader = create(TEXT);
 +
 +    assertEquals("Test\r\n", reader.readLine());
 +    assertEquals("Test2", reader.readLine());
 +    assertNull(reader.readLine());
 +    assertNull(reader.readLine());
 +    reader.close();
 +  }
 +
 +  @Test
 +  public void testLF() throws Exception {
 +    final String TEXT = "Test\n" +
 +        "Test2";
 +
 +    BatchLineReader reader = create(TEXT);
 +
 +    assertEquals("Test\n", reader.readLine());
 +    assertEquals("Test2", reader.readLine());
 +    assertNull(reader.readLine());
 +    assertNull(reader.readLine());
 +    reader.close();
 +  }
 +
 +  @Test
 +  public void testCR() throws Exception {
 +    final String TEXT = "Test\r" +
 +        "Test2";
 +
 +    BatchLineReader reader = create(TEXT);
 +
 +    assertEquals("Test\r", reader.readLine());
 +    assertEquals("Test2", reader.readLine());
 +    assertNull(reader.readLine());
 +    assertNull(reader.readLine());
 +    reader.close();
 +  }
 +
 +  @Test
 +  public void testCombined() throws Exception {
 +    BatchLineReader reader = create(TEXT_COMBINED);
 +
 +    assertEquals("Test\r", reader.readLine());
 +    assertEquals("Test2\r\n", reader.readLine());
 +    assertEquals("Test3\n", reader.readLine());
 +    assertEquals("Test4\r", reader.readLine());
 +    assertEquals("\r", reader.readLine());
 +    assertEquals("\r\n", reader.readLine());
 +    assertEquals("\r\n", reader.readLine());
 +    assertEquals("Test5\n", reader.readLine());
 +    assertEquals("Test6\r\n", reader.readLine());
 +    assertEquals("Test7\n", reader.readLine());
 +    assertEquals("\n", reader.readLine());
 +    assertNull(reader.readLine());
 +    assertNull(reader.readLine());
 +    reader.close();
 +  }
 +
 +  @Test
 +  public void testCombinedBufferSizeTwo() throws Exception {
 +    BatchLineReader reader = create(TEXT_COMBINED, 2);
 +
 +    assertEquals("Test\r", reader.readLine());
 +    assertEquals("Test2\r\n", reader.readLine());
 +    assertEquals("Test3\n", reader.readLine());
 +    assertEquals("Test4\r", reader.readLine());
 +    assertEquals("\r", reader.readLine());
 +    assertEquals("\r\n", reader.readLine());
 +    assertEquals("\r\n", reader.readLine());
 +    assertEquals("Test5\n", reader.readLine());
 +    assertEquals("Test6\r\n", reader.readLine());
 +    assertEquals("Test7\n", reader.readLine());
 +    assertEquals("\n", reader.readLine());
 +    assertNull(reader.readLine());
 +    assertNull(reader.readLine());
 +    reader.close();
 +  }
 +
 +  @Test
 +  public void testCombinedBufferSizeOne() throws Exception {
 +    final String TEXT = "Test\r" +
 +        "Test2\r\n" +
 +        "Test3\n" +
 +        "Test4\r" +
 +        "\r" +
 +        "\r\n" +
 +        "\r\n" +
 +        "Test5\n" +
 +        "Test6\r\n" +
 +        "Test7\n" +
 +        "\r\n";
 +
 +    BatchLineReader reader = create(TEXT, 1);
 +
 +    assertEquals("Test\r", reader.readLine());
 +    assertEquals("Test2\r\n", reader.readLine());
 +    assertEquals("Test3\n", reader.readLine());
 +    assertEquals("Test4\r", reader.readLine());
 +    assertEquals("\r", reader.readLine());
 +    assertEquals("\r\n", reader.readLine());
 +    assertEquals("\r\n", reader.readLine());
 +    assertEquals("Test5\n", reader.readLine());
 +    assertEquals("Test6\r\n", reader.readLine());
 +    assertEquals("Test7\n", reader.readLine());
 +    assertEquals("\r\n", reader.readLine());
 +    assertNull(reader.readLine());
 +    assertNull(reader.readLine());
 +
 +    reader.close();
 +  }
 +
 +  @Test
 +  public void testDoubleLF() throws Exception {
 +    final String TEXT = "Test\r" +
 +        "\r";
 +
 +    BatchLineReader reader = create(TEXT, 1);
 +
 +    assertEquals("Test\r", reader.readLine());
 +    assertEquals("\r", reader.readLine());
 +    reader.close();
 +  }
 +
 +  @Test
 +  public void testReadMoreBufferCapacityThanCharacterAvailable() throws Exception {
 +    final String TEXT = "Foo";
 +    byte[] buffer = new byte[20];
 +
 +    BatchLineReader reader = create(TEXT);
 +    assertEquals(3, reader.read(buffer, 0, 20));
 +    assertEquals(-1, reader.read(buffer, 0, 20));
 +    reader.close();
 +
 +    BatchLineReader readerBufferOne = create(TEXT, 1);
 +    assertEquals(3, readerBufferOne.read(buffer, 0, 20));
 +    assertEquals(-1, readerBufferOne.read(buffer, 0, 20));
 +    readerBufferOne.close();
 +  }
 +
 +  @Test
 +  public void testLineEqualsAndHashCode() {
 +    Line l1 = new Line("The first line", 1);
 +    Line l2 = new Line("The first line", 1);
 +    Line l3 = new Line("The second line", 2);
 +
 +    assertEquals(l1, l2);
 +    assertFalse(l1.equals(l3));
 +    assertTrue(l1.hashCode() != l3.hashCode());
 +  }
 +
- //  @Test(expected = IllegalArgumentException.class)
- //  public void testSkipNegative() throws Exception {
- //    BufferedReaderIncludingLineEndings reader = create("123");
- //    reader.skip(-1);
- //  }
- 
-   @Test(expected = IllegalArgumentException.class)
-   public void testFailBufferSizeZero() throws Exception {
-     BatchLineReader reader = create(TEXT_EMPTY, 0);
-     reader.close();
-   }
++  @Test
++  public void testToList() throws Exception {
++    BatchLineReader reader = create(TEXT_COMBINED);
++    List<String> stringList = reader.toList();
 +
-   @Test(expected = IllegalArgumentException.class)
-   public void testFailBufferSizeNegative() throws Exception {
-     BatchLineReader reader = create(TEXT_EMPTY, -1);
++    assertEquals(11, stringList.size());
++    assertEquals("Test\r", stringList.get(0));
++    assertEquals("Test2\r\n", stringList.get(1));
++    assertEquals("Test3\n", stringList.get(2));
++    assertEquals("Test4\r", stringList.get(3));
++    assertEquals("\r", stringList.get(4));
++    assertEquals("\r\n", stringList.get(5));
++    assertEquals("\r\n", stringList.get(6));
++    assertEquals("Test5\n", stringList.get(7));
++    assertEquals("Test6\r\n", stringList.get(8));
++    assertEquals("Test7\n", stringList.get(9));
++    assertEquals("\n", stringList.get(10));
 +    reader.close();
 +  }
 +
 +  @Test
-   public void testToList() throws Exception {
++  public void testToLineList() throws Exception {
 +    BatchLineReader reader = create(TEXT_COMBINED);
 +    List<Line> stringList = reader.toLineList();
 +
 +    assertEquals(11, stringList.size());
 +    assertEquals("Test\r", stringList.get(0).toString());
 +    assertEquals("Test2\r\n", stringList.get(1).toString());
 +    assertEquals("Test3\n", stringList.get(2).toString());
 +    assertEquals("Test4\r", stringList.get(3).toString());
 +    assertEquals("\r", stringList.get(4).toString());
 +    assertEquals("\r\n", stringList.get(5).toString());
 +    assertEquals("\r\n", stringList.get(6).toString());
 +    assertEquals("Test5\n", stringList.get(7).toString());
 +    assertEquals("Test6\r\n", stringList.get(8).toString());
 +    assertEquals("Test7\n", stringList.get(9).toString());
 +    assertEquals("\n", stringList.get(10).toString());
 +    reader.close();
 +  }
 +
++  @Test
++  public void testBatchContent() throws Exception {
++    String batchContent = getFileContent("/batchLarge.batch", "utf-8");
++    BatchLineReader reader = create(batchContent);
++
++    List<String> lines = reader.toList();
++    assertEquals(2422, lines.size());
++    assertEquals("--batch_8194-cf13-1f56\n", lines.get(0));
++    assertEquals("              <d:City m:type=\"RefScenario.c_City\">\n", lines.get(1402));
++    assertEquals("\n", lines.get(1903));
++    assertEquals("--batch_8194-cf13-1f56--", lines.get(2421));
++  }
++
++  private String getFileContent(String fileName, String charset) throws IOException {
++    byte[] content = getFileContent(fileName);
++    return new String(content, Charset.forName(charset));
++  }
++
++  private byte[] getFileContent(String fileName) throws IOException {
++    final InputStream input = ClassLoader.class.getResourceAsStream(fileName);
++    if (input == null) {
++      throw new IOException("Requested file '" + fileName + "' was not found.");
++    }
++      ByteArrayOutputStream output = new ByteArrayOutputStream();
++      ByteBuffer inBuffer = ByteBuffer.allocate(8192);
++      ReadableByteChannel ic = Channels.newChannel(input);
++      WritableByteChannel oc = Channels.newChannel(output);
++      while (ic.read(inBuffer) > 0) {
++        inBuffer.flip();
++        oc.write(inBuffer);
++        inBuffer.rewind();
++      }
++      return output.toByteArray();
++  }
++
++  @Test(expected = IllegalArgumentException.class)
++  public void testFailBufferSizeZero() throws Exception {
++    BatchLineReader reader = create(TEXT_EMPTY, 0);
++    reader.close();
++  }
++
++  @Test(expected = IllegalArgumentException.class)
++  public void testFailBufferSizeNegative() throws Exception {
++    BatchLineReader reader = create(TEXT_EMPTY, -1);
++    reader.close();
++  }
++
 +  private BatchLineReader create(final String inputString) throws Exception {
 +    return new BatchLineReader(new ByteArrayInputStream(inputString
 +        .getBytes("UTF-8")));
 +  }
 +
 +  private BatchLineReader create(final String inputString, final int bufferSize) throws Exception {
 +    return new BatchLineReader(new ByteArrayInputStream(inputString
 +        .getBytes("UTF-8")), bufferSize);
 +  }
 +
 +}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/594ad4ab/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
----------------------------------------------------------------------
diff --cc lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
index f73479b,c5d0653..9570d35
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
@@@ -22,11 -22,10 +22,12 @@@ import static org.junit.Assert.assertEq
  import static org.junit.Assert.assertNotNull;
  import static org.junit.Assert.assertTrue;
  
 +import java.io.ByteArrayInputStream;
  import java.io.InputStream;
 -import java.io.InputStreamReader;
 +import java.nio.charset.Charset;
  import java.util.ArrayList;
  import java.util.List;
++import java.util.Random;
  import java.util.UUID;
  
  import org.apache.commons.io.IOUtils;
@@@ -96,219 -93,7 +97,219 @@@ public class BatchResponseSerializerTes
      assertEquals(CRLF, body.get(line++));
      assertEquals(CRLF, body.get(line++));
      assertTrue(body.get(line++).contains("--changeset_"));
-     assertTrue(body.get(line++).contains("--batch_"));
++    assertTrue(body.get(line).contains("--batch_"));
 +  }
 +
 +  @Test
 +  public void testBatchResponseUmlautsUtf8() throws Exception {
 +    final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
 +    ODataResponse response = new ODataResponse();
 +    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
 +    response.setHeader(HttpHeader.CONTENT_TYPE,
 +            ContentType.APPLICATION_JSON.toContentTypeString() + "; charset=UTF-8");
 +    response.setContent(IOUtils.toInputStream("Wälter Winter" + CRLF));
 +
 +    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
 +    responses.add(response);
 +    parts.add(new ODataResponsePart(responses, false));
 +
 +    ODataResponse changeSetResponse = new ODataResponse();
 +    changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
 +    changeSetResponse.setHeader(HttpHeader.CONTENT_ID, "1");
 +    responses = new ArrayList<ODataResponse>(1);
 +    responses.add(changeSetResponse);
 +    parts.add(new ODataResponsePart(responses, true));
 +
 +    BatchResponseSerializer serializer = new BatchResponseSerializer();
 +    final InputStream content = serializer.serialize(parts, BOUNDARY);
 +    assertNotNull(content);
 +    final BatchLineReader reader =
 +            new BatchLineReader(content);
 +    final List<String> body = reader.toList();
 +    reader.close();
 +
 +    int line = 0;
 +    assertEquals(24, body.size());
      assertTrue(body.get(line++).contains("--batch_"));
 +    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
 +    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals("HTTP/1.1 200 OK" + CRLF, body.get(line++));
 +    assertEquals("Content-Type: application/json; charset=UTF-8" + CRLF, body.get(line++));
 +    assertEquals("Content-Length: 16" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals("Wälter Winter" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertTrue(body.get(line++).contains("--batch_"));
 +    assertTrue(body.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
 +    assertEquals(CRLF, body.get(line++));
 +    assertTrue(body.get(line++).contains("--changeset_"));
 +    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
 +    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
 +    assertEquals("Content-ID: 1" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals("HTTP/1.1 204 No Content" + CRLF, body.get(line++));
 +    assertEquals("Content-Length: 0" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertTrue(body.get(line++).contains("--changeset_"));
-     assertTrue(body.get(line++).contains("--batch_"));
++    assertTrue(body.get(line).contains("--batch_"));
 +  }
 +
 +  @Test
 +  public void testBatchResponseUmlautsUtf8BodyIsoHeader() throws Exception {
 +    final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
 +    ODataResponse response = new ODataResponse();
 +    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
 +    response.setHeader(HttpHeader.CONTENT_TYPE,
 +        ContentType.APPLICATION_JSON.toContentTypeString() + "; charset=UTF-8");
 +    response.setContent(IOUtils.toInputStream("Wälter Winter" + CRLF));
 +
 +    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
 +    responses.add(response);
 +    parts.add(new ODataResponsePart(responses, false));
 +
 +    ODataResponse changeSetResponse = new ODataResponse();
 +    changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
 +    changeSetResponse.setHeader(HttpHeader.CONTENT_ID, "1");
 +
 +    byte[] umlauts = "äüö".getBytes(CS_ISO_8859_1);
 +    changeSetResponse.setHeader("Custom-Header", new String(umlauts, CS_ISO_8859_1));
 +    responses = new ArrayList<ODataResponse>(1);
 +    responses.add(changeSetResponse);
 +    parts.add(new ODataResponsePart(responses, true));
 +
 +    BatchResponseSerializer serializer = new BatchResponseSerializer();
 +    final InputStream content = serializer.serialize(parts, BOUNDARY);
 +    assertNotNull(content);
 +    final BatchLineReader reader =
 +        new BatchLineReader(content);
 +    final List<String> body = reader.toList();
 +    reader.close();
 +
 +    int line = 0;
 +    assertEquals(25, body.size());
 +    assertTrue(body.get(line++).contains("--batch_"));
 +    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
 +    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals("HTTP/1.1 200 OK" + CRLF, body.get(line++));
 +    assertEquals("Content-Type: application/json; charset=UTF-8" + CRLF, body.get(line++));
 +    assertEquals("Content-Length: 16" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals("Wälter Winter" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertTrue(body.get(line++).contains("--batch_"));
 +    assertTrue(body.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
 +    assertEquals(CRLF, body.get(line++));
 +    assertTrue(body.get(line++).contains("--changeset_"));
 +    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
 +    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
 +    assertEquals("Content-ID: 1" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals("HTTP/1.1 204 No Content" + CRLF, body.get(line++));
 +    assertEquals("Custom-Header: äüö" + CRLF, body.get(line++));
 +    assertEquals("Content-Length: 0" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertTrue(body.get(line++).contains("--changeset_"));
-     assertTrue(body.get(line++).contains("--batch_"));
++    assertTrue(body.get(line).contains("--batch_"));
 +  }
 +
 +  @Test
 +  public void testBatchResponseUmlautsUtf8BodyAndHeader() throws Exception {
 +    final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
 +    ODataResponse response = new ODataResponse();
 +    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
 +    response.setHeader(HttpHeader.CONTENT_TYPE,
 +        ContentType.APPLICATION_JSON.toContentTypeString() + "; charset=UTF-8");
 +    response.setContent(IOUtils.toInputStream("Wälter Winter" + CRLF));
 +
 +    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
 +    responses.add(response);
 +    parts.add(new ODataResponsePart(responses, false));
 +
 +    ODataResponse changeSetResponse = new ODataResponse();
 +    changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
 +    changeSetResponse.setHeader(HttpHeader.CONTENT_ID, "1");
 +
 +//    byte[] umlauts = "äüö".getBytes(CS_UTF_8);
 +//    changeSetResponse.setHeader("Custom-Header", new String(umlauts, CS_UTF_8));
 +    changeSetResponse.setHeader("Custom-Header", "äüö");
 +    responses = new ArrayList<ODataResponse>(1);
 +    responses.add(changeSetResponse);
 +    parts.add(new ODataResponsePart(responses, true));
 +
 +    BatchResponseSerializer serializer = new BatchResponseSerializer();
 +    final InputStream content = serializer.serialize(parts, BOUNDARY);
 +    assertNotNull(content);
 +    final BatchLineReader reader =
 +        new BatchLineReader(content);
 +    final List<String> body = reader.toList();
 +    reader.close();
 +
 +    assertEquals(25, body.size());
 +    // TODO: check: with latest change in BatchResponseSerializer is not possible
 +    // to set header values with UTF-8 (only iso-8859-1)
 +//    assertEquals("Custom-Header: äüö" + CRLF, body.get(19));
 +    assertEquals("Custom-Header: äüö" + CRLF, body.get(19));
 +  }
 +
 +  @Test
 +  public void testBatchResponseUmlautsIso() throws Exception {
 +    final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
 +    ODataResponse response = new ODataResponse();
 +    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
 +    response.setHeader(HttpHeader.CONTENT_TYPE,
 +            ContentType.APPLICATION_JSON.toContentTypeString() + "; charset=iso-8859-1");
 +    byte[] payload = ("Wälter Winter" + CRLF).getBytes("iso-8859-1");
 +    response.setContent(new ByteArrayInputStream(payload));
 +
 +    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
 +    responses.add(response);
 +    parts.add(new ODataResponsePart(responses, false));
 +
 +    ODataResponse changeSetResponse = new ODataResponse();
 +    changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
 +    changeSetResponse.setHeader(HttpHeader.CONTENT_ID, "1");
 +    responses = new ArrayList<ODataResponse>(1);
 +    responses.add(changeSetResponse);
 +    parts.add(new ODataResponsePart(responses, true));
 +
 +    BatchResponseSerializer serializer = new BatchResponseSerializer();
 +    final InputStream content = serializer.serialize(parts, BOUNDARY);
 +    assertNotNull(content);
 +    final BatchLineReader reader =
 +            new BatchLineReader(content);
 +    final List<String> body = reader.toList();
 +    reader.close();
 +
 +    int line = 0;
 +    assertEquals(24, body.size());
 +    assertTrue(body.get(line++).contains("--batch_"));
 +    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
 +    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals("HTTP/1.1 200 OK" + CRLF, body.get(line++));
 +    assertEquals("Content-Type: application/json; charset=iso-8859-1" + CRLF, body.get(line++));
 +    assertEquals("Content-Length: 15" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals("Wälter Winter" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertTrue(body.get(line++).contains("--batch_"));
 +    assertTrue(body.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
 +    assertEquals(CRLF, body.get(line++));
 +    assertTrue(body.get(line++).contains("--changeset_"));
 +    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
 +    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
 +    assertEquals("Content-ID: 1" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals("HTTP/1.1 204 No Content" + CRLF, body.get(line++));
 +    assertEquals("Content-Length: 0" + CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertEquals(CRLF, body.get(line++));
 +    assertTrue(body.get(line++).contains("--changeset_"));
-     assertTrue(body.get(line++).contains("--batch_"));
++    assertTrue(body.get(line).contains("--batch_"));
    }
  
    @Test
@@@ -362,7 -147,7 +363,7 @@@
      assertEquals(CRLF, body.get(line++));
      assertEquals(CRLF, body.get(line++));
      assertTrue(body.get(line++).contains("--changeset_"));
--    assertTrue(body.get(line++).contains("--batch_"));
++    assertTrue(body.get(line).contains("--batch_"));
    }
  
    @Test
@@@ -397,7 -182,7 +398,54 @@@
      assertEquals("Content-Length: 13" + CRLF, body.get(line++));
      assertEquals(CRLF, body.get(line++));
      assertEquals("Walter Winter" + CRLF, body.get(line++));
++    assertTrue(body.get(line).contains("--batch_"));
++  }
++
++  @Test
++  public void testResponseVeryLargeHeader() throws Exception {
++    List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
++    ODataResponse response = new ODataResponse();
++    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
++    response.setHeader(HttpHeader.CONTENT_TYPE, "application/json");
++    final String chValue = generateTestData(20000);
++    response.setHeader("Custom-Header", chValue);
++    response.setContent(IOUtils.toInputStream("Walter Winter"));
++
++    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
++    responses.add(response);
++    parts.add(new ODataResponsePart(responses, false));
++
++    final BatchResponseSerializer serializer = new BatchResponseSerializer();
++    final InputStream content = serializer.serialize(parts, BOUNDARY);
++
++    assertNotNull(content);
++    final BatchLineReader reader =
++            new BatchLineReader(content);
++    final List<String> body = reader.toList();
++    reader.close();
++
++    int line = 0;
++    assertEquals(11, body.size());
      assertTrue(body.get(line++).contains("--batch_"));
++    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
++    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
++    assertEquals(CRLF, body.get(line++));
++    assertEquals("HTTP/1.1 200 OK" + CRLF, body.get(line++));
++    assertEquals("Custom-Header: " + chValue + CRLF, body.get(line++));
++    assertEquals("Content-Type: application/json" + CRLF, body.get(line++));
++    assertEquals("Content-Length: 13" + CRLF, body.get(line++));
++    assertEquals(CRLF, body.get(line++));
++    assertEquals("Walter Winter" + CRLF, body.get(line++));
++    assertTrue(body.get(line).contains("--batch_"));
++  }
++
++  private String generateTestData(int amount) {
++    StringBuilder sb = new StringBuilder();
++    Random r = new Random();
++    for (int j = 0; j < amount; j++) {
++      sb.append((char)(65 + r.nextInt(25)));
++    }
++    return sb.toString();
    }
  
    @Test
@@@ -436,6 -221,6 +484,6 @@@
      assertEquals(CRLF, body.get(line++));
      assertEquals(CRLF, body.get(line++));
      assertTrue(body.get(line++).contains("--changeset_"));
--    assertTrue(body.get(line++).contains("--batch_"));
++    assertTrue(body.get(line).contains("--batch_"));
    }
  }


[2/5] olingo-odata4 git commit: [OLINGO-729] Added separate encoding for header and body

Posted by mi...@apache.org.
[OLINGO-729] Added separate encoding for header and body


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

Branch: refs/heads/master
Commit: 575f369ac7def6f771c7ec67b290b149dff6cfd2
Parents: 925a86d
Author: mibo <mi...@apache.org>
Authored: Wed Jul 8 15:47:40 2015 +0200
Committer: mibo <mi...@apache.org>
Committed: Wed Jul 8 15:47:40 2015 +0200

----------------------------------------------------------------------
 .../deserializer/batch/BatchLineReader.java     | 276 ++++++++++++++
 .../core/deserializer/batch/BatchParser.java    |   2 +-
 .../BufferedReaderIncludingLineEndings.java     | 251 -------------
 .../serializer/BatchResponseSerializer.java     |  18 +-
 .../batchhandler/MockedBatchHandlerTest.java    |  18 +-
 .../deserializer/batch/BatchLineReaderTest.java | 280 ++++++++++++++
 .../BufferedReaderIncludingLineEndingsTest.java | 367 -------------------
 .../serializer/BatchResponseSerializerTest.java | 131 ++++++-
 8 files changed, 687 insertions(+), 656 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/575f369a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
new file mode 100644
index 0000000..c4cee5a
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
@@ -0,0 +1,276 @@
+/*
+ * 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.deserializer.batch;
+
+import org.apache.olingo.commons.api.format.ContentType;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+public class BatchLineReader {
+  private static final byte CR = '\r';
+  private static final byte LF = '\n';
+  private static final int EOF = -1;
+  private static final int BUFFER_SIZE = 8192;
+  private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
+  private static final Charset CS_ISO_8859_1 = Charset.forName("iso-8859-1");
+  private Charset currentCharset = DEFAULT_CHARSET;
+  private String currentBoundary = null;
+//  private boolean readBody = false;
+  private ReadState readState = new ReadState();
+  private InputStream reader;
+  private byte[] buffer;
+  private int offset = 0;
+  private int limit = 0;
+
+  public BatchLineReader(final InputStream reader) {
+    this(reader, BUFFER_SIZE);
+  }
+
+  public BatchLineReader(final InputStream reader, final int bufferSize) {
+    if (bufferSize <= 0) {
+      throw new IllegalArgumentException("Buffer size must be greater than zero.");
+    }
+
+    this.reader = reader;
+    buffer = new byte[bufferSize];
+  }
+
+  public void close() throws IOException {
+    reader.close();
+  }
+
+  public List<String> toList() throws IOException {
+    final List<String> result = new ArrayList<String>();
+    String currentLine = readLine();
+    if(currentLine != null) {
+      currentBoundary = currentLine.trim();
+      result.add(currentLine);
+
+      while ((currentLine = readLine()) != null) {
+        result.add(currentLine);
+      }
+    }
+    return result;
+  }
+
+  public List<Line> toLineList() throws IOException {
+    final List<Line> result = new ArrayList<Line>();
+    String currentLine = readLine();
+    if(currentLine != null) {
+      currentBoundary = currentLine.trim();
+      int counter = 1;
+      result.add(new Line(currentLine, counter++));
+
+      while ((currentLine = readLine()) != null) {
+        result.add(new Line(currentLine, counter++));
+      }
+    }
+
+    return result;
+  }
+
+  int read(final byte[] byteBuffer, final int bufferOffset, final int length) throws IOException {
+    if ((bufferOffset + length) > byteBuffer.length) {
+      throw new IndexOutOfBoundsException("Buffer is too small");
+    }
+
+    if (length < 0 || bufferOffset < 0) {
+      throw new IndexOutOfBoundsException("Offset and length must be grater than zero");
+    }
+
+    // Check if buffer is filled. Return if EOF is reached
+    // Is buffer refill required
+    if (limit == offset || isEOF()) {
+      fillBuffer();
+
+      if (isEOF()) {
+        return EOF;
+      }
+    }
+
+    int bytesRead = 0;
+    int bytesToRead = length;
+    int currentOutputOffset = bufferOffset;
+
+    while (bytesToRead != 0) {
+      // Is buffer refill required?
+      if (limit == offset) {
+        fillBuffer();
+
+        if (isEOF()) {
+          bytesToRead = 0;
+        }
+      }
+
+      if (bytesToRead > 0) {
+        int readByte = Math.min(limit - offset, bytesToRead);
+        bytesRead += readByte;
+        bytesToRead -= readByte;
+
+        for (int i = 0; i < readByte; i++) {
+          byteBuffer[currentOutputOffset++] = buffer[offset++];
+        }
+      }
+    }
+
+    return bytesRead;
+  }
+
+  private void updateCurrentCharset(String currentLine) {
+    // TODO: mibo: Improve this method
+    if(currentLine != null) {
+      if(currentLine.startsWith("Content-Type:")) {
+//        if(currentLine.contains(ContentType.PARAMETER_CHARSET)) {
+        currentLine = currentLine.substring(13, currentLine.length() - 2).trim();
+        ContentType t = ContentType.parse(currentLine);
+        if (t != null) {
+          String charsetString = t.getParameter(ContentType.PARAMETER_CHARSET);
+          if (charsetString != null) {
+            currentCharset = Charset.forName(charsetString);
+          } else {
+            currentCharset = DEFAULT_CHARSET;
+          }
+          // boundary
+          String boundary = t.getParameter("boundary");
+          if (boundary != null) {
+            currentBoundary = "--" + boundary;
+          }
+        }
+      } else if("\r\n".equals(currentLine)) {
+        readState.foundLinebreak();
+      } else if(isBoundary(currentLine)) {
+        readState.foundBoundary();
+//        if(readState.isReadBody()) {
+//          currentCharset = CS_ISO_8859_1;
+//        }
+      }
+    }
+  }
+
+  private class ReadState {
+    private int state = 0;
+
+    public void foundLinebreak() {
+      state++;
+    }
+    public void foundBoundary() {
+      state = 0;
+    }
+    public boolean isReadBody() {
+      return state >= 2;
+    }
+    public boolean isReadHeader() {
+      return state < 2;
+    }
+
+    @Override
+    public String toString() {
+      return String.valueOf(state);
+    }
+  }
+
+  private boolean isBoundary(String currentLine) {
+    if((currentBoundary + "\r\n").equals(currentLine)) {
+      return true;
+    } else if((currentBoundary + "--\r\n").equals(currentLine)) {
+      return true;
+    }
+    return false;
+  }
+
+  String readLine() throws IOException {
+    if (limit == EOF) {
+      return null;
+    }
+
+    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
+    boolean foundLineEnd = false; // EOF will be considered as line ending
+
+    while (!foundLineEnd) {
+      // Is buffer refill required?
+      if (limit == offset) {
+        if (fillBuffer() == EOF) {
+          foundLineEnd = true;
+        }
+      }
+
+      if (!foundLineEnd) {
+        byte currentChar = this.buffer[offset++];
+        if(!buffer.hasRemaining()) {
+          buffer.flip();
+          ByteBuffer tmp = ByteBuffer.allocate(buffer.limit() *2);
+          tmp.put(buffer);
+          buffer = tmp;
+        }
+        buffer.put(currentChar);
+
+        if (currentChar == LF) {
+          foundLineEnd = true;
+        } else if (currentChar == CR) {
+          foundLineEnd = true;
+
+          // Check next char. Consume \n if available
+          // Is buffer refill required?
+          if (limit == offset) {
+            fillBuffer();
+          }
+
+          // Check if there is at least one character
+          if (limit != EOF && this.buffer[offset] == LF) {
+            buffer.put(LF);
+            offset++;
+          }
+        }
+      }
+    }
+
+    if(buffer.position() == 0) {
+      return null;
+    } else {
+      String currentLine;
+      if(readState.isReadBody()) {
+        currentLine = new String(buffer.array(), 0, buffer.position(), getCurrentCharset());
+      } else {
+        currentLine = new String(buffer.array(), 0, buffer.position(), CS_ISO_8859_1);
+      }
+      updateCurrentCharset(currentLine);
+      return currentLine;
+    }
+  }
+
+  private boolean isEOF() {
+    return limit == EOF;
+  }
+
+  private int fillBuffer() throws IOException {
+    limit = reader.read(buffer, 0, buffer.length);
+    offset = 0;
+
+    return limit;
+  }
+
+  private Charset getCurrentCharset() {
+    return currentCharset;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/575f369a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchParser.java
index 731437a..3aeb1b5 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchParser.java
@@ -73,7 +73,7 @@ public class BatchParser {
 
   private List<List<Line>> splitBodyParts(final InputStream in, final String boundary) throws IOException,
       BatchDeserializerException {
-    final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(in);
+    final BatchLineReader reader = new BatchLineReader(in);
     final List<Line> message = reader.toLineList();
     reader.close();
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/575f369a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndings.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndings.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndings.java
deleted file mode 100644
index a36b86b..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndings.java
+++ /dev/null
@@ -1,251 +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.deserializer.batch;
-
-import org.apache.olingo.commons.api.format.ContentType;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-
-public class BufferedReaderIncludingLineEndings {
-  private static final byte CR = '\r';
-  private static final byte LF = '\n';
-  private static final int EOF = -1;
-  private static final int BUFFER_SIZE = 8192;
-  public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
-  private InputStream reader;
-  private byte[] buffer;
-  private int offset = 0;
-  private int limit = 0;
-
-  public BufferedReaderIncludingLineEndings(final InputStream reader) {
-    this(reader, BUFFER_SIZE);
-  }
-
-  public BufferedReaderIncludingLineEndings(final InputStream reader, final int bufferSize) {
-    if (bufferSize <= 0) {
-      throw new IllegalArgumentException("Buffer size must be greater than zero.");
-    }
-
-    this.reader = reader;
-    buffer = new byte[bufferSize];
-  }
-
-  public int read(final byte[] byteBuffer, final int bufferOffset, final int length) throws IOException {
-    if ((bufferOffset + length) > byteBuffer.length) {
-      throw new IndexOutOfBoundsException("Buffer is too small");
-    }
-
-    if (length < 0 || bufferOffset < 0) {
-      throw new IndexOutOfBoundsException("Offset and length must be grater than zero");
-    }
-
-    // Check if buffer is filled. Return if EOF is reached
-    // Is buffer refill required
-    if (limit == offset || isEOF()) {
-      fillBuffer();
-
-      if (isEOF()) {
-        return EOF;
-      }
-    }
-
-    int bytesRead = 0;
-    int bytesToRead = length;
-    int currentOutputOffset = bufferOffset;
-
-    while (bytesToRead != 0) {
-      // Is buffer refill required?
-      if (limit == offset) {
-        fillBuffer();
-
-        if (isEOF()) {
-          bytesToRead = 0;
-        }
-      }
-
-      if (bytesToRead > 0) {
-        int readByte = Math.min(limit - offset, bytesToRead);
-        bytesRead += readByte;
-        bytesToRead -= readByte;
-
-        for (int i = 0; i < readByte; i++) {
-          byteBuffer[currentOutputOffset++] = buffer[offset++];
-        }
-      }
-    }
-
-    return bytesRead;
-  }
-
-  public List<String> toList() throws IOException {
-    final List<String> result = new ArrayList<String>();
-    String currentLine;
-
-    while ((currentLine = readLine()) != null) {
-      result.add(currentLine);
-    }
-
-    return result;
-  }
-
-  private Charset currentCharset = DEFAULT_CHARSET;
-
-  private void updateCurrentCharset(String currentLine) {
-    if(currentLine != null) {
-      if(currentLine.startsWith("Content-Type:") && currentLine.contains(ContentType.PARAMETER_CHARSET)) {
-        currentLine = currentLine.substring(13, currentLine.length()-2).trim();
-        ContentType t = ContentType.parse(currentLine);
-        if(t != null) {
-          String charsetString = t.getParameter(ContentType.PARAMETER_CHARSET);
-          currentCharset = Charset.forName(charsetString);
-        }
-      } else if(isEndBoundary(currentLine)) {
-        currentCharset = Charset.forName("us-ascii");
-      }
-    }
-  }
-
-  private boolean isEndBoundary(String currentLine) {
-    return false;
-  }
-
-  public List<Line> toLineList() throws IOException {
-    final List<Line> result = new ArrayList<Line>();
-    String currentLine;
-    int counter = 1;
-
-    while ((currentLine = readLine()) != null) {
-      result.add(new Line(currentLine, counter++));
-    }
-
-    return result;
-  }
-
-  public String readLine() throws IOException {
-    if (limit == EOF) {
-      return null;
-    }
-
-    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
-    boolean foundLineEnd = false; // EOF will be considered as line ending
-
-    while (!foundLineEnd) {
-      // Is buffer refill required?
-      if (limit == offset) {
-        if (fillBuffer() == EOF) {
-          foundLineEnd = true;
-        }
-      }
-
-      if (!foundLineEnd) {
-        byte currentChar = this.buffer[offset++];
-        if(!buffer.hasRemaining()) {
-          buffer.flip();
-          ByteBuffer tmp = ByteBuffer.allocate(buffer.limit() *2);
-          tmp.put(buffer);
-          buffer = tmp;
-        }
-        buffer.put(currentChar);
-
-        if (currentChar == LF) {
-          foundLineEnd = true;
-        } else if (currentChar == CR) {
-          foundLineEnd = true;
-
-          // Check next char. Consume \n if available
-          // Is buffer refill required?
-          if (limit == offset) {
-            fillBuffer();
-          }
-
-          // Check if there is at least one character
-          if (limit != EOF && this.buffer[offset] == LF) {
-            buffer.put(LF);
-            offset++;
-          }
-        }
-      }
-    }
-
-    if(buffer.position() == 0) {
-      return null;
-    } else {
-      String currentLine = new String(buffer.array(), 0, buffer.position(), getCurrentCharset());
-      updateCurrentCharset(currentLine);
-      return currentLine;
-    }
-  }
-
-  public void close() throws IOException {
-    reader.close();
-  }
-
-  public long skip(final long n) throws IOException {
-    if (n == 0) {
-      return 0;
-    } else if (n < 0) {
-      throw new IllegalArgumentException("skip value is negative");
-    } else {
-      long charactersToSkip = n;
-      long charactersSkiped = 0;
-
-      while (charactersToSkip != 0) {
-        // Is buffer refill required?
-        if (limit == offset) {
-          fillBuffer();
-
-          if (isEOF()) {
-            charactersToSkip = 0;
-          }
-        }
-
-        // Check if more characters are available
-        if (!isEOF()) {
-          int skipChars = (int) Math.min(limit - offset, charactersToSkip);
-
-          charactersSkiped += skipChars;
-          charactersToSkip -= skipChars;
-          offset += skipChars;
-        }
-      }
-
-      return charactersSkiped;
-    }
-  }
-
-  private boolean isEOF() {
-    return limit == EOF;
-  }
-
-  private int fillBuffer() throws IOException {
-    limit = reader.read(buffer, 0, buffer.length);
-    offset = 0;
-
-    return limit;
-  }
-
-  private Charset getCurrentCharset() {
-    return currentCharset;
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/575f369a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
index e277b59..28d7c73 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
@@ -29,7 +29,6 @@ import java.util.Map;
 import java.util.UUID;
 
 import org.apache.olingo.commons.api.ODataRuntimeException;
-import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.api.http.HttpContentType;
 import org.apache.olingo.commons.api.http.HttpHeader;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
@@ -165,6 +164,7 @@ public class BatchResponseSerializer {
 
   private class BodyBuilder {
     private final Charset CHARSET_UTF_8 = Charset.forName("utf-8");
+    private final Charset CHARSET_ISO_8859_1 = Charset.forName("iso-8859-1");
     private ByteBuffer buffer = ByteBuffer.allocate(8192);
     private boolean isClosed = false;
 
@@ -177,7 +177,9 @@ public class BatchResponseSerializer {
     }
 
     public BodyBuilder append(String string) {
-      byte [] b = string.getBytes(CHARSET_UTF_8);
+      // TODO: mibo: check used charset
+//      byte [] b = string.getBytes(CHARSET_UTF_8);
+      byte [] b = string.getBytes(CHARSET_ISO_8859_1);
       put(b);
       return this;
     }
@@ -212,22 +214,10 @@ public class BatchResponseSerializer {
   }
 
   private class Body {
-    private final Charset CHARSET_DEFAULT = Charset.forName("utf-8");
     private final byte[] content;
-    private Charset charset = CHARSET_DEFAULT;
 
     public Body(ODataResponse response) {
       this.content = getBody(response);
-      String contentType = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
-      if(contentType != null) {
-        ContentType ct = ContentType.create(contentType);
-        if(ct != null) {
-          String usedCharset = ct.getParameter(ContentType.PARAMETER_CHARSET);
-          if(usedCharset != null) {
-            this.charset = Charset.forName(usedCharset);
-          }
-        }
-      }
     }
 
     public int getLength() {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/575f369a/lib/server-core/src/test/java/org/apache/olingo/server/core/batchhandler/MockedBatchHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/batchhandler/MockedBatchHandlerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/batchhandler/MockedBatchHandlerTest.java
index 3e4e610..7d13d8a 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/batchhandler/MockedBatchHandlerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/batchhandler/MockedBatchHandlerTest.java
@@ -53,7 +53,7 @@ import org.apache.olingo.server.api.processor.BatchProcessor;
 import org.apache.olingo.server.api.serializer.BatchSerializerException;
 import org.apache.olingo.server.core.ODataHandler;
 import org.apache.olingo.server.core.deserializer.batch.BatchParserCommon;
-import org.apache.olingo.server.core.deserializer.batch.BufferedReaderIncludingLineEndings;
+import org.apache.olingo.server.core.deserializer.batch.BatchLineReader;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
@@ -148,8 +148,8 @@ public class MockedBatchHandlerTest {
 
     batchHandler.process(request, response, true);
 
-    BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(response.getContent());
+    BatchLineReader reader =
+        new BatchLineReader(response.getContent());
 
     final List<String> responseContent = reader.toList();
     reader.close();
@@ -219,8 +219,8 @@ public class MockedBatchHandlerTest {
 
     batchHandler.process(request, response, true);
 
-    BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(response.getContent());
+    BatchLineReader reader =
+        new BatchLineReader(response.getContent());
 
     final List<String> responseContent = reader.toList();
     int line = 0;
@@ -298,8 +298,8 @@ public class MockedBatchHandlerTest {
 
     batchHandler.process(request, response, true);
 
-    BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(response.getContent());
+    BatchLineReader reader =
+        new BatchLineReader(response.getContent());
 
     final List<String> responseContent = reader.toList();
     reader.close();
@@ -416,8 +416,8 @@ public class MockedBatchHandlerTest {
 
     batchHandler.process(request, response, true);
 
-    BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(response.getContent());
+    BatchLineReader reader =
+        new BatchLineReader(response.getContent());
 
     final List<String> responseContent = reader.toList();
     reader.close();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/575f369a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
new file mode 100644
index 0000000..3d2507c
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReaderTest.java
@@ -0,0 +1,280 @@
+/*
+ * 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.deserializer.batch;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.util.List;
+
+import org.junit.Test;
+
+public class BatchLineReaderTest {
+
+  private static final String TEXT_COMBINED = "Test\r" +
+      "Test2\r\n" +
+      "Test3\n" +
+      "Test4\r" +
+      "\r" +
+      "\r\n" +
+      "\r\n" +
+      "Test5\n" +
+      "Test6\r\n" +
+      "Test7\n" +
+      "\n";
+
+  private static final String TEXT_EMPTY = "";
+
+  @Test
+  public void testSimpleText() throws Exception {
+    final String TEXT = "Test";
+    BatchLineReader reader = create(TEXT);
+
+    assertEquals(TEXT, reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testNoText() throws Exception {
+    final String TEXT = "";
+    BatchLineReader reader = create(TEXT);
+
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testNoBytes() throws Exception {
+    BatchLineReader reader =
+        new BatchLineReader(new ByteArrayInputStream(new byte[0]));
+
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testCRLF() throws Exception {
+    final String TEXT = "Test\r\n" +
+        "Test2";
+
+    BatchLineReader reader = create(TEXT);
+
+    assertEquals("Test\r\n", reader.readLine());
+    assertEquals("Test2", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testLF() throws Exception {
+    final String TEXT = "Test\n" +
+        "Test2";
+
+    BatchLineReader reader = create(TEXT);
+
+    assertEquals("Test\n", reader.readLine());
+    assertEquals("Test2", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testCR() throws Exception {
+    final String TEXT = "Test\r" +
+        "Test2";
+
+    BatchLineReader reader = create(TEXT);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("Test2", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testCombined() throws Exception {
+    BatchLineReader reader = create(TEXT_COMBINED);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("Test2\r\n", reader.readLine());
+    assertEquals("Test3\n", reader.readLine());
+    assertEquals("Test4\r", reader.readLine());
+    assertEquals("\r", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("Test5\n", reader.readLine());
+    assertEquals("Test6\r\n", reader.readLine());
+    assertEquals("Test7\n", reader.readLine());
+    assertEquals("\n", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testCombinedBufferSizeTwo() throws Exception {
+    BatchLineReader reader = create(TEXT_COMBINED, 2);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("Test2\r\n", reader.readLine());
+    assertEquals("Test3\n", reader.readLine());
+    assertEquals("Test4\r", reader.readLine());
+    assertEquals("\r", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("Test5\n", reader.readLine());
+    assertEquals("Test6\r\n", reader.readLine());
+    assertEquals("Test7\n", reader.readLine());
+    assertEquals("\n", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testCombinedBufferSizeOne() throws Exception {
+    final String TEXT = "Test\r" +
+        "Test2\r\n" +
+        "Test3\n" +
+        "Test4\r" +
+        "\r" +
+        "\r\n" +
+        "\r\n" +
+        "Test5\n" +
+        "Test6\r\n" +
+        "Test7\n" +
+        "\r\n";
+
+    BatchLineReader reader = create(TEXT, 1);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("Test2\r\n", reader.readLine());
+    assertEquals("Test3\n", reader.readLine());
+    assertEquals("Test4\r", reader.readLine());
+    assertEquals("\r", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertEquals("Test5\n", reader.readLine());
+    assertEquals("Test6\r\n", reader.readLine());
+    assertEquals("Test7\n", reader.readLine());
+    assertEquals("\r\n", reader.readLine());
+    assertNull(reader.readLine());
+    assertNull(reader.readLine());
+
+    reader.close();
+  }
+
+  @Test
+  public void testDoubleLF() throws Exception {
+    final String TEXT = "Test\r" +
+        "\r";
+
+    BatchLineReader reader = create(TEXT, 1);
+
+    assertEquals("Test\r", reader.readLine());
+    assertEquals("\r", reader.readLine());
+    reader.close();
+  }
+
+  @Test
+  public void testReadMoreBufferCapacityThanCharacterAvailable() throws Exception {
+    final String TEXT = "Foo";
+    byte[] buffer = new byte[20];
+
+    BatchLineReader reader = create(TEXT);
+    assertEquals(3, reader.read(buffer, 0, 20));
+    assertEquals(-1, reader.read(buffer, 0, 20));
+    reader.close();
+
+    BatchLineReader readerBufferOne = create(TEXT, 1);
+    assertEquals(3, readerBufferOne.read(buffer, 0, 20));
+    assertEquals(-1, readerBufferOne.read(buffer, 0, 20));
+    readerBufferOne.close();
+  }
+
+  @Test
+  public void testLineEqualsAndHashCode() {
+    Line l1 = new Line("The first line", 1);
+    Line l2 = new Line("The first line", 1);
+    Line l3 = new Line("The second line", 2);
+
+    assertEquals(l1, l2);
+    assertFalse(l1.equals(l3));
+    assertTrue(l1.hashCode() != l3.hashCode());
+  }
+
+//  @Test(expected = IllegalArgumentException.class)
+//  public void testSkipNegative() throws Exception {
+//    BufferedReaderIncludingLineEndings reader = create("123");
+//    reader.skip(-1);
+//  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testFailBufferSizeZero() throws Exception {
+    BatchLineReader reader = create(TEXT_EMPTY, 0);
+    reader.close();
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testFailBufferSizeNegative() throws Exception {
+    BatchLineReader reader = create(TEXT_EMPTY, -1);
+    reader.close();
+  }
+
+  @Test
+  public void testToList() throws Exception {
+    BatchLineReader reader = create(TEXT_COMBINED);
+    List<Line> stringList = reader.toLineList();
+
+    assertEquals(11, stringList.size());
+    assertEquals("Test\r", stringList.get(0).toString());
+    assertEquals("Test2\r\n", stringList.get(1).toString());
+    assertEquals("Test3\n", stringList.get(2).toString());
+    assertEquals("Test4\r", stringList.get(3).toString());
+    assertEquals("\r", stringList.get(4).toString());
+    assertEquals("\r\n", stringList.get(5).toString());
+    assertEquals("\r\n", stringList.get(6).toString());
+    assertEquals("Test5\n", stringList.get(7).toString());
+    assertEquals("Test6\r\n", stringList.get(8).toString());
+    assertEquals("Test7\n", stringList.get(9).toString());
+    assertEquals("\n", stringList.get(10).toString());
+    reader.close();
+  }
+
+  private BatchLineReader create(final String inputString) throws Exception {
+    return new BatchLineReader(new ByteArrayInputStream(inputString
+        .getBytes("UTF-8")));
+  }
+
+  private BatchLineReader create(final String inputString, final int bufferSize) throws Exception {
+    return new BatchLineReader(new ByteArrayInputStream(inputString
+        .getBytes("UTF-8")), bufferSize);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/575f369a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndingsTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndingsTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndingsTest.java
deleted file mode 100644
index d0d2fa8..0000000
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/deserializer/batch/BufferedReaderIncludingLineEndingsTest.java
+++ /dev/null
@@ -1,367 +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.deserializer.batch;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.util.List;
-
-import org.junit.Test;
-
-public class BufferedReaderIncludingLineEndingsTest {
-
-  private static final String TEXT_COMBINED = "Test\r" +
-      "Test2\r\n" +
-      "Test3\n" +
-      "Test4\r" +
-      "\r" +
-      "\r\n" +
-      "\r\n" +
-      "Test5\n" +
-      "Test6\r\n" +
-      "Test7\n" +
-      "\n";
-
-  private static final String TEXT_SMALL = "Test\r" +
-      "123";
-  private static final String TEXT_EMPTY = "";
-
-  @Test
-  public void testSimpleText() throws Exception {
-    final String TEXT = "Test";
-    BufferedReaderIncludingLineEndings reader = create(TEXT);
-
-    assertEquals(TEXT, reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testNoText() throws Exception {
-    final String TEXT = "";
-    BufferedReaderIncludingLineEndings reader = create(TEXT);
-
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testNoBytes() throws Exception {
-    BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(new ByteArrayInputStream(new byte[0]));
-
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testCRLF() throws Exception {
-    final String TEXT = "Test\r\n" +
-        "Test2";
-
-    BufferedReaderIncludingLineEndings reader = create(TEXT);
-
-    assertEquals("Test\r\n", reader.readLine());
-    assertEquals("Test2", reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testLF() throws Exception {
-    final String TEXT = "Test\n" +
-        "Test2";
-
-    BufferedReaderIncludingLineEndings reader = create(TEXT);
-
-    assertEquals("Test\n", reader.readLine());
-    assertEquals("Test2", reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testCR() throws Exception {
-    final String TEXT = "Test\r" +
-        "Test2";
-
-    BufferedReaderIncludingLineEndings reader = create(TEXT);
-
-    assertEquals("Test\r", reader.readLine());
-    assertEquals("Test2", reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testCombined() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_COMBINED);
-
-    assertEquals("Test\r", reader.readLine());
-    assertEquals("Test2\r\n", reader.readLine());
-    assertEquals("Test3\n", reader.readLine());
-    assertEquals("Test4\r", reader.readLine());
-    assertEquals("\r", reader.readLine());
-    assertEquals("\r\n", reader.readLine());
-    assertEquals("\r\n", reader.readLine());
-    assertEquals("Test5\n", reader.readLine());
-    assertEquals("Test6\r\n", reader.readLine());
-    assertEquals("Test7\n", reader.readLine());
-    assertEquals("\n", reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testCombinedBufferSizeTwo() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_COMBINED, 2);
-
-    assertEquals("Test\r", reader.readLine());
-    assertEquals("Test2\r\n", reader.readLine());
-    assertEquals("Test3\n", reader.readLine());
-    assertEquals("Test4\r", reader.readLine());
-    assertEquals("\r", reader.readLine());
-    assertEquals("\r\n", reader.readLine());
-    assertEquals("\r\n", reader.readLine());
-    assertEquals("Test5\n", reader.readLine());
-    assertEquals("Test6\r\n", reader.readLine());
-    assertEquals("Test7\n", reader.readLine());
-    assertEquals("\n", reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testCombinedBufferSizeOne() throws Exception {
-    final String TEXT = "Test\r" +
-        "Test2\r\n" +
-        "Test3\n" +
-        "Test4\r" +
-        "\r" +
-        "\r\n" +
-        "\r\n" +
-        "Test5\n" +
-        "Test6\r\n" +
-        "Test7\n" +
-        "\r\n";
-
-    BufferedReaderIncludingLineEndings reader = create(TEXT, 1);
-
-    assertEquals("Test\r", reader.readLine());
-    assertEquals("Test2\r\n", reader.readLine());
-    assertEquals("Test3\n", reader.readLine());
-    assertEquals("Test4\r", reader.readLine());
-    assertEquals("\r", reader.readLine());
-    assertEquals("\r\n", reader.readLine());
-    assertEquals("\r\n", reader.readLine());
-    assertEquals("Test5\n", reader.readLine());
-    assertEquals("Test6\r\n", reader.readLine());
-    assertEquals("Test7\n", reader.readLine());
-    assertEquals("\r\n", reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-
-    reader.close();
-  }
-
-  @Test
-  public void testDoubleLF() throws Exception {
-    final String TEXT = "Test\r" +
-        "\r";
-
-    BufferedReaderIncludingLineEndings reader = create(TEXT, 1);
-
-    assertEquals("Test\r", reader.readLine());
-    assertEquals("\r", reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testSkipSimple() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
-
-    assertEquals(5, reader.skip(5)); // Test\r
-    assertEquals("123", reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testSkipBufferOne() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL, 1);
-
-    assertEquals(5, reader.skip(5)); // Test\r
-    assertEquals("123", reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testReadThanSkip() throws Exception {
-    final String TEXT = "Test\r" +
-        "\r" +
-        "123";
-
-    BufferedReaderIncludingLineEndings reader = create(TEXT);
-
-    assertEquals("Test\r", reader.readLine());
-    assertEquals(1, reader.skip(1)); // Test\r
-    assertEquals("123", reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-  @Test
-  public void testReadMoreBufferCapacityThanCharacterAvailable() throws Exception {
-    final String TEXT = "Foo";
-    byte[] buffer = new byte[20];
-
-    BufferedReaderIncludingLineEndings reader = create(TEXT);
-    assertEquals(3, reader.read(buffer, 0, 20));
-    assertEquals(-1, reader.read(buffer, 0, 20));
-    reader.close();
-
-    BufferedReaderIncludingLineEndings readerBufferOne = create(TEXT, 1);
-    assertEquals(3, readerBufferOne.read(buffer, 0, 20));
-    assertEquals(-1, readerBufferOne.read(buffer, 0, 20));
-    readerBufferOne.close();
-  }
-
-  @Test
-  public void testSkipZero() throws Exception {
-    final String TEXT = "Test\r" +
-        "123\r\n";
-
-    BufferedReaderIncludingLineEndings reader = create(TEXT);
-
-    assertEquals(0, reader.skip(0)); // Test\r
-    assertEquals("Test\r", reader.readLine());
-    assertEquals("123\r\n", reader.readLine());
-    assertNull(reader.readLine());
-    assertNull(reader.readLine());
-    reader.close();
-  }
-
-//  @Test
-//  public void testSkipToMuch() throws Exception {
-//    BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
-//
-//    assertEquals(8, reader.skip(10)); // Test\r
-//    assertEquals(null, reader.readLine());
-//    reader.close();
-//  }
-//
-
-  @Test
-  public void testLineEqualsAndHashCode() {
-    Line l1 = new Line("The first line", 1);
-    Line l2 = new Line("The first line", 1);
-    Line l3 = new Line("The second line", 2);
-
-    assertEquals(l1, l2);
-    assertFalse(l1.equals(l3));
-    assertTrue(l1.hashCode() != l3.hashCode());
-  }
-
-//  @Test(expected = IllegalArgumentException.class)
-//  public void testSkipNegative() throws Exception {
-//    BufferedReaderIncludingLineEndings reader = create("123");
-//    reader.skip(-1);
-//  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testFailBufferSizeZero() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY, 0);
-    reader.close();
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testFailBufferSizeNegative() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY, -1);
-    reader.close();
-  }
-
-//  @Test
-//  public void testMarkSupoorted() throws Exception {
-//    BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY);
-//
-//    assertEquals(false, reader.markSupported());
-//    reader.close();
-//  }
-
-//  @Test(expected = Exception.class)
-//  public void testFailMark() throws Exception {
-//    BufferedReaderIncludingLineEndings reader = create("123");
-//
-//    reader.mark(1);
-//  }
-//
-//  @Test(expected = Exception.class)
-//  public void testFailReset() throws Exception {
-//    BufferedReaderIncludingLineEndings reader = create("123");
-//
-//    reader.reset();
-//  }
-
-  @Test
-  public void testToList() throws Exception {
-    BufferedReaderIncludingLineEndings reader = create(TEXT_COMBINED);
-    List<Line> stringList = reader.toLineList();
-
-    assertEquals(11, stringList.size());
-    assertEquals("Test\r", stringList.get(0).toString());
-    assertEquals("Test2\r\n", stringList.get(1).toString());
-    assertEquals("Test3\n", stringList.get(2).toString());
-    assertEquals("Test4\r", stringList.get(3).toString());
-    assertEquals("\r", stringList.get(4).toString());
-    assertEquals("\r\n", stringList.get(5).toString());
-    assertEquals("\r\n", stringList.get(6).toString());
-    assertEquals("Test5\n", stringList.get(7).toString());
-    assertEquals("Test6\r\n", stringList.get(8).toString());
-    assertEquals("Test7\n", stringList.get(9).toString());
-    assertEquals("\n", stringList.get(10).toString());
-    reader.close();
-  }
-
-  private BufferedReaderIncludingLineEndings create(final String inputString) throws Exception {
-    return new BufferedReaderIncludingLineEndings(new ByteArrayInputStream(inputString
-        .getBytes("UTF-8")));
-  }
-
-  private BufferedReaderIncludingLineEndings create(final String inputString, final int bufferSize) throws Exception {
-    return new BufferedReaderIncludingLineEndings(new ByteArrayInputStream(inputString
-        .getBytes("UTF-8")), bufferSize);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/575f369a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
index 29d0329..9d3ebee 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
@@ -34,13 +35,16 @@ import org.apache.olingo.commons.api.http.HttpHeader;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
 import org.apache.olingo.server.api.ODataResponse;
 import org.apache.olingo.server.api.deserializer.batch.ODataResponsePart;
-import org.apache.olingo.server.core.deserializer.batch.BufferedReaderIncludingLineEndings;
+import org.apache.olingo.server.core.deserializer.batch.BatchLineReader;
 import org.junit.Test;
 
 public class BatchResponseSerializerTest {
   private static final String CRLF = "\r\n";
   private static final String BOUNDARY = "batch_" + UUID.randomUUID().toString();
 
+  private static final Charset CS_ISO_8859_1 = Charset.forName("iso-8859-1");
+  private static final Charset CS_UTF_8 = Charset.forName("utf-8");
+
   @Test
   public void testBatchResponse() throws Exception {
     final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
@@ -63,8 +67,8 @@ public class BatchResponseSerializerTest {
     BatchResponseSerializer serializer = new BatchResponseSerializer();
     final InputStream content = serializer.serialize(parts, BOUNDARY);
     assertNotNull(content);
-    final BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(content);
+    final BatchLineReader reader =
+        new BatchLineReader(content);
     final List<String> body = reader.toList();
     reader.close();
 
@@ -97,7 +101,7 @@ public class BatchResponseSerializerTest {
   }
 
   @Test
-  public void testBatchResponseUmlauteUtf8() throws Exception {
+  public void testBatchResponseUmlautsUtf8() throws Exception {
     final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
     ODataResponse response = new ODataResponse();
     response.setStatusCode(HttpStatusCode.OK.getStatusCode());
@@ -119,8 +123,8 @@ public class BatchResponseSerializerTest {
     BatchResponseSerializer serializer = new BatchResponseSerializer();
     final InputStream content = serializer.serialize(parts, BOUNDARY);
     assertNotNull(content);
-    final BufferedReaderIncludingLineEndings reader =
-            new BufferedReaderIncludingLineEndings(content);
+    final BatchLineReader reader =
+            new BatchLineReader(content);
     final List<String> body = reader.toList();
     reader.close();
 
@@ -153,6 +157,105 @@ public class BatchResponseSerializerTest {
   }
 
   @Test
+  public void testBatchResponseUmlautsUtf8BodyIsoHeader() throws Exception {
+    final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
+    ODataResponse response = new ODataResponse();
+    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+    response.setHeader(HttpHeader.CONTENT_TYPE,
+        ContentType.APPLICATION_JSON.toContentTypeString() + "; charset=UTF-8");
+    response.setContent(IOUtils.toInputStream("Wälter Winter" + CRLF));
+
+    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+    responses.add(response);
+    parts.add(new ODataResponsePart(responses, false));
+
+    ODataResponse changeSetResponse = new ODataResponse();
+    changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    changeSetResponse.setHeader(HttpHeader.CONTENT_ID, "1");
+
+    byte[] umlauts = "äüö".getBytes(CS_ISO_8859_1);
+    changeSetResponse.setHeader("Custom-Header", new String(umlauts, CS_ISO_8859_1));
+    responses = new ArrayList<ODataResponse>(1);
+    responses.add(changeSetResponse);
+    parts.add(new ODataResponsePart(responses, true));
+
+    BatchResponseSerializer serializer = new BatchResponseSerializer();
+    final InputStream content = serializer.serialize(parts, BOUNDARY);
+    assertNotNull(content);
+    final BatchLineReader reader =
+        new BatchLineReader(content);
+    final List<String> body = reader.toList();
+    reader.close();
+
+    int line = 0;
+    assertEquals(25, body.size());
+    assertTrue(body.get(line++).contains("--batch_"));
+    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
+    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals("HTTP/1.1 200 OK" + CRLF, body.get(line++));
+    assertEquals("Content-Type: application/json; charset=UTF-8" + CRLF, body.get(line++));
+    assertEquals("Content-Length: 16" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals("Wälter Winter" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertTrue(body.get(line++).contains("--batch_"));
+    assertTrue(body.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
+    assertEquals(CRLF, body.get(line++));
+    assertTrue(body.get(line++).contains("--changeset_"));
+    assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
+    assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
+    assertEquals("Content-ID: 1" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals("HTTP/1.1 204 No Content" + CRLF, body.get(line++));
+    assertEquals("Custom-Header: äüö" + CRLF, body.get(line++));
+    assertEquals("Content-Length: 0" + CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertEquals(CRLF, body.get(line++));
+    assertTrue(body.get(line++).contains("--changeset_"));
+    assertTrue(body.get(line++).contains("--batch_"));
+  }
+
+  @Test
+  public void testBatchResponseUmlautsUtf8BodyAndHeader() throws Exception {
+    final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
+    ODataResponse response = new ODataResponse();
+    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+    response.setHeader(HttpHeader.CONTENT_TYPE,
+        ContentType.APPLICATION_JSON.toContentTypeString() + "; charset=UTF-8");
+    response.setContent(IOUtils.toInputStream("Wälter Winter" + CRLF));
+
+    List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+    responses.add(response);
+    parts.add(new ODataResponsePart(responses, false));
+
+    ODataResponse changeSetResponse = new ODataResponse();
+    changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    changeSetResponse.setHeader(HttpHeader.CONTENT_ID, "1");
+
+//    byte[] umlauts = "äüö".getBytes(CS_UTF_8);
+//    changeSetResponse.setHeader("Custom-Header", new String(umlauts, CS_UTF_8));
+    changeSetResponse.setHeader("Custom-Header", "äüö");
+    responses = new ArrayList<ODataResponse>(1);
+    responses.add(changeSetResponse);
+    parts.add(new ODataResponsePart(responses, true));
+
+    BatchResponseSerializer serializer = new BatchResponseSerializer();
+    final InputStream content = serializer.serialize(parts, BOUNDARY);
+    assertNotNull(content);
+    final BatchLineReader reader =
+        new BatchLineReader(content);
+    final List<String> body = reader.toList();
+    reader.close();
+
+    assertEquals(25, body.size());
+    // TODO: check: with latest change in BatchResponseSerializer is not possible
+    // to set header values with UTF-8 (only iso-8859-1)
+//    assertEquals("Custom-Header: äüö" + CRLF, body.get(19));
+    assertEquals("Custom-Header: äüö" + CRLF, body.get(19));
+  }
+
+  @Test
   public void testBatchResponseUmlauteIso() throws Exception {
     final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
     ODataResponse response = new ODataResponse();
@@ -176,8 +279,8 @@ public class BatchResponseSerializerTest {
     BatchResponseSerializer serializer = new BatchResponseSerializer();
     final InputStream content = serializer.serialize(parts, BOUNDARY);
     assertNotNull(content);
-    final BufferedReaderIncludingLineEndings reader =
-            new BufferedReaderIncludingLineEndings(content);
+    final BatchLineReader reader =
+            new BatchLineReader(content);
     final List<String> body = reader.toList();
     reader.close();
 
@@ -231,8 +334,8 @@ public class BatchResponseSerializerTest {
     BatchResponseSerializer serializer = new BatchResponseSerializer();
     final InputStream content = serializer.serialize(parts, BOUNDARY);
     assertNotNull(content);
-    final BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(content);
+    final BatchLineReader reader =
+        new BatchLineReader(content);
     final List<String> body = reader.toList();
     reader.close();
 
@@ -279,8 +382,8 @@ public class BatchResponseSerializerTest {
     final InputStream content = serializer.serialize(parts, BOUNDARY);
 
     assertNotNull(content);
-    final BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(content);
+    final BatchLineReader reader =
+        new BatchLineReader(content);
     final List<String> body = reader.toList();
     reader.close();
 
@@ -314,8 +417,8 @@ public class BatchResponseSerializerTest {
 
     assertNotNull(content);
 
-    final BufferedReaderIncludingLineEndings reader =
-        new BufferedReaderIncludingLineEndings(content);
+    final BatchLineReader reader =
+        new BatchLineReader(content);
     final List<String> body = reader.toList();
     reader.close();
 


[3/5] olingo-odata4 git commit: [OLINGO-729] Minor code clean up

Posted by mi...@apache.org.
[OLINGO-729] Minor code clean up


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

Branch: refs/heads/master
Commit: 3c591da1a0cc0ab400803ca5a57fed6566d993e2
Parents: 575f369
Author: Michael Bolz <mi...@sap.com>
Authored: Thu Jul 9 15:29:48 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Thu Jul 9 15:48:16 2015 +0200

----------------------------------------------------------------------
 .../deserializer/batch/BatchLineReader.java     | 71 ++++++++++----------
 .../serializer/BatchResponseSerializer.java     | 57 ++++++++--------
 .../serializer/BatchResponseSerializerTest.java |  3 +-
 3 files changed, 66 insertions(+), 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3c591da1/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
index c4cee5a..d96a5f5 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/batch/BatchLineReader.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.server.core.deserializer.batch;
 
 import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -34,9 +35,11 @@ public class BatchLineReader {
   private static final int BUFFER_SIZE = 8192;
   private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
   private static final Charset CS_ISO_8859_1 = Charset.forName("iso-8859-1");
+  public static final String BOUNDARY = "boundary";
+  public static final String DOUBLE_DASH = "--";
+  public static final String CRLF = "\r\n";
   private Charset currentCharset = DEFAULT_CHARSET;
   private String currentBoundary = null;
-//  private boolean readBody = false;
   private ReadState readState = new ReadState();
   private InputStream reader;
   private byte[] buffer;
@@ -140,60 +143,34 @@ public class BatchLineReader {
   private void updateCurrentCharset(String currentLine) {
     // TODO: mibo: Improve this method
     if(currentLine != null) {
-      if(currentLine.startsWith("Content-Type:")) {
-//        if(currentLine.contains(ContentType.PARAMETER_CHARSET)) {
+      if(currentLine.startsWith(HttpHeader.CONTENT_TYPE)) {
         currentLine = currentLine.substring(13, currentLine.length() - 2).trim();
-        ContentType t = ContentType.parse(currentLine);
-        if (t != null) {
-          String charsetString = t.getParameter(ContentType.PARAMETER_CHARSET);
+        ContentType ct = ContentType.parse(currentLine);
+        if (ct != null) {
+          String charsetString = ct.getParameter(ContentType.PARAMETER_CHARSET);
           if (charsetString != null) {
             currentCharset = Charset.forName(charsetString);
           } else {
             currentCharset = DEFAULT_CHARSET;
           }
           // boundary
-          String boundary = t.getParameter("boundary");
+          String boundary = ct.getParameter(BOUNDARY);
           if (boundary != null) {
-            currentBoundary = "--" + boundary;
+            currentBoundary = DOUBLE_DASH + boundary;
           }
         }
-      } else if("\r\n".equals(currentLine)) {
+      } else if(CRLF.equals(currentLine)) {
         readState.foundLinebreak();
       } else if(isBoundary(currentLine)) {
         readState.foundBoundary();
-//        if(readState.isReadBody()) {
-//          currentCharset = CS_ISO_8859_1;
-//        }
       }
     }
   }
 
-  private class ReadState {
-    private int state = 0;
-
-    public void foundLinebreak() {
-      state++;
-    }
-    public void foundBoundary() {
-      state = 0;
-    }
-    public boolean isReadBody() {
-      return state >= 2;
-    }
-    public boolean isReadHeader() {
-      return state < 2;
-    }
-
-    @Override
-    public String toString() {
-      return String.valueOf(state);
-    }
-  }
-
   private boolean isBoundary(String currentLine) {
-    if((currentBoundary + "\r\n").equals(currentLine)) {
+    if((currentBoundary + CRLF).equals(currentLine)) {
       return true;
-    } else if((currentBoundary + "--\r\n").equals(currentLine)) {
+    } else if((currentBoundary + DOUBLE_DASH + CRLF).equals(currentLine)) {
       return true;
     }
     return false;
@@ -273,4 +250,26 @@ public class BatchLineReader {
   private Charset getCurrentCharset() {
     return currentCharset;
   }
+
+  /**
+   * Read state indicator (whether currently the <code>body</code> or <code>header</code> part is read).
+   */
+  private class ReadState {
+    private int state = 0;
+
+    public void foundLinebreak() {
+      state++;
+    }
+    public void foundBoundary() {
+      state = 0;
+    }
+    public boolean isReadBody() {
+      return state >= 2;
+    }
+
+    @Override
+    public String toString() {
+      return String.valueOf(state);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3c591da1/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
index 28d7c73..377c5e1 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
@@ -22,7 +22,11 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+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.List;
 import java.util.Map;
@@ -162,8 +166,10 @@ public class BatchResponseSerializer {
     return value + "_" + UUID.randomUUID().toString();
   }
 
+  /**
+   * Builder class to create the body and the header.
+   */
   private class BodyBuilder {
-    private final Charset CHARSET_UTF_8 = Charset.forName("utf-8");
     private final Charset CHARSET_ISO_8859_1 = Charset.forName("iso-8859-1");
     private ByteBuffer buffer = ByteBuffer.allocate(8192);
     private boolean isClosed = false;
@@ -177,8 +183,6 @@ public class BatchResponseSerializer {
     }
 
     public BodyBuilder append(String string) {
-      // TODO: mibo: check used charset
-//      byte [] b = string.getBytes(CHARSET_UTF_8);
       byte [] b = string.getBytes(CHARSET_ISO_8859_1);
       put(b);
       return this;
@@ -207,12 +211,13 @@ public class BatchResponseSerializer {
     }
 
     public String toString() {
-//      byte[] tmp = new byte[buffer.position()];
-//      buffer.get(tmp, 0, buffer.position());
       return new String(buffer.array(), 0, buffer.position());
     }
   }
 
+  /**
+   * Body part which is read and stored as bytes (no charset conversion).
+   */
   private class Body {
     private final byte[] content;
 
@@ -224,31 +229,29 @@ public class BatchResponseSerializer {
       return content.length;
     }
 
-    private byte[] getBody(final ODataResponse response) {
-      final InputStream content = response.getContent();
-      final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-      if (content != null) {
-        byte[] buffer = new byte[BUFFER_SIZE];
-        int n;
-
-        try {
-          while ((n = content.read(buffer, 0, buffer.length)) != -1) {
-            out.write(buffer, 0, n);
-          }
-          out.flush();
-        } catch (IOException e) {
-          throw new ODataRuntimeException(e);
-        }
+    public byte[] getContent() {
+      return content;
+    }
 
-        return out.toByteArray();
-      } else {
+    private byte[] getBody(final ODataResponse response) {
+      if (response == null || response.getContent() == null) {
         return new byte[0];
       }
-    }
 
-    public byte[] getContent() {
-      return content;
+      try {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        ByteBuffer inBuffer = ByteBuffer.allocate(BUFFER_SIZE);
+        ReadableByteChannel ic = Channels.newChannel(response.getContent());
+        WritableByteChannel oc = Channels.newChannel(output);
+        while (ic.read(inBuffer) > 0) {
+          inBuffer.flip();
+          oc.write(inBuffer);
+          inBuffer.rewind();
+        }
+        return output.toByteArray();
+      } catch (IOException e) {
+        throw new ODataRuntimeException("Error on reading request content");
+      }
     }
   }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3c591da1/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
index 9d3ebee..f73479b 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/BatchResponseSerializerTest.java
@@ -43,7 +43,6 @@ public class BatchResponseSerializerTest {
   private static final String BOUNDARY = "batch_" + UUID.randomUUID().toString();
 
   private static final Charset CS_ISO_8859_1 = Charset.forName("iso-8859-1");
-  private static final Charset CS_UTF_8 = Charset.forName("utf-8");
 
   @Test
   public void testBatchResponse() throws Exception {
@@ -256,7 +255,7 @@ public class BatchResponseSerializerTest {
   }
 
   @Test
-  public void testBatchResponseUmlauteIso() throws Exception {
+  public void testBatchResponseUmlautsIso() throws Exception {
     final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
     ODataResponse response = new ODataResponse();
     response.setStatusCode(HttpStatusCode.OK.getStatusCode());