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
20 package org.apache.james.core;
21
22 import javax.mail.MessagingException;
23 import javax.mail.util.SharedFileInputStream;
24
25 import java.io.BufferedOutputStream;
26 import java.io.File;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.OutputStream;
31
32 import org.apache.avalon.framework.activity.Disposable;
33
34 /***
35 * Takes an input stream and creates a repeatable input stream source
36 * for a MimeMessageWrapper. It does this by completely reading the
37 * input stream and saving that to a temporary file that should delete on exit,
38 * or when this object is GC'd.
39 *
40 * @see MimeMessageWrapper
41 *
42 *
43 */
44 public class MimeMessageInputStreamSource
45 extends MimeMessageSource
46 implements Disposable {
47
48 /***
49 * A temporary file used to hold the message stream
50 */
51 File file;
52
53 /***
54 * The full path of the temporary file
55 */
56 String sourceId;
57
58 /***
59 * Construct a new MimeMessageInputStreamSource from an
60 * <code>InputStream</code> that contains the bytes of a
61 * MimeMessage.
62 *
63 * @param key the prefix for the name of the temp file
64 * @param in the stream containing the MimeMessage
65 *
66 * @throws MessagingException if an error occurs while trying to store
67 * the stream
68 */
69 public MimeMessageInputStreamSource(String key, InputStream in)
70 throws MessagingException {
71
72
73 OutputStream fout = null;
74 try {
75 file = File.createTempFile(key, ".m64");
76 fout = new BufferedOutputStream(new FileOutputStream(file));
77 int b = -1;
78 while ((b = in.read()) != -1) {
79 fout.write(b);
80 }
81 fout.flush();
82
83 sourceId = file.getCanonicalPath();
84 } catch (IOException ioe) {
85
86
87
88
89 if (fout != null) try {
90 fout.close();
91 fout = null;
92 } catch (IOException _) {
93
94 }
95
96 if (file != null) {
97 file.delete();
98 file = null;
99 }
100
101 throw new MessagingException("Unable to retrieve the data: " + ioe.getMessage(), ioe);
102 } finally {
103 try {
104 if (fout != null) {
105 fout.close();
106 }
107 } catch (IOException ioe) {
108
109 }
110
111 try {
112 if (in != null) {
113 in.close();
114 }
115 } catch (IOException ioe) {
116
117 }
118 }
119 }
120
121 /***
122 * Returns the unique identifier of this input stream source
123 *
124 * @return the unique identifier for this MimeMessageInputStreamSource
125 */
126 public String getSourceId() {
127 return sourceId;
128 }
129
130 /***
131 * Get an input stream to retrieve the data stored in the temporary file
132 *
133 * @return a <code>BufferedInputStream</code> containing the data
134 */
135 public synchronized InputStream getInputStream() throws IOException {
136 return new SharedFileInputStream(file);
137 }
138
139 /***
140 * Get the size of the temp file
141 *
142 * @return the size of the temp file
143 *
144 * @throws IOException if an error is encoutered while computing the size of the message
145 */
146 public long getMessageSize() throws IOException {
147 return file.length();
148 }
149
150 /***
151 * @see org.apache.avalon.framework.activity.Disposable#dispose()
152 */
153 public void dispose() {
154 try {
155 if (file != null && file.exists()) {
156 file.delete();
157 }
158 } catch (Exception e) {
159
160 }
161 file = null;
162 }
163
164 /***
165 * <p>Finalizer that closes and deletes the temp file. Very bad.</p>
166 * We're leaving this in temporarily, while also establishing a more
167 * formal mechanism for cleanup through use of the dispose() method.
168 * @throws Throwable
169 *
170 public void finalize() throws Throwable {
171 dispose();
172 super.finalize();
173 }
174 */
175 }