001    package biweekly.property;
002    
003    import java.io.File;
004    import java.io.FileInputStream;
005    import java.io.IOException;
006    import java.util.List;
007    
008    import biweekly.Warning;
009    import biweekly.component.ICalComponent;
010    import biweekly.util.IOUtils;
011    
012    /*
013     Copyright (c) 2013, Michael Angstadt
014     All rights reserved.
015    
016     Redistribution and use in source and binary forms, with or without
017     modification, are permitted provided that the following conditions are met: 
018    
019     1. Redistributions of source code must retain the above copyright notice, this
020     list of conditions and the following disclaimer. 
021     2. Redistributions in binary form must reproduce the above copyright notice,
022     this list of conditions and the following disclaimer in the documentation
023     and/or other materials provided with the distribution. 
024    
025     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
026     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
027     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
028     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
029     ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
030     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
031     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
032     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
033     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
034     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
035     */
036    
037    /**
038     * <p>
039     * Represents a binary resource that is associated with an event, to-do, journal
040     * entry, or alarm.
041     * </p>
042     * 
043     * <p>
044     * <b>Examples:</b>
045     * 
046     * <pre class="brush:java">
047     * //from a byte array
048     * byte[] data = ...
049     * Attachment attach = new Attachment("image/png", data);
050     * 
051     * //reading from a file 
052     * Attachment attach = new Attachment(&quot;image/png&quot;, new File(&quot;image.png&quot;));
053     * 
054     * //referencing a URL
055     * Attachment attach = new Attachment(&quot;image/png&quot;, &quot;http://example.com/image.png&quot;);
056     * </pre>
057     * 
058     * </p>
059     * @author Michael Angstadt
060     * @rfc 5545 p.80-1
061     */
062    public class Attachment extends ICalProperty {
063            private byte[] data;
064            private String uri;
065    
066            /**
067             * Creates a new attachment.
068             * @param formatType the content-type of the data (e.g. "image/png")
069             * @param file the file to attach
070             * @throws IOException if there's a problem reading from the file
071             */
072            public Attachment(String formatType, File file) throws IOException {
073                    this.data = IOUtils.toByteArray(new FileInputStream(file), true);
074                    setFormatType(formatType);
075            }
076    
077            /**
078             * Creates a new attachment.
079             * @param formatType the content-type of the data (e.g. "image/png")
080             * @param data the binary data
081             */
082            public Attachment(String formatType, byte[] data) {
083                    this.data = data;
084                    setFormatType(formatType);
085            }
086    
087            /**
088             * Creates a new attachment.
089             * @param formatType the content-type of the data (e.g. "image/png")
090             * @param uri a URL pointing to the resource (e.g.
091             * "http://example.com/image.png")
092             */
093            public Attachment(String formatType, String uri) {
094                    this.uri = uri;
095                    setFormatType(formatType);
096            }
097    
098            /**
099             * Gets the attachment's binary data.
100             * @return the binary data or null if not set
101             */
102            public byte[] getData() {
103                    return data;
104            }
105    
106            /**
107             * Sets the attachment's binary data. If the attachment has a URI associated
108             * with it, the URI will be set to null.
109             * @param data the binary data
110             */
111            public void setData(byte[] data) {
112                    this.data = data;
113                    uri = null;
114            }
115    
116            /**
117             * Gets the attachment's URI.
118             * @return the URI (e.g. "http://example.com/image.png") or null if not set
119             */
120            public String getUri() {
121                    return uri;
122            }
123    
124            /**
125             * Sets the attachment's URI. If the attachment has binary data associated
126             * with it, the binary data will be set to null.
127             * @param uri the URI (e.g. "http://example.com/image.png")
128             */
129            public void setUri(String uri) {
130                    this.uri = uri;
131                    data = null;
132            }
133    
134            @Override
135            public String getFormatType() {
136                    return super.getFormatType();
137            }
138    
139            @Override
140            public void setFormatType(String formatType) {
141                    super.setFormatType(formatType);
142            }
143    
144            @Override
145            protected void validate(List<ICalComponent> components, List<Warning> warnings) {
146                    if (uri == null && data == null) {
147                            warnings.add(Warning.validate(26));
148                    }
149            }
150    }