~ubuntu-branches/ubuntu/saucy/apache-mime4j/saucy

« back to all changes in this revision

Viewing changes to src/main/java/org/apache/james/mime4j/message/BodyFactory.java

  • Committer: Bazaar Package Importer
  • Author(s): David Paleino
  • Date: 2010-07-13 09:28:28 UTC
  • Revision ID: james.westby@ubuntu.com-20100713092828-g6wafdtidgmtx7su
Tags: upstream-0.6
ImportĀ upstreamĀ versionĀ 0.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.mime4j.message;
 
21
 
 
22
import java.io.IOException;
 
23
import java.io.InputStream;
 
24
import java.nio.charset.Charset;
 
25
 
 
26
import org.apache.commons.logging.Log;
 
27
import org.apache.commons.logging.LogFactory;
 
28
import org.apache.james.mime4j.storage.DefaultStorageProvider;
 
29
import org.apache.james.mime4j.storage.MultiReferenceStorage;
 
30
import org.apache.james.mime4j.storage.Storage;
 
31
import org.apache.james.mime4j.storage.StorageProvider;
 
32
import org.apache.james.mime4j.util.CharsetUtil;
 
33
 
 
34
/**
 
35
 * Factory for creating message bodies.
 
36
 */
 
37
public class BodyFactory {
 
38
 
 
39
    private static Log log = LogFactory.getLog(BodyFactory.class);
 
40
 
 
41
    private static final Charset FALLBACK_CHARSET = CharsetUtil.DEFAULT_CHARSET;
 
42
 
 
43
    private StorageProvider storageProvider;
 
44
 
 
45
    /**
 
46
     * Creates a new <code>BodyFactory</code> instance that uses the default
 
47
     * storage provider for creating message bodies from input streams.
 
48
     */
 
49
    public BodyFactory() {
 
50
        this.storageProvider = DefaultStorageProvider.getInstance();
 
51
    }
 
52
 
 
53
    /**
 
54
     * Creates a new <code>BodyFactory</code> instance that uses the given
 
55
     * storage provider for creating message bodies from input streams.
 
56
     * 
 
57
     * @param storageProvider
 
58
     *            a storage provider or <code>null</code> to use the default
 
59
     *            one.
 
60
     */
 
61
    public BodyFactory(StorageProvider storageProvider) {
 
62
        if (storageProvider == null)
 
63
            storageProvider = DefaultStorageProvider.getInstance();
 
64
 
 
65
        this.storageProvider = storageProvider;
 
66
    }
 
67
 
 
68
    /**
 
69
     * Returns the <code>StorageProvider</code> this <code>BodyFactory</code>
 
70
     * uses to create message bodies from input streams.
 
71
     * 
 
72
     * @return a <code>StorageProvider</code>.
 
73
     */
 
74
    public StorageProvider getStorageProvider() {
 
75
        return storageProvider;
 
76
    }
 
77
 
 
78
    /**
 
79
     * Creates a {@link BinaryBody} that holds the content of the given input
 
80
     * stream.
 
81
     * 
 
82
     * @param is
 
83
     *            input stream to create a message body from.
 
84
     * @return a binary body.
 
85
     * @throws IOException
 
86
     *             if an I/O error occurs.
 
87
     */
 
88
    public BinaryBody binaryBody(InputStream is) throws IOException {
 
89
        if (is == null)
 
90
            throw new IllegalArgumentException();
 
91
 
 
92
        Storage storage = storageProvider.store(is);
 
93
        return new StorageBinaryBody(new MultiReferenceStorage(storage));
 
94
    }
 
95
 
 
96
    /**
 
97
     * Creates a {@link BinaryBody} that holds the content of the given
 
98
     * {@link Storage}.
 
99
     * <p>
 
100
     * Note that the caller must not invoke {@link Storage#delete() delete()} on
 
101
     * the given <code>Storage</code> object after it has been passed to this
 
102
     * method. Instead the message body created by this method takes care of
 
103
     * deleting the storage when it gets disposed of (see
 
104
     * {@link Disposable#dispose()}).
 
105
     * 
 
106
     * @param storage
 
107
     *            storage to create a message body from.
 
108
     * @return a binary body.
 
109
     * @throws IOException
 
110
     *             if an I/O error occurs.
 
111
     */
 
112
    public BinaryBody binaryBody(Storage storage) throws IOException {
 
113
        if (storage == null)
 
114
            throw new IllegalArgumentException();
 
115
 
 
116
        return new StorageBinaryBody(new MultiReferenceStorage(storage));
 
117
    }
 
118
 
 
119
    /**
 
120
     * Creates a {@link TextBody} that holds the content of the given input
 
121
     * stream.
 
122
     * <p>
 
123
     * &quot;us-ascii&quot; is used to decode the byte content of the
 
124
     * <code>Storage</code> into a character stream when calling
 
125
     * {@link TextBody#getReader() getReader()} on the returned object.
 
126
     * 
 
127
     * @param is
 
128
     *            input stream to create a message body from.
 
129
     * @return a text body.
 
130
     * @throws IOException
 
131
     *             if an I/O error occurs.
 
132
     */
 
133
    public TextBody textBody(InputStream is) throws IOException {
 
134
        if (is == null)
 
135
            throw new IllegalArgumentException();
 
136
 
 
137
        Storage storage = storageProvider.store(is);
 
138
        return new StorageTextBody(new MultiReferenceStorage(storage),
 
139
                CharsetUtil.DEFAULT_CHARSET);
 
140
    }
 
141
 
 
142
    /**
 
143
     * Creates a {@link TextBody} that holds the content of the given input
 
144
     * stream.
 
145
     * <p>
 
146
     * The charset corresponding to the given MIME charset name is used to
 
147
     * decode the byte content of the input stream into a character stream when
 
148
     * calling {@link TextBody#getReader() getReader()} on the returned object.
 
149
     * If the MIME charset has no corresponding Java charset or the Java charset
 
150
     * cannot be used for decoding then &quot;us-ascii&quot; is used instead.
 
151
     * 
 
152
     * @param is
 
153
     *            input stream to create a message body from.
 
154
     * @param mimeCharset
 
155
     *            name of a MIME charset.
 
156
     * @return a text body.
 
157
     * @throws IOException
 
158
     *             if an I/O error occurs.
 
159
     */
 
160
    public TextBody textBody(InputStream is, String mimeCharset)
 
161
            throws IOException {
 
162
        if (is == null)
 
163
            throw new IllegalArgumentException();
 
164
        if (mimeCharset == null)
 
165
            throw new IllegalArgumentException();
 
166
 
 
167
        Storage storage = storageProvider.store(is);
 
168
        Charset charset = toJavaCharset(mimeCharset, false);
 
169
        return new StorageTextBody(new MultiReferenceStorage(storage), charset);
 
170
    }
 
171
 
 
172
    /**
 
173
     * Creates a {@link TextBody} that holds the content of the given
 
174
     * {@link Storage}.
 
175
     * <p>
 
176
     * &quot;us-ascii&quot; is used to decode the byte content of the
 
177
     * <code>Storage</code> into a character stream when calling
 
178
     * {@link TextBody#getReader() getReader()} on the returned object.
 
179
     * <p>
 
180
     * Note that the caller must not invoke {@link Storage#delete() delete()} on
 
181
     * the given <code>Storage</code> object after it has been passed to this
 
182
     * method. Instead the message body created by this method takes care of
 
183
     * deleting the storage when it gets disposed of (see
 
184
     * {@link Disposable#dispose()}).
 
185
     * 
 
186
     * @param storage
 
187
     *            storage to create a message body from.
 
188
     * @return a text body.
 
189
     * @throws IOException
 
190
     *             if an I/O error occurs.
 
191
     */
 
192
    public TextBody textBody(Storage storage) throws IOException {
 
193
        if (storage == null)
 
194
            throw new IllegalArgumentException();
 
195
 
 
196
        return new StorageTextBody(new MultiReferenceStorage(storage),
 
197
                CharsetUtil.DEFAULT_CHARSET);
 
198
    }
 
199
 
 
200
    /**
 
201
     * Creates a {@link TextBody} that holds the content of the given
 
202
     * {@link Storage}.
 
203
     * <p>
 
204
     * The charset corresponding to the given MIME charset name is used to
 
205
     * decode the byte content of the <code>Storage</code> into a character
 
206
     * stream when calling {@link TextBody#getReader() getReader()} on the
 
207
     * returned object. If the MIME charset has no corresponding Java charset or
 
208
     * the Java charset cannot be used for decoding then &quot;us-ascii&quot; is
 
209
     * used instead.
 
210
     * <p>
 
211
     * Note that the caller must not invoke {@link Storage#delete() delete()} on
 
212
     * the given <code>Storage</code> object after it has been passed to this
 
213
     * method. Instead the message body created by this method takes care of
 
214
     * deleting the storage when it gets disposed of (see
 
215
     * {@link Disposable#dispose()}).
 
216
     * 
 
217
     * @param storage
 
218
     *            storage to create a message body from.
 
219
     * @param mimeCharset
 
220
     *            name of a MIME charset.
 
221
     * @return a text body.
 
222
     * @throws IOException
 
223
     *             if an I/O error occurs.
 
224
     */
 
225
    public TextBody textBody(Storage storage, String mimeCharset)
 
226
            throws IOException {
 
227
        if (storage == null)
 
228
            throw new IllegalArgumentException();
 
229
        if (mimeCharset == null)
 
230
            throw new IllegalArgumentException();
 
231
 
 
232
        Charset charset = toJavaCharset(mimeCharset, false);
 
233
        return new StorageTextBody(new MultiReferenceStorage(storage), charset);
 
234
    }
 
235
 
 
236
    /**
 
237
     * Creates a {@link TextBody} that holds the content of the given string.
 
238
     * <p>
 
239
     * &quot;us-ascii&quot; is used to encode the characters of the string into
 
240
     * a byte stream when calling
 
241
     * {@link SingleBody#writeTo(java.io.OutputStream) writeTo(OutputStream)} on
 
242
     * the returned object.
 
243
     * 
 
244
     * @param text
 
245
     *            text to create a message body from.
 
246
     * @return a text body.
 
247
     */
 
248
    public TextBody textBody(String text) {
 
249
        if (text == null)
 
250
            throw new IllegalArgumentException();
 
251
 
 
252
        return new StringTextBody(text, CharsetUtil.DEFAULT_CHARSET);
 
253
    }
 
254
 
 
255
    /**
 
256
     * Creates a {@link TextBody} that holds the content of the given string.
 
257
     * <p>
 
258
     * The charset corresponding to the given MIME charset name is used to
 
259
     * encode the characters of the string into a byte stream when calling
 
260
     * {@link SingleBody#writeTo(java.io.OutputStream) writeTo(OutputStream)} on
 
261
     * the returned object. If the MIME charset has no corresponding Java
 
262
     * charset or the Java charset cannot be used for encoding then
 
263
     * &quot;us-ascii&quot; is used instead.
 
264
     * 
 
265
     * @param text
 
266
     *            text to create a message body from.
 
267
     * @param mimeCharset
 
268
     *            name of a MIME charset.
 
269
     * @return a text body.
 
270
     */
 
271
    public TextBody textBody(String text, String mimeCharset) {
 
272
        if (text == null)
 
273
            throw new IllegalArgumentException();
 
274
        if (mimeCharset == null)
 
275
            throw new IllegalArgumentException();
 
276
 
 
277
        Charset charset = toJavaCharset(mimeCharset, true);
 
278
        return new StringTextBody(text, charset);
 
279
    }
 
280
 
 
281
    private static Charset toJavaCharset(String mimeCharset, boolean forEncoding) {
 
282
        String charset = CharsetUtil.toJavaCharset(mimeCharset);
 
283
        if (charset == null) {
 
284
            if (log.isWarnEnabled())
 
285
                log.warn("MIME charset '" + mimeCharset + "' has no "
 
286
                        + "corresponding Java charset. Using "
 
287
                        + FALLBACK_CHARSET + " instead.");
 
288
            return FALLBACK_CHARSET;
 
289
        }
 
290
 
 
291
        if (forEncoding && !CharsetUtil.isEncodingSupported(charset)) {
 
292
            if (log.isWarnEnabled())
 
293
                log.warn("MIME charset '" + mimeCharset
 
294
                        + "' does not support encoding. Using "
 
295
                        + FALLBACK_CHARSET + " instead.");
 
296
            return FALLBACK_CHARSET;
 
297
        }
 
298
 
 
299
        if (!forEncoding && !CharsetUtil.isDecodingSupported(charset)) {
 
300
            if (log.isWarnEnabled())
 
301
                log.warn("MIME charset '" + mimeCharset
 
302
                        + "' does not support decoding. Using "
 
303
                        + FALLBACK_CHARSET + " instead.");
 
304
            return FALLBACK_CHARSET;
 
305
        }
 
306
 
 
307
        return Charset.forName(charset);
 
308
    }
 
309
 
 
310
}