source: contrib/MailArchiver/sources/vendor/mime4j/apache-mime4j-0.7-SNAPSHOT-20110327.010440-17/storage/src/main/java/org/apache/james/mime4j/storage/TempFileStorageProvider.java @ 6785

Revision 6785, 6.5 KB checked in by rafaelraymundo, 12 years ago (diff)

Ticket #2946 - Liberado codigo do MailArchiver?. Documentação na subpasta DOCS.

Line 
1/****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one   *
3 * or more contributor license agreements.  See the NOTICE file *
4 * distributed with this work for additional information        *
5 * regarding copyright ownership.  The ASF licenses this file   *
6 * to you under the Apache License, Version 2.0 (the            *
7 * "License"); you may not use this file except in compliance   *
8 * with the License.  You may obtain a copy of the License at   *
9 *                                                              *
10 *   http://www.apache.org/licenses/LICENSE-2.0                 *
11 *                                                              *
12 * Unless required by applicable law or agreed to in writing,   *
13 * software distributed under the License is distributed on an  *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15 * KIND, either express or implied.  See the License for the    *
16 * specific language governing permissions and limitations      *
17 * under the License.                                           *
18 ****************************************************************/
19
20package org.apache.james.mime4j.storage;
21
22import java.io.BufferedInputStream;
23import java.io.File;
24import java.io.FileInputStream;
25import java.io.FileOutputStream;
26import java.io.IOException;
27import java.io.InputStream;
28import java.io.OutputStream;
29import java.util.HashSet;
30import java.util.Iterator;
31import java.util.Set;
32
33/**
34 * A {@link StorageProvider} that stores the data in temporary files. The files
35 * are stored either in a user-specified directory or the default temporary-file
36 * directory (specified by system property <code>java.io.tmpdir</code>).
37 * <p>
38 * Example usage:
39 *
40 * <pre>
41 * File directory = new File(&quot;/tmp/mime4j&quot;);
42 * StorageProvider provider = new TempFileStorageProvider(directory);
43 * DefaultStorageProvider.setInstance(provider);
44 * </pre>
45 */
46public class TempFileStorageProvider extends AbstractStorageProvider {
47
48    private static final String DEFAULT_PREFIX = "m4j";
49
50    private final String prefix;
51    private final String suffix;
52    private final File directory;
53
54    /**
55     * Equivalent to using constructor
56     * <code>TempFileStorageProvider("m4j", null, null)</code>.
57     */
58    public TempFileStorageProvider() {
59        this(DEFAULT_PREFIX, null, null);
60    }
61
62    /**
63     * Equivalent to using constructor
64     * <code>TempFileStorageProvider("m4j", null, directory)</code>.
65     */
66    public TempFileStorageProvider(File directory) {
67        this(DEFAULT_PREFIX, null, directory);
68    }
69
70    /**
71     * Creates a new <code>TempFileStorageProvider</code> using the given
72     * values.
73     *
74     * @param prefix
75     *            prefix for generating the temporary file's name; must be at
76     *            least three characters long.
77     * @param suffix
78     *            suffix for generating the temporary file's name; may be
79     *            <code>null</code> to use the suffix <code>".tmp"</code>.
80     * @param directory
81     *            the directory in which the file is to be created, or
82     *            <code>null</code> if the default temporary-file directory is
83     *            to be used (specified by the system property
84     *            <code>java.io.tmpdir</code>).
85     * @throws IllegalArgumentException
86     *             if the given prefix is less than three characters long or the
87     *             given directory does not exist and cannot be created (if it
88     *             is not <code>null</code>).
89     */
90    public TempFileStorageProvider(String prefix, String suffix, File directory) {
91        if (prefix == null || prefix.length() < 3)
92            throw new IllegalArgumentException("invalid prefix");
93
94        if (directory != null && !directory.isDirectory()
95                && !directory.mkdirs())
96            throw new IllegalArgumentException("invalid directory");
97
98        this.prefix = prefix;
99        this.suffix = suffix;
100        this.directory = directory;
101    }
102
103    public StorageOutputStream createStorageOutputStream() throws IOException {
104        File file = File.createTempFile(prefix, suffix, directory);
105        file.deleteOnExit();
106
107        return new TempFileStorageOutputStream(file);
108    }
109
110    private static final class TempFileStorageOutputStream extends
111            StorageOutputStream {
112        private File file;
113        private OutputStream out;
114
115        public TempFileStorageOutputStream(File file) throws IOException {
116            this.file = file;
117            this.out = new FileOutputStream(file);
118        }
119
120        @Override
121        public void close() throws IOException {
122            super.close();
123            out.close();
124        }
125
126        @Override
127        protected void write0(byte[] buffer, int offset, int length)
128                throws IOException {
129            out.write(buffer, offset, length);
130        }
131
132        @Override
133        protected Storage toStorage0() throws IOException {
134            // out has already been closed because toStorage calls close
135            return new TempFileStorage(file);
136        }
137    }
138
139    private static final class TempFileStorage implements Storage {
140
141        private File file;
142
143        private static final Set<File> filesToDelete = new HashSet<File>();
144
145        public TempFileStorage(File file) {
146            this.file = file;
147        }
148
149        public void delete() {
150            // deleting a file might not immediately succeed if there are still
151            // streams left open (especially under Windows). so we keep track of
152            // the files that have to be deleted and try to delete all these
153            // files each time this method gets invoked.
154
155            // a better but more complicated solution would be to start a
156            // separate thread that tries to delete the files periodically.
157
158            synchronized (filesToDelete) {
159                if (file != null) {
160                    filesToDelete.add(file);
161                    file = null;
162                }
163
164                for (Iterator<File> iterator = filesToDelete.iterator(); iterator
165                        .hasNext();) {
166                    File file = iterator.next();
167                    if (file.delete()) {
168                        iterator.remove();
169                    }
170                }
171            }
172        }
173
174        public InputStream getInputStream() throws IOException {
175            if (file == null)
176                throw new IllegalStateException("storage has been deleted");
177
178            return new BufferedInputStream(new FileInputStream(file));
179        }
180
181    }
182
183}
Note: See TracBrowser for help on using the repository browser.