001/**
002 * Copyright 2011 Bill Brown
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package com.colorfulsoftware.rss;
017
018import java.io.Serializable;
019import java.util.LinkedList;
020import java.util.List;
021
022/**
023 * <p>
024 * The &lt;enclosure> element.
025 * </p>
026 * <p>
027 * From the <a href="http://cyber.law.harvard.edu/rss/rss.html">RSS 2.0
028 * specification</a>...
029 * </p>
030 * <p>
031 * Describes a media object that is attached to the item. <a href=
032 * "http://cyber.law.harvard.edu/rss/rss.html#ltenclosuregtSubelementOfLtitemgt"
033 * >More</a>.
034 * </p>
035 * 
036 * <p>
037 * &lt;enclosure> is an optional sub-element of &lt;item>.
038 * </p>
039 * 
040 * <p>
041 * It has three required attributes. url says where the enclosure is located,
042 * length says how big it is in bytes, and type says what its type is, a
043 * standard MIME type.
044 * </p>
045 * 
046 * <p>
047 * The url must be an http url.
048 * </p>
049 * 
050 * <p>
051 * &lt;enclosure url="http://www.scripting.com/mp3s/weatherReportSuite.mp3"
052 * length="12216320" type="audio/mpeg" />
053 * </p>
054 * 
055 * <p>
056 * A use-case narrative for this element is <a
057 * href="http://www.thetwowayweb.com/payloadsforrss">here</a>.
058 * </p>
059 * 
060 * @author Bill Brown
061 * 
062 */
063public class Enclosure implements Serializable {
064
065        /**
066         * 
067         */
068        private static final long serialVersionUID = -7669768690905784080L;
069
070        private final List<Attribute> attributes;
071        private final Attribute url;
072        private final Attribute length;
073        private final Attribute type;
074
075        Enclosure(List<Attribute> attributes) throws RSSpectException {
076
077                if (attributes == null) {
078                        throw new RSSpectException(
079                                        "enclosure elements MUST contain the url, length and type attributes.  See: http://cyber.law.harvard.edu/rss/rss.html#ltenclosuregtSubelementOfLtitemgt");
080                } else {
081                        this.attributes = new LinkedList<Attribute>();
082                        for (Attribute attr : attributes) {
083                                // check for unsupported attribute.
084                                this.attributes.add(new Attribute(attr));
085                        }
086                }
087
088                if ((this.url = getAttribute("url")) == null) {
089                        throw new RSSpectException(
090                                        "enclosure elements MUST have a url attribute.");
091                }
092
093                if ((this.length = getAttribute("length")) == null) {
094                        throw new RSSpectException(
095                                        "enclosure elements MUST have a length attribute.");
096                }
097
098                if ((this.type = getAttribute("type")) == null) {
099                        throw new RSSpectException(
100                                        "enclosure elements MUST have a type attribute.");
101                }
102
103        }
104
105        Enclosure(Enclosure enclosure) {
106                this.attributes = enclosure.getAttributes();
107                this.url = enclosure.getUrl();
108                this.length = enclosure.getLength();
109                this.type = enclosure.getType();
110        }
111
112        /**
113         * 
114         * @return the cloud attribute list.
115         */
116        public List<Attribute> getAttributes() {
117
118                List<Attribute> attrsCopy = new LinkedList<Attribute>();
119                for (Attribute attr : this.attributes) {
120                        attrsCopy.add(new Attribute(attr));
121                }
122
123                return attrsCopy;
124        }
125
126        /**
127         * @return the url attribute
128         */
129        public Attribute getUrl() {
130                return new Attribute(url);
131
132        }
133
134        /**
135         * @return the length attribute.
136         */
137        public Attribute getLength() {
138                return new Attribute(length);
139        }
140
141        /**
142         * @return the type attribute.
143         */
144        public Attribute getType() {
145                return new Attribute(type);
146        }
147
148        /**
149         * @param attrName
150         *            the name of the attribute to get.
151         * @return the Attribute object if attrName matches or null if not found.
152         */
153        public Attribute getAttribute(String attrName) {
154                for (Attribute attribute : this.attributes) {
155                        if (attribute.getName().equals(attrName)) {
156                                return new Attribute(attribute);
157                        }
158                }
159                return null;
160        }
161
162        /**
163         * Shows the contents of the &lt;enclosure> element.
164         */
165        @Override
166        public String toString() {
167                StringBuilder sb = new StringBuilder("<enclosure");
168                for (Attribute attribute : attributes) {
169                        sb.append(attribute);
170                }
171                sb.append(" />");
172                return sb.toString();
173        }
174        
175        @Override
176        public boolean equals(Object obj) {
177                if (obj == this) {
178                        return true;
179                }
180                if (!(obj instanceof Enclosure)) {
181                        return false;
182                }
183                return this.toString().equals(obj.toString());
184        }
185        
186        @Override public int hashCode() {
187                return toString().hashCode();
188        }
189
190}