001    /****************************************************************
002     * Licensed to the Apache Software Foundation (ASF) under one   *
003     * or more contributor license agreements.  See the NOTICE file *
004     * distributed with this work for additional information        *
005     * regarding copyright ownership.  The ASF licenses this file   *
006     * to you under the Apache License, Version 2.0 (the            *
007     * "License"); you may not use this file except in compliance   *
008     * with the License.  You may obtain a copy of the License at   *
009     *                                                              *
010     *   http://www.apache.org/licenses/LICENSE-2.0                 *
011     *                                                              *
012     * Unless required by applicable law or agreed to in writing,   *
013     * software distributed under the License is distributed on an  *
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
015     * KIND, either express or implied.  See the License for the    *
016     * specific language governing permissions and limitations      *
017     * under the License.                                           *
018     ****************************************************************/
019    
020    package org.apache.james.mime4j.storage;
021    
022    import java.io.ByteArrayInputStream;
023    import java.io.IOException;
024    import java.io.InputStream;
025    
026    import org.apache.james.mime4j.util.ByteArrayBuffer;
027    
028    /**
029     * A {@link StorageProvider} that stores the data entirely in memory.
030     * <p>
031     * Example usage:
032     *
033     * <pre>
034     * StorageProvider provider = new MemoryStorageProvider();
035     * DefaultStorageProvider.setInstance(provider);
036     * </pre>
037     */
038    public class MemoryStorageProvider extends AbstractStorageProvider {
039    
040        /**
041         * Creates a new <code>MemoryStorageProvider</code>.
042         */
043        public MemoryStorageProvider() {
044        }
045    
046        public StorageOutputStream createStorageOutputStream() {
047            return new MemoryStorageOutputStream();
048        }
049    
050        private static final class MemoryStorageOutputStream extends
051                StorageOutputStream {
052            ByteArrayBuffer bab = new ByteArrayBuffer(1024);
053    
054            @Override
055            protected void write0(byte[] buffer, int offset, int length)
056                    throws IOException {
057                bab.append(buffer, offset, length);
058            }
059    
060            @Override
061            protected Storage toStorage0() throws IOException {
062                return new MemoryStorage(bab.buffer(), bab.length());
063            }
064        }
065    
066        static final class MemoryStorage implements Storage {
067            private byte[] data;
068            private final int count;
069    
070            public MemoryStorage(byte[] data, int count) {
071                this.data = data;
072                this.count = count;
073            }
074    
075            public InputStream getInputStream() throws IOException {
076                if (data == null)
077                    throw new IllegalStateException("storage has been deleted");
078    
079                return new ByteArrayInputStream(data, 0, count);
080            }
081    
082            public void delete() {
083                data = null;
084            }
085        }
086    
087    }