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 782475 2009-06-07 22:02:58Z sgoeschl $
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            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    }