1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.mail;
18
19 import java.io.BufferedInputStream;
20 import java.io.BufferedOutputStream;
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.io.UnsupportedEncodingException;
27
28 import javax.activation.DataSource;
29
30 /**
31 * This class implements a typed DataSource from:<br>
32 *
33 * - an InputStream<br>
34 * - a byte array<br>
35 * - a String<br>
36 *
37 * <p>
38 * From version 1.3.1, it is possible to set a name for this DataSource,
39 * and it is recommended to do so.
40 *
41 * @since 1.0
42 * @author <a href="mailto:colin.chalmers@maxware.nl">Colin Chalmers</a>
43 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
44 * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
45 * @version $Id: ByteArrayDataSource.java 1448989 2013-02-22 11:05:02Z tn $
46 */
47 public class ByteArrayDataSource implements DataSource
48 {
49 /** Define the buffer size. */
50 public static final int BUFFER_SIZE = 512;
51
52 /** Stream containing the Data. */
53 private ByteArrayOutputStream baos;
54
55 /** The Content-type. */
56 private final String type; // = "application/octet-stream";
57
58 /**
59 * The name associated with this data source.
60 * By default, the name is an empty string, similar to javax.mail.util.ByteArrayDataSource.
61 * @since 1.3.1
62 */
63 private String name = "";
64
65 /**
66 * Create a datasource from a byte array.
67 *
68 * @param data A byte[].
69 * @param aType A String.
70 * @throws IOException IOException
71 * @since 1.0
72 */
73 public ByteArrayDataSource(byte[] data, String aType) throws IOException
74 {
75 this.type = aType;
76 ByteArrayInputStream bis = null;
77
78 try
79 {
80 bis = new ByteArrayInputStream(data);
81 this.byteArrayDataSource(bis);
82 }
83 finally
84 {
85 if (bis != null)
86 {
87 bis.close();
88 }
89 }
90 }
91
92 /**
93 * Create a datasource from an input stream.
94 *
95 * @param aIs An InputStream.
96 * @param aType A String.
97 * @throws IOException IOException
98 * @since 1.0
99 */
100 public ByteArrayDataSource(InputStream aIs, String aType) throws IOException
101 {
102 this.type = aType;
103 this.byteArrayDataSource(aIs);
104 }
105
106 /**
107 * Create a datasource from a String.
108 * N.B. assumes the data string can be converted using the charset iso-8859-1.
109 *
110 * @param data A String.
111 * @param aType A String.
112 * @throws IOException IOException
113 * @since 1.0
114 */
115 public ByteArrayDataSource(String data, String aType) throws IOException
116 {
117 this.type = aType;
118
119 try
120 {
121 baos = new ByteArrayOutputStream();
122
123 // Assumption that the string contains only ASCII characters!
124 // Else just pass in a charset into this constructor and use it in getBytes().
125 baos.write(data.getBytes("iso-8859-1"));
126 baos.flush();
127 baos.close();
128 }
129 catch (UnsupportedEncodingException uex)
130 {
131 throw new IOException("The Character Encoding is not supported.");
132 }
133 finally
134 {
135 if (baos != null)
136 {
137 baos.close();
138 }
139 }
140 }
141
142 /**
143 * Create a datasource from an input stream.
144 *
145 * @param aIs An InputStream.
146 * @throws IOException IOException
147 */
148 private void byteArrayDataSource(InputStream aIs)
149 throws IOException
150 {
151 BufferedInputStream bis = null;
152 BufferedOutputStream osWriter = null;
153
154 try
155 {
156 int length = 0;
157 byte[] buffer = new byte[ByteArrayDataSource.BUFFER_SIZE];
158
159 bis = new BufferedInputStream(aIs);
160 baos = new ByteArrayOutputStream();
161 osWriter = new BufferedOutputStream(baos);
162
163 // Write the InputData to OutputStream
164 while ((length = bis.read(buffer)) != -1)
165 {
166 osWriter.write(buffer, 0, length);
167 }
168 osWriter.flush();
169 osWriter.close();
170
171 }
172 finally
173 {
174 if (bis != null)
175 {
176 bis.close();
177 }
178 if (baos != null)
179 {
180 baos.close();
181 }
182 if (osWriter != null)
183 {
184 osWriter.close();
185 }
186 }
187 }
188
189 /**
190 * Get the content type.
191 *
192 * @return A String.
193 * @since 1.0
194 */
195 public String getContentType()
196 {
197 return type == null ? "application/octet-stream" : type;
198 }
199
200 /**
201 * Get the input stream.
202 *
203 * @return An InputStream.
204 * @throws IOException IOException
205 * @since 1.0
206 */
207 public InputStream getInputStream() throws IOException
208 {
209 if (baos == null)
210 {
211 throw new IOException("no data");
212 }
213 return new ByteArrayInputStream(baos.toByteArray());
214 }
215
216 /**
217 * Sets the name for this DataSource.
218 *
219 * @param name The name.
220 * @since 1.3.1
221 */
222 public void setName(String name)
223 {
224 this.name = name;
225 }
226
227 /**
228 * Get the name.
229 *
230 * @return A String.
231 * @since 1.0
232 */
233 public String getName()
234 {
235 return name;
236 }
237
238 /**
239 * Get the OutputStream to write to.
240 *
241 * @return An OutputStream
242 * @since 1.0
243 */
244 public OutputStream getOutputStream()
245 {
246 baos = new ByteArrayOutputStream();
247 return baos;
248 }
249 }