001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.mail;
018
019import java.io.BufferedInputStream;
020import java.io.BufferedOutputStream;
021import java.io.ByteArrayInputStream;
022import java.io.ByteArrayOutputStream;
023import java.io.IOException;
024import java.io.InputStream;
025import java.io.OutputStream;
026import java.io.UnsupportedEncodingException;
027
028import javax.activation.DataSource;
029
030/**
031 * This class implements a typed DataSource from:<br>
032 *
033 * - an InputStream<br>
034 * - a byte array<br>
035 * - a String<br>
036 *
037 * @since 1.0
038 * @author <a href="mailto:colin.chalmers@maxware.nl">Colin Chalmers</a>
039 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
040 * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
041 * @version $Id: ByteArrayDataSource.java 782475 2009-06-07 22:02:58Z sgoeschl $
042 */
043public class ByteArrayDataSource implements DataSource
044{
045    /** define the buffer size */
046    public static final int BUFFER_SIZE = 512;
047
048    /** Stream containg the Data */
049    private ByteArrayOutputStream baos;
050
051    /** Content-type. */
052    private String type = "application/octet-stream";
053
054    /**
055     * Create a datasource from a byte array.
056     *
057     * @param data A byte[].
058     * @param aType A String.
059     * @throws IOException IOException
060     * @since 1.0
061     */
062    public ByteArrayDataSource(byte[] data, String aType) throws IOException
063    {
064        ByteArrayInputStream bis = null;
065
066        try
067        {
068            bis = new ByteArrayInputStream(data);
069            this.byteArrayDataSource(bis, aType);
070        }
071        finally
072        {
073            if (bis != null)
074            {
075                bis.close();
076            }
077        }
078    }
079
080    /**
081     * Create a datasource from an input stream.
082     *
083     * @param aIs An InputStream.
084     * @param aType A String.
085     * @throws IOException IOException
086     * @since 1.0
087     */
088    public ByteArrayDataSource(InputStream aIs, String aType) throws IOException
089    {
090        this.byteArrayDataSource(aIs, aType);
091    }
092
093    /**
094     * Create a datasource from a String.
095     *
096     * @param data A String.
097     * @param aType A String.
098     * @throws IOException IOException
099     * @since 1.0
100     */
101    public ByteArrayDataSource(String data, String aType) throws IOException
102    {
103        this.type = aType;
104
105        try
106        {
107            baos = new ByteArrayOutputStream();
108
109            // Assumption that the string contains only ASCII
110            // characters!  Else just pass in a charset into this
111            // constructor and use it in getBytes().
112            baos.write(data.getBytes("iso-8859-1"));
113            baos.flush();
114            baos.close();
115        }
116        catch (UnsupportedEncodingException uex)
117        {
118            throw new IOException("The Character Encoding is not supported.");
119        }
120        finally
121        {
122            if (baos != null)
123            {
124                baos.close();
125            }
126        }
127    }
128
129    /**
130      * Create a datasource from an input stream.
131      *
132      * @param aIs An InputStream.
133      * @param aType A String.
134      * @throws IOException IOException
135      */
136    private void byteArrayDataSource(InputStream aIs, String aType)
137        throws IOException
138    {
139        this.type = aType;
140
141        BufferedInputStream bis = null;
142        BufferedOutputStream osWriter = null;
143
144        try
145        {
146            int length = 0;
147            byte[] buffer = new byte[ByteArrayDataSource.BUFFER_SIZE];
148
149            bis = new BufferedInputStream(aIs);
150            baos = new ByteArrayOutputStream();
151            osWriter = new BufferedOutputStream(baos);
152
153            //Write the InputData to OutputStream
154            while ((length = bis.read(buffer)) != -1)
155            {
156                osWriter.write(buffer, 0, length);
157            }
158            osWriter.flush();
159            osWriter.close();
160
161        }
162        finally
163        {
164            if (bis != null)
165            {
166                bis.close();
167            }
168            if (baos != null)
169            {
170                baos.close();
171            }
172            if (osWriter != null)
173            {
174                osWriter.close();
175            }
176        }
177    }
178
179
180
181    /**
182     * Get the content type.
183     *
184     * @return A String.
185     * @since 1.0
186     */
187    public String getContentType()
188    {
189        return type == null ? "application/octet-stream" : type;
190    }
191
192    /**
193     * Get the input stream.
194     *
195     * @return An InputStream.
196     * @throws IOException IOException
197     * @since 1.0
198     */
199    public InputStream getInputStream() throws IOException
200    {
201        if (baos == null)
202        {
203            throw new IOException("no data");
204        }
205        return new ByteArrayInputStream(baos.toByteArray());
206    }
207
208    /**
209     * Get the name.
210     *
211     * @return A String.
212     * @since 1.0
213     */
214    public String getName()
215    {
216        return "ByteArrayDataSource";
217    }
218
219    /**
220     * Get the OutputStream to write to
221     *
222     * @return  An OutputStream
223     * @since 1.0
224     */
225    public OutputStream getOutputStream()
226    {
227        baos = new ByteArrayOutputStream();
228        return baos;
229    }
230}