You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2010/06/04 15:07:08 UTC

svn commit: r951398 [4/4] - in /james/imap/trunk: deployment/src/test/java/org/apache/james/imap/functional/inmemory/ deployment/src/test/java/org/apache/james/imap/functional/jcr/ deployment/src/test/java/org/apache/james/imap/functional/jpa/ jcr/src/...

Added: james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/InputStreamContent.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/InputStreamContent.java?rev=951398&view=auto
==============================================================================
--- james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/InputStreamContent.java (added)
+++ james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/InputStreamContent.java Fri Jun  4 13:07:05 2010
@@ -0,0 +1,79 @@
+/****************************************************************
+ * 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.james.imap.store.streaming;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+
+import org.apache.james.imap.mailbox.Content;
+
+/**
+ * {@link Content} which is stored in a {@link InputStream}
+ *
+ */
+public final class InputStreamContent implements Content{
+
+    private RewindableInputStream in;
+    private long size;
+
+    public InputStreamContent(RewindableInputStream in) throws IOException{
+        this.in = in;
+        this.size = in.available();
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.imap.mailbox.Content#size()
+     */
+    public long size() {
+        return size;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.imap.mailbox.Content#writeTo(java.nio.channels.WritableByteChannel)
+     */
+    public void writeTo(WritableByteChannel channel) throws IOException {
+        
+        try {
+            // rewind the stream before write it to the channel
+            in.rewind();
+        
+            // read all the content of the underlying InputStream in 16384 byte chunks, wrap them
+            // in a ByteBuffer and finally write the Buffer to the channel
+            byte[] buf = new byte[16384];
+            int i = 0;
+            while ((i = in.read(buf)) != -1) {
+                ByteBuffer buffer = ByteBuffer.wrap(buf);
+                // set the limit of the buffer to the returned bytes
+                    buffer.limit(i);
+                    channel.write(buffer);
+            }
+        } finally {
+            // close the stream so temporary files could get delete
+            in.close();
+        }
+        
+    }
+    
+   
+
+}

Added: james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/InputStreamFullContent.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/InputStreamFullContent.java?rev=951398&view=auto
==============================================================================
--- james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/InputStreamFullContent.java (added)
+++ james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/InputStreamFullContent.java Fri Jun  4 13:07:05 2010
@@ -0,0 +1,81 @@
+/****************************************************************
+ * 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.james.imap.store.streaming;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+import java.util.List;
+
+import org.apache.james.imap.mailbox.MessageResult;
+
+
+/**
+ * {@link AbstractFullContent} implementations which uses an {@link InputStream} as source for the 
+ * body content
+ *
+ */
+public class InputStreamFullContent extends AbstractFullContent{
+
+    private final RewindableInputStream in;
+    private long size;
+
+
+    public InputStreamFullContent(final RewindableInputStream contents, final List<MessageResult.Header> headers) throws IOException{
+        super(headers);
+        this.in = contents;
+        this.size = caculateSize();
+    }
+
+    
+
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.james.imap.mailbox.Content#size()
+     */
+    public final long size() {
+        return size;
+    }
+
+    @Override
+    protected void bodyWriteTo(WritableByteChannel channel) throws IOException {
+        // rewind the stream before write it to the channel
+        in.rewind();
+        
+        // read all the content of the underlying InputStream in 16384 byte chunks, wrap them
+        // in a ByteBuffer and finally write the Buffer to the channel
+        byte[] buf = new byte[16384];
+        int i = 0;
+        while ((i = in.read(buf)) != -1) {
+            ByteBuffer buffer = ByteBuffer.wrap(buf);
+            // set the limit of the buffer to the returned bytes
+            buffer.limit(i);
+            channel.write(buffer);
+        }  
+    }
+
+
+    @Override
+    protected long getBodySize() throws IOException{
+        return in.available();
+    }
+
+}

Added: james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/LazySkippingInputStream.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/LazySkippingInputStream.java?rev=951398&view=auto
==============================================================================
--- james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/LazySkippingInputStream.java (added)
+++ james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/LazySkippingInputStream.java Fri Jun  4 13:07:05 2010
@@ -0,0 +1,101 @@
+/****************************************************************
+ * 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.james.imap.store.streaming;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * {@link FilterInputStream} implementation which skip the given bytes as late as possible.
+ * 
+ *
+ */
+public class LazySkippingInputStream extends FilterInputStream{
+
+    private long skipBytes;
+    private boolean skipped = false;
+
+    /**
+     * Construct the {@link LazySkippingInputStream}
+     * 
+     * @param in {@link InputStream} to wrap
+     * @param skipBytes bytes to skip
+     */
+    public LazySkippingInputStream(InputStream in, long skipBytes) {
+        super(in);
+        this.skipBytes = skipBytes;
+    }
+
+    @Override
+    public int read() throws IOException {
+        skipIfNeeded();
+
+        return super.read();
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        skipIfNeeded();
+        return super.read(b, off, len);
+    }
+
+    @Override
+    public int read(byte[] b) throws IOException {
+        skipIfNeeded();
+        return super.read(b);
+    }
+    
+    @Override
+    public int available() throws IOException {
+        skipIfNeeded();
+
+        return super.available();
+    }
+
+    @Override
+    public synchronized void mark(int readlimit) {
+        // not supported
+    }
+
+    @Override
+    public boolean markSupported() {
+        return false;
+    }
+
+    @Override
+    public long skip(long n) throws IOException {
+        skipIfNeeded();
+        return super.skip(n);
+    }
+
+    /**
+     * Check if the bytes are skipped already. If not do now
+     * 
+     * @throws IOException
+     */
+    private void skipIfNeeded() throws IOException {
+        if (skipped == false) {
+            super.skip(skipBytes);
+            skipped = true;
+        }
+    }
+
+}

Added: james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/PartContentBuilder.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/PartContentBuilder.java?rev=951398&view=auto
==============================================================================
--- james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/PartContentBuilder.java (added)
+++ james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/PartContentBuilder.java Fri Jun  4 13:07:05 2010
@@ -0,0 +1,291 @@
+/****************************************************************
+ * 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.james.imap.store.streaming;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.james.imap.mailbox.Content;
+import org.apache.james.imap.mailbox.MessageResult;
+import org.apache.james.imap.mailbox.MessageResult.Header;
+import org.apache.james.imap.store.ResultHeader;
+import org.apache.james.mime4j.MimeException;
+import org.apache.james.mime4j.parser.MimeTokenStream;
+
+public class PartContentBuilder {
+
+    private static final byte[] EMPTY = {};
+
+    private MimeTokenStream parser;
+
+    private boolean empty = false;
+
+    private boolean topLevel = true;
+
+    public PartContentBuilder() {
+        parser = new MimeTokenStream();
+    }
+
+    public void markEmpty() {
+        empty = true;
+    }
+
+    public void parse(final InputStream in) {
+        parser.setRecursionMode(MimeTokenStream.M_RECURSE);
+        parser.parse(in);
+        topLevel = true;
+    }
+
+    private void skipToStartOfInner(int position) throws IOException, MimeException {
+        final int state = parser.next();
+        switch (state) {
+            case MimeTokenStream.T_START_MULTIPART:
+                break;
+            case MimeTokenStream.T_START_MESSAGE:
+                break;
+            case MimeTokenStream.T_END_OF_STREAM:
+                throw new PartNotFoundException(position);
+            case MimeTokenStream.T_END_BODYPART:
+                throw new PartNotFoundException(position);
+            default:
+                skipToStartOfInner(position);
+        }
+    }
+
+    public void to(int position) throws IOException, MimeException {
+        try {
+            if (topLevel) {
+                topLevel = false;
+            } else {
+                skipToStartOfInner(position);
+            }
+            for (int count = 0; count < position;) {
+                final int state = parser.next();
+                switch (state) {
+                    case MimeTokenStream.T_BODY:
+                        if (position == 1) {
+                            count++;
+                        }
+                        break;
+                    case MimeTokenStream.T_START_BODYPART:
+                        count++;
+                        break;
+                    case MimeTokenStream.T_START_MULTIPART:
+                        if (count > 0 && count < position) {
+                            ignoreInnerMessage();
+                        }
+                        break;
+                    case MimeTokenStream.T_END_OF_STREAM:
+                        throw new PartNotFoundException(position);
+                }
+            }
+        } catch (IllegalStateException e) {
+            throw new PartNotFoundException(position, e);
+        }
+    }
+
+    private void ignoreInnerMessage() throws IOException, UnexpectedEOFException, MimeException {
+        for (int state = parser.next(); state != MimeTokenStream.T_END_MULTIPART; state = parser
+                .next()) {
+            switch (state) {
+                case MimeTokenStream.T_END_OF_STREAM:
+                    throw new UnexpectedEOFException();
+
+                case MimeTokenStream.T_START_MULTIPART:
+                    ignoreInnerMessage();
+                    break;
+            }
+        }
+    }
+
+    public Content getFullContent() throws IOException, UnexpectedEOFException, MimeException {
+        final List<Header> headers = getMimeHeaders();
+        final byte[] content = mimeBodyContent();
+        return new FullByteContent(ByteBuffer.wrap(content), headers);
+    }
+
+    public Content getMessageBodyContent() throws IOException, MimeException {
+        final byte[] content = messageBodyContent();
+        return new ByteContent(ByteBuffer.wrap(content));
+    }
+
+    private byte[] messageBodyContent() throws IOException, MimeException {
+        final byte[] content;
+        if (empty) {
+            content = EMPTY;
+        } else {
+            boolean valid;
+            try {
+                advancedToMessage();
+                valid = true;
+            } catch (UnexpectedEOFException e) {
+                // No TEXT part
+                valid = false;
+            }
+            if (valid) {
+                parser.setRecursionMode(MimeTokenStream.M_FLAT);
+                for (int state = parser.getState(); state != MimeTokenStream.T_BODY
+                        && state != MimeTokenStream.T_START_MULTIPART; state = parser
+                        .next()) {
+                    if (state == MimeTokenStream.T_END_OF_STREAM) {
+                        valid = false;
+                        break;
+                    }
+                }
+                if (valid) {
+                    content = StreamUtils.toByteArray(parser.getInputStream());
+                } else {
+                    content = EMPTY;
+                }
+            } else {
+                content = EMPTY;
+            }
+        }
+        return content;
+    }
+
+    public Content getMimeBodyContent() throws IOException, MimeException {
+        final byte[] content = mimeBodyContent();
+        return new ByteContent(ByteBuffer.wrap(content));
+    }
+
+    private byte[] mimeBodyContent() throws IOException, MimeException {
+        final byte[] content;
+        if (empty) {
+            content = EMPTY;
+        } else {
+            parser.setRecursionMode(MimeTokenStream.M_FLAT);
+            boolean valid = true;
+            for (int state = parser.getState(); state != MimeTokenStream.T_BODY
+                    && state != MimeTokenStream.T_START_MULTIPART; state = parser
+                    .next()) {
+                if (state == MimeTokenStream.T_END_OF_STREAM) {
+                    valid = false;
+                    break;
+                }
+            }
+            if (valid) {
+                content = StreamUtils.toByteArray(parser.getInputStream());
+            } else {
+                content = EMPTY;
+            }
+        }
+        return content;
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<MessageResult.Header> getMimeHeaders() throws IOException, UnexpectedEOFException, MimeException {
+        final List<MessageResult.Header> results;
+        if (empty) {
+            results = Collections.EMPTY_LIST;
+        } else {
+            results = new ArrayList<MessageResult.Header>();
+            for (int state = parser.getState(); state != MimeTokenStream.T_END_HEADER; state = parser
+                    .next()) {
+                switch (state) {
+                    case MimeTokenStream.T_END_OF_STREAM:
+                        throw new UnexpectedEOFException();
+
+                    case MimeTokenStream.T_FIELD:
+                        final String fieldValue = parser.getField().getBody().trim();
+                        final String fieldName = parser.getField().getName();
+                        ResultHeader header = new ResultHeader(fieldName, fieldValue);
+                        results.add(header);
+                        break;
+                }
+            }
+        }
+        return results;
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<MessageResult.Header> getMessageHeaders() throws IOException, MimeException {
+        final List<MessageResult.Header> results;
+        if (empty) {
+            results = Collections.EMPTY_LIST;
+        } else {
+            results = new ArrayList<MessageResult.Header>();
+            try {
+                advancedToMessage();
+
+                for (int state = parser.getState(); state != MimeTokenStream.T_END_HEADER; state = parser
+                        .next()) {
+                    switch (state) {
+                        case MimeTokenStream.T_END_OF_STREAM:
+                            throw new IOException("Unexpected EOF");
+
+                        case MimeTokenStream.T_FIELD:
+                            final String fieldValue = parser.getField().getBody().trim();
+                            final String fieldName = parser.getField().getName();
+                            ResultHeader header = new ResultHeader(fieldName, fieldValue);
+                            results.add(header);
+                            break;
+                    }
+                }
+            } catch (UnexpectedEOFException e) {
+                // No headers found
+            }
+        }
+        return results;
+    }
+
+    private void advancedToMessage() throws IOException, UnexpectedEOFException, MimeException {
+        for (int state = parser.getState(); state != MimeTokenStream.T_START_MESSAGE; state = parser
+                .next()) {
+            if (state == MimeTokenStream.T_END_OF_STREAM) {
+                throw new UnexpectedEOFException();
+            }
+        }
+    }
+
+    public static final class UnexpectedEOFException extends MimeException {
+
+        private static final long serialVersionUID = -3755637466593055796L;
+
+        public UnexpectedEOFException() {
+            super("Unexpected EOF");
+        }
+    }
+
+    public static final class PartNotFoundException extends MimeException {
+
+        private static final long serialVersionUID = 7519976990944851574L;
+
+        private final int position;
+
+        public PartNotFoundException(int position) {
+            this(position, null);
+        }
+
+        public PartNotFoundException(int position, Exception e) {
+            super("Part " + position + " not found.", e);
+            this.position = position;
+        }
+
+        public final int getPosition() {
+            return position;
+        }
+
+    }
+}

Added: james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/RewindableInputStream.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/RewindableInputStream.java?rev=951398&view=auto
==============================================================================
--- james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/RewindableInputStream.java (added)
+++ james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/RewindableInputStream.java Fri Jun  4 13:07:05 2010
@@ -0,0 +1,73 @@
+/****************************************************************
+ * 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.james.imap.store.streaming;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * {@link FilterInputStream} which support the get rewinded.
+ * 
+ * The rewinding will get delayed as long as possible. So if you call
+ * rewind, it will only get performed when needed
+ * 
+ * Be sure to call {@link #close()} to cleanup temporary data when you 
+ * are done with reading from the stream
+ * 
+ *
+ */
+public abstract class RewindableInputStream extends FilterInputStream{
+
+    private boolean rewind;
+
+    protected RewindableInputStream(InputStream in) {
+        super(in);
+    }
+
+    /**
+     * Return if the stream needs to get rewinded
+     * 
+     * @return needsRewind
+     */
+    public final boolean needsRewind() {
+        return rewind;
+    }
+    
+    /**
+     * Rewind was done
+     */
+    protected final void rewindDone() {
+        this.rewind = false;
+    }
+    
+    /**
+     * Mark the stream for rewind. The rewind itself should get delayed as long as possible
+     */
+    public final void rewind() {
+        this.rewind = true;
+    }
+
+    /**
+     * Perform the actual rewind 
+     * @throws IOException
+     */
+    protected abstract void rewindIfNeeded() throws IOException;
+
+}

Added: james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/StreamUtils.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/StreamUtils.java?rev=951398&view=auto
==============================================================================
--- james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/StreamUtils.java (added)
+++ james/imap/trunk/store/src/main/java/org/apache/james/imap/store/streaming/StreamUtils.java Fri Jun  4 13:07:05 2010
@@ -0,0 +1,57 @@
+/****************************************************************
+ * 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.james.imap.store.streaming;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Utility methods for messages.
+ * 
+ */
+public class StreamUtils {
+
+    private static final int BYTE_STREAM_CAPACITY = 8182;
+
+    private static final int BYTE_BUFFER_SIZE = 4096;
+
+    public static byte[] toByteArray(InputStream is) throws IOException {
+        ByteArrayOutputStream baos = out(is);
+
+        final byte[] bytes = baos.toByteArray();
+        return bytes;
+    }
+
+    public static ByteArrayOutputStream out(InputStream is) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(
+                BYTE_STREAM_CAPACITY);
+        out(is, baos);
+        return baos;
+    }
+
+    public static void out(InputStream is, ByteArrayOutputStream baos) throws IOException {
+        byte[] buf = new byte[BYTE_BUFFER_SIZE];
+        int read;
+        while ((read = is.read(buf)) > 0) {
+            baos.write(buf, 0, read);
+        }
+    }
+}

Modified: james/imap/trunk/store/src/main/java/org/apache/james/imap/store/transaction/AbstractTransactionalMapper.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/transaction/AbstractTransactionalMapper.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/store/src/main/java/org/apache/james/imap/store/transaction/AbstractTransactionalMapper.java (original)
+++ james/imap/trunk/store/src/main/java/org/apache/james/imap/store/transaction/AbstractTransactionalMapper.java Fri Jun  4 13:07:05 2010
@@ -26,7 +26,7 @@ import org.apache.james.imap.mailbox.Mai
  * Run Transaction and handle begin, commit and rollback in the right order
  *
  */
-public abstract class AbstractTransactionalMapper implements TransactionalMapper{
+public abstract class AbstractTransactionalMapper implements TransactionalMapper {
 
     /*
      * (non-Javadoc)
@@ -41,7 +41,6 @@ public abstract class AbstractTransactio
             rollback();
             throw e;
         }
-        
     }
     
     /**
@@ -58,13 +57,11 @@ public abstract class AbstractTransactio
      */
     protected abstract void commit() throws MailboxException;
     
-    
     /**
      * Rollback transaction
      * 
      * @throws StorageException
      */
     protected abstract void rollback() throws MailboxException;
-    
 
 }

Modified: james/imap/trunk/store/src/main/java/org/apache/james/imap/store/transaction/TransactionalMapper.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/transaction/TransactionalMapper.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/store/src/main/java/org/apache/james/imap/store/transaction/TransactionalMapper.java (original)
+++ james/imap/trunk/store/src/main/java/org/apache/james/imap/store/transaction/TransactionalMapper.java Fri Jun  4 13:07:05 2010
@@ -23,12 +23,16 @@ import org.apache.james.imap.mailbox.Mai
 
 /**
  * Mapper which execute units of work in a {@link Transaction}
- * @author norman
  *
  */
 public interface TransactionalMapper {
     
     /**
+     * IMAP Request was complete. Cleanup all Request scoped stuff
+     */
+    public void endRequest();
+    
+    /**
      * Execute the given Transaction
      * 
      * @param transaction 

Modified: james/imap/trunk/store/src/test/java/org/apache/james/imap/store/FileRewindableInputStreamTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/test/java/org/apache/james/imap/store/FileRewindableInputStreamTest.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/store/src/test/java/org/apache/james/imap/store/FileRewindableInputStreamTest.java (original)
+++ james/imap/trunk/store/src/test/java/org/apache/james/imap/store/FileRewindableInputStreamTest.java Fri Jun  4 13:07:05 2010
@@ -21,6 +21,9 @@ package org.apache.james.imap.store;
 import java.io.IOException;
 import java.io.InputStream;
 
+import org.apache.james.imap.store.streaming.FileRewindableInputStream;
+import org.apache.james.imap.store.streaming.RewindableInputStream;
+
 public class FileRewindableInputStreamTest extends RewindableInputStreamTest{
 
     @Override

Modified: james/imap/trunk/store/src/test/java/org/apache/james/imap/store/InMemoryRewindableInputStreamTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/test/java/org/apache/james/imap/store/InMemoryRewindableInputStreamTest.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/store/src/test/java/org/apache/james/imap/store/InMemoryRewindableInputStreamTest.java (original)
+++ james/imap/trunk/store/src/test/java/org/apache/james/imap/store/InMemoryRewindableInputStreamTest.java Fri Jun  4 13:07:05 2010
@@ -21,6 +21,9 @@ package org.apache.james.imap.store;
 import java.io.IOException;
 import java.io.InputStream;
 
+import org.apache.james.imap.store.streaming.InMemoryRewindableInputStream;
+import org.apache.james.imap.store.streaming.RewindableInputStream;
+
 public class InMemoryRewindableInputStreamTest extends RewindableInputStreamTest{
 
     @Override

Modified: james/imap/trunk/store/src/test/java/org/apache/james/imap/store/PartContentBuilderComplexMultipartTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/test/java/org/apache/james/imap/store/PartContentBuilderComplexMultipartTest.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/store/src/test/java/org/apache/james/imap/store/PartContentBuilderComplexMultipartTest.java (original)
+++ james/imap/trunk/store/src/test/java/org/apache/james/imap/store/PartContentBuilderComplexMultipartTest.java Fri Jun  4 13:07:05 2010
@@ -28,7 +28,8 @@ import java.nio.charset.Charset;
 import java.util.List;
 
 import org.apache.james.imap.mailbox.MessageResult.Header;
-import org.apache.james.imap.store.PartContentBuilder.PartNotFoundException;
+import org.apache.james.imap.store.streaming.PartContentBuilder;
+import org.apache.james.imap.store.streaming.PartContentBuilder.PartNotFoundException;
 import org.junit.Before;
 import org.junit.Test;
 

Modified: james/imap/trunk/store/src/test/java/org/apache/james/imap/store/PartContentBuilderMultipartAlternativeTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/test/java/org/apache/james/imap/store/PartContentBuilderMultipartAlternativeTest.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/store/src/test/java/org/apache/james/imap/store/PartContentBuilderMultipartAlternativeTest.java (original)
+++ james/imap/trunk/store/src/test/java/org/apache/james/imap/store/PartContentBuilderMultipartAlternativeTest.java Fri Jun  4 13:07:05 2010
@@ -27,6 +27,7 @@ import java.nio.charset.Charset;
 import java.util.List;
 
 import org.apache.james.imap.mailbox.MessageResult.Header;
+import org.apache.james.imap.store.streaming.PartContentBuilder;
 import org.junit.Before;
 import org.junit.Test;
 

Modified: james/imap/trunk/store/src/test/java/org/apache/james/imap/store/RewindableInputStreamTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/test/java/org/apache/james/imap/store/RewindableInputStreamTest.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/store/src/test/java/org/apache/james/imap/store/RewindableInputStreamTest.java (original)
+++ james/imap/trunk/store/src/test/java/org/apache/james/imap/store/RewindableInputStreamTest.java Fri Jun  4 13:07:05 2010
@@ -25,6 +25,7 @@ import java.io.InputStream;
 
 import static org.junit.Assert.*;
 
+import org.apache.james.imap.store.streaming.RewindableInputStream;
 import org.junit.Before;
 import org.junit.Test;
 

Modified: james/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMessage.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMessage.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMessage.java (original)
+++ james/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMessage.java Fri Jun  4 13:07:05 2010
@@ -29,6 +29,8 @@ import java.util.List;
 import org.apache.james.imap.store.mail.model.Document;
 import org.apache.james.imap.store.mail.model.Header;
 import org.apache.james.imap.store.mail.model.Property;
+import org.apache.james.imap.store.streaming.InMemoryRewindableInputStream;
+import org.apache.james.imap.store.streaming.RewindableInputStream;
 
 public class SimpleMessage implements Document {
     

Modified: james/imap/trunk/torque/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/torque/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/torque/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java (original)
+++ james/imap/trunk/torque/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java Fri Jun  4 13:07:05 2010
@@ -39,11 +39,11 @@ import org.apache.james.imap.mailbox.Mim
 import org.apache.james.imap.mailbox.MessageResult.FetchGroup;
 import org.apache.james.imap.mailbox.MessageResult.MimePath;
 import org.apache.james.imap.mailbox.util.MessageResultImpl;
-import org.apache.james.imap.store.ByteContent;
-import org.apache.james.imap.store.FullByteContent;
 import org.apache.james.imap.store.MimeDescriptorImpl;
-import org.apache.james.imap.store.PartContentBuilder;
 import org.apache.james.imap.store.ResultHeader;
+import org.apache.james.imap.store.streaming.ByteContent;
+import org.apache.james.imap.store.streaming.FullByteContent;
+import org.apache.james.imap.store.streaming.PartContentBuilder;
 import org.apache.james.mailboxmanager.torque.om.MessageBody;
 import org.apache.james.mailboxmanager.torque.om.MessageHeader;
 import org.apache.james.mailboxmanager.torque.om.MessageRow;

Modified: james/imap/trunk/torque/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/torque/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/torque/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java (original)
+++ james/imap/trunk/torque/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java Fri Jun  4 13:07:05 2010
@@ -59,7 +59,7 @@ import org.apache.james.imap.mailbox.Sea
 import org.apache.james.imap.mailbox.SearchQuery.NumericRange;
 import org.apache.james.imap.mailbox.util.FetchGroupImpl;
 import org.apache.james.imap.mailbox.util.UidRange;
-import org.apache.james.imap.store.CRLFOutputStream;
+import org.apache.james.imap.store.streaming.CRLFOutputStream;
 import org.apache.james.mailboxmanager.torque.om.MailboxRow;
 import org.apache.james.mailboxmanager.torque.om.MailboxRowPeer;
 import org.apache.james.mailboxmanager.torque.om.MessageBody;

Modified: james/imap/trunk/torque/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderComplexMultipartTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/torque/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderComplexMultipartTest.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/torque/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderComplexMultipartTest.java (original)
+++ james/imap/trunk/torque/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderComplexMultipartTest.java Fri Jun  4 13:07:05 2010
@@ -27,9 +27,9 @@ import java.nio.charset.Charset;
 import java.util.List;
 
 import org.apache.james.imap.mailbox.MessageResult.Header;
-import org.apache.james.imap.store.PartContentBuilder;
 import org.apache.james.imap.store.StringBuilderChannel;
-import org.apache.james.imap.store.PartContentBuilder.PartNotFoundException;
+import org.apache.james.imap.store.streaming.PartContentBuilder;
+import org.apache.james.imap.store.streaming.PartContentBuilder.PartNotFoundException;
 import org.junit.Before;
 import org.junit.Test;
 

Modified: james/imap/trunk/torque/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderMultipartAlternativeTest.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/torque/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderMultipartAlternativeTest.java?rev=951398&r1=951397&r2=951398&view=diff
==============================================================================
--- james/imap/trunk/torque/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderMultipartAlternativeTest.java (original)
+++ james/imap/trunk/torque/src/test/java/org/apache/james/mailboxmanager/torque/PartContentBuilderMultipartAlternativeTest.java Fri Jun  4 13:07:05 2010
@@ -27,8 +27,8 @@ import java.nio.charset.Charset;
 import java.util.List;
 
 import org.apache.james.imap.mailbox.MessageResult.Header;
-import org.apache.james.imap.store.PartContentBuilder;
 import org.apache.james.imap.store.StringBuilderChannel;
+import org.apache.james.imap.store.streaming.PartContentBuilder;
 import org.junit.Before;
 import org.junit.Test;
 



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org