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 c4cee5afe..d96a5f52d 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 body or header 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); + } + } } 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 28d7c73f3..377c5e1d6 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); - } - - return out.toByteArray(); - } else { - return new byte[0]; - } - } - 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"); + } + } } -} +} \ No newline at end of file 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 9d3ebeea6..f73479b0a 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 parts = new ArrayList(); ODataResponse response = new ODataResponse(); response.setStatusCode(HttpStatusCode.OK.getStatusCode());