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     */
017    package org.apache.commons.mail;
018    
019    import java.io.BufferedInputStream;
020    import java.io.BufferedOutputStream;
021    import java.io.ByteArrayInputStream;
022    import java.io.ByteArrayOutputStream;
023    import java.io.IOException;
024    import java.io.InputStream;
025    import java.io.OutputStream;
026    import java.io.UnsupportedEncodingException;
027    
028    import 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 480401 2006-11-29 04:40:04Z bayard $
042     */
043    public 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            catch (IOException ioex)
072            {
073                throw ioex;
074            }
075            finally
076            {
077                if (bis != null)
078                {
079                    bis.close();
080                }
081            }
082        }
083    
084        /**
085         * Create a datasource from an input stream.
086         *
087         * @param aIs An InputStream.
088         * @param aType A String.
089         * @throws IOException IOException
090         * @since 1.0
091         */
092        public ByteArrayDataSource(InputStream aIs, String aType) throws IOException
093        {
094            this.byteArrayDataSource(aIs, aType);
095        }
096    
097        /**
098         * Create a datasource from a String.
099         *
100         * @param data A String.
101         * @param aType A String.
102         * @throws IOException IOException
103         * @since 1.0
104         */
105        public ByteArrayDataSource(String data, String aType) throws IOException
106        {
107            this.type = aType;
108    
109            try
110            {
111                baos = new ByteArrayOutputStream();
112    
113                // Assumption that the string contains only ASCII
114                // characters!  Else just pass in a charset into this
115                // constructor and use it in getBytes().
116                baos.write(data.getBytes("iso-8859-1"));
117                baos.flush();
118                baos.close();
119            }
120            catch (UnsupportedEncodingException uex)
121            {
122                throw new IOException("The Character Encoding is not supported.");
123            }
124            finally
125            {
126                if (baos != null)
127                {
128                    baos.close();
129                }
130            }
131        }
132    
133        /**
134          * Create a datasource from an input stream.
135          *
136          * @param aIs An InputStream.
137          * @param aType A String.
138          * @throws IOException IOException
139          */
140        private void byteArrayDataSource(InputStream aIs, String aType)
141            throws IOException
142        {
143            this.type = aType;
144    
145            BufferedInputStream bis = null;
146            BufferedOutputStream osWriter = null;
147    
148            try
149            {
150                int length = 0;
151                byte[] buffer = new byte[ByteArrayDataSource.BUFFER_SIZE];
152    
153                bis = new BufferedInputStream(aIs);
154                baos = new ByteArrayOutputStream();
155                osWriter = new BufferedOutputStream(baos);
156    
157                //Write the InputData to OutputStream
158                while ((length = bis.read(buffer)) != -1)
159                {
160                    osWriter.write(buffer, 0, length);
161                }
162                osWriter.flush();
163                osWriter.close();
164    
165            }
166            catch (IOException ioex)
167            {
168                throw ioex;
169            }
170            finally
171            {
172                if (bis != null)
173                {
174                    bis.close();
175                }
176                if (baos != null)
177                {
178                    baos.close();
179                }
180                if (osWriter != null)
181                {
182                    osWriter.close();
183                }
184            }
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         * Get the name.
218         *
219         * @return A String.
220         * @since 1.0
221         */
222        public String getName()
223        {
224            return "ByteArrayDataSource";
225        }
226    
227        /**
228         * Get the OutputStream to write to
229         *
230         * @return  An OutputStream
231         * @since 1.0
232         */
233        public OutputStream getOutputStream()
234        {
235            baos = new ByteArrayOutputStream();
236            return baos;
237        }
238    }