001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *  http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    
020    package javax.mail.util;
021    
022    import java.io.ByteArrayOutputStream;
023    import java.io.ByteArrayInputStream;
024    import java.io.IOException;
025    import java.io.InputStream;
026    import java.io.OutputStream;
027    
028    import javax.activation.DataSource;
029    import javax.mail.internet.ContentType;
030    import javax.mail.internet.ParseException;
031    import javax.mail.internet.MimeUtility;
032    
033    
034    /**
035     * An activation DataSource object that sources the data from
036     * a byte[] array.
037     * @version $Rev: 467553 $ $Date: 2006-10-25 00:01:51 -0400 (Wed, 25 Oct 2006) $
038     */
039    public class ByteArrayDataSource implements DataSource {
040        // the data source
041        private byte[] source;
042        // the content MIME type
043        private String contentType;
044        // the name information (defaults to a null string)
045        private String name = "";
046    
047    
048        /**
049         * Create a ByteArrayDataSource from an input stream.
050         *
051         * @param in     The source input stream.
052         * @param type   The MIME-type of the data.
053         *
054         * @exception IOException
055         */
056        public ByteArrayDataSource(InputStream in, String type) throws IOException {
057            ByteArrayOutputStream sink = new ByteArrayOutputStream();
058    
059            // ok, how I wish you could just pipe an input stream into an output stream :-)
060            byte[] buffer = new byte[8192];
061            int bytesRead;
062    
063            while ((bytesRead = in.read(buffer)) > 0) {
064                sink.write(buffer, 0, bytesRead);
065            }
066    
067            source = sink.toByteArray();
068            contentType = type;
069        }
070    
071    
072        /**
073         * Create a ByteArrayDataSource directly from a byte array.
074         *
075         * @param data   The source byte array (not copied).
076         * @param type   The content MIME-type.
077         */
078        public ByteArrayDataSource(byte[] data, String type) {
079            source = data;
080            contentType = type;
081        }
082    
083        /**
084         * Create a ByteArrayDataSource from a string value.  If the
085         * type information includes a charset parameter, that charset
086         * is used to extract the bytes.  Otherwise, the default Java
087         * char set is used.
088         *
089         * @param data   The source data string.
090         * @param type   The MIME type information.
091         *
092         * @exception IOException
093         */
094        public ByteArrayDataSource(String data, String type) throws IOException {
095            String charset = null;
096            try {
097                // the charset can be encoded in the content type, which we parse using
098                // the ContentType class.
099                ContentType content = new ContentType(type);
100                charset = content.getParameter("charset");
101            } catch (ParseException e) {
102                // ignored...just use the default if this fails
103            }
104            if (charset == null) {
105                charset = MimeUtility.getDefaultJavaCharset();
106            }
107            else {
108                // the type information encodes a MIME charset, which may need mapping to a Java one.
109                charset = MimeUtility.javaCharset(charset);
110            }
111    
112            // get the source using the specified charset
113            source = data.getBytes(charset);
114            contentType = type;
115        }
116    
117    
118        /**
119         * Create an input stream for this data.  A new input stream
120         * is created each time.
121         *
122         * @return An InputStream for reading the encapsulated data.
123         * @exception IOException
124         */
125        public InputStream getInputStream() throws IOException {
126            return new ByteArrayInputStream(source);
127        }
128    
129    
130        /**
131         * Open an output stream for the DataSource.  This is not
132         * supported by this DataSource, so an IOException is always
133         * throws.
134         *
135         * @return Nothing...an IOException is always thrown.
136         * @exception IOException
137         */
138        public OutputStream getOutputStream() throws IOException {
139            throw new IOException("Writing to a ByteArrayDataSource is not supported");
140        }
141    
142    
143        /**
144         * Get the MIME content type information for this DataSource.
145         *
146         * @return The MIME content type string.
147         */
148        public String getContentType() {
149            return contentType;
150        }
151    
152    
153        /**
154         * Retrieve the DataSource name.  If not explicitly set, this
155         * returns "".
156         *
157         * @return The currently set DataSource name.
158         */
159        public String getName() {
160            return name;
161        }
162    
163    
164        /**
165         * Set a new DataSource name.
166         *
167         * @param name   The new name.
168         */
169        public void setName(String name) {
170            this.name = name;
171        }
172    }
173