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 <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 * <enclosure> is an optional sub-element of <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 * <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 <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}