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 external namespace extension 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 * This class can be used to add extended namespace elements. 032 * </p> 033 * 034 * @author Bill Brown 035 * 036 */ 037public class Extension implements Serializable { 038 039 /** 040 * 041 */ 042 private static final long serialVersionUID = 7382104018423864548L; 043 private final String elementName; 044 private final List<Attribute> attributes; 045 private final String content; 046 private final String namespacePrefix; 047 048 Extension(String elementName, List<Attribute> attributes, String content) 049 throws RSSpectException { 050 051 this.elementName = elementName; 052 053 this.content = content; 054 055 if (attributes == null) { 056 this.attributes = null; 057 } else { 058 this.attributes = new LinkedList<Attribute>(); 059 for (Attribute attr : attributes) { 060 this.attributes.add(new Attribute(attr)); 061 } 062 } 063 064 if (elementName == null 065 || elementName.equals("") 066 || (elementName.indexOf(":") == -1 && getAttribute("xmlns") == null) 067 || elementName.indexOf(":") == 0) { 068 069 throw new RSSpectException( 070 "Extension element '" 071 + elementName 072 + "' is missing a namespace prefix or namespace declaration."); 073 } 074 075 // the namespace prefix is used here for validation only. 076 if (elementName.indexOf(":") != -1) { 077 String potentialPrefix = elementName.substring(0, elementName 078 .indexOf(":")); 079 if (getAttribute("xmlns:" + potentialPrefix) == null) { 080 this.namespacePrefix = potentialPrefix; 081 } else { 082 this.namespacePrefix = null; 083 } 084 } else { 085 this.namespacePrefix = null; 086 } 087 } 088 089 Extension(Extension extension) { 090 this.elementName = extension.elementName; 091 this.attributes = extension.getAttributes(); 092 this.content = extension.content; 093 this.namespacePrefix = extension.namespacePrefix; 094 } 095 096 /** 097 * 098 * @return the attribute list. 099 */ 100 public List<Attribute> getAttributes() { 101 102 List<Attribute> attrsCopy = new LinkedList<Attribute>(); 103 if (this.attributes != null) { 104 for (Attribute attr : this.attributes) { 105 attrsCopy.add(new Attribute(attr)); 106 } 107 } 108 return (this.attributes == null) ? null : attrsCopy; 109 } 110 111 /** 112 * @return the content. 113 */ 114 public String getContent() { 115 return content; 116 } 117 118 /** 119 * @return the extension element name. eg "atom:link" or "someExtension" 120 */ 121 public String getElementName() { 122 return elementName; 123 } 124 125 /** 126 * @param attrName 127 * the name of the attribute to get. 128 * @return the Attribute object if attrName matches or null if not found. 129 */ 130 public Attribute getAttribute(String attrName) { 131 if (this.attributes != null) { 132 for (Attribute attribute : this.attributes) { 133 if (attribute.getName().equals(attrName)) { 134 return new Attribute(attribute); 135 } 136 } 137 } 138 return null; 139 } 140 141 /** 142 * Shows the contents of the extension element. 143 */ 144 @Override 145 public String toString() { 146 StringBuilder sb = new StringBuilder("<" + elementName); 147 if (attributes != null) { 148 for (Attribute attribute : attributes) { 149 sb.append(attribute); 150 } 151 } 152 153 if (content == null || content.equals("")) { 154 sb.append(" />"); 155 } else { 156 sb.append(" >" + content + "</" + elementName + ">"); 157 } 158 159 return sb.toString(); 160 } 161 162 String getNamespacePrefix() { 163 return namespacePrefix; 164 } 165 166 @Override 167 public boolean equals(Object obj) { 168 if (obj == this) { 169 return true; 170 } 171 if (!(obj instanceof Extension)) { 172 return false; 173 } 174 return this.toString().equals(obj.toString()); 175 } 176 177 @Override public int hashCode() { 178 return toString().hashCode(); 179 } 180}