1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.sun.syndication.io.impl;
18
19 import com.sun.syndication.feed.WireFeed;
20 import com.sun.syndication.feed.rss.*;
21 import com.sun.syndication.io.FeedException;
22 import org.jdom.Document;
23 import org.jdom.Element;
24 import org.jdom.Namespace;
25
26 import java.util.List;
27
28
29 /***
30 * Feed Generator for RSS 0.90
31 * <p/>
32 *
33 * @author Elaine Chien
34 */
35 public class RSS090Generator extends BaseWireFeedGenerator {
36
37 private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
38 private static final String RSS_URI = "http://my.netscape.com/rdf/simple/0.9/";
39 private static final String CONTENT_URI = "http://purl.org/rss/1.0/modules/content/";
40
41 private static final Namespace RDF_NS = Namespace.getNamespace("rdf", RDF_URI);
42 private static final Namespace RSS_NS = Namespace.getNamespace(RSS_URI);
43 private static final Namespace CONTENT_NS = Namespace.getNamespace("content", CONTENT_URI);
44
45 public RSS090Generator() {
46 this("rss_0.9");
47 }
48
49 protected RSS090Generator(String type) {
50 super(type);
51 }
52
53 public Document generate(WireFeed feed) throws FeedException {
54 Channel channel = (Channel)feed;
55 Element root = createRootElement(channel);
56 populateFeed(channel,root);
57 purgeUnusedNamespaceDeclarations(root);
58 return createDocument(root);
59 }
60
61 protected Namespace getFeedNamespace() {
62 return RSS_NS;
63 }
64
65 protected Namespace getRDFNamespace() {
66 return RDF_NS;
67 }
68
69 protected Namespace getContentNamespace() {
70 return CONTENT_NS;
71 }
72
73 protected Document createDocument(Element root) {
74 return new Document(root);
75 }
76
77 protected Element createRootElement(Channel channel) {
78 Element root = new Element("RDF",getRDFNamespace());
79 root.addNamespaceDeclaration(getFeedNamespace());
80 root.addNamespaceDeclaration(getRDFNamespace());
81 root.addNamespaceDeclaration(getContentNamespace());
82 generateModuleNamespaceDefs(root);
83 return root;
84 }
85
86 protected void populateFeed(Channel channel, Element parent) throws FeedException {
87 addChannel(channel,parent);
88 addImage(channel,parent);
89 addTextInput(channel,parent);
90 addItems(channel,parent);
91 generateForeignMarkup(parent, (List)channel.getForeignMarkup());
92 }
93
94 protected void addChannel(Channel channel,Element parent) throws FeedException {
95 Element eChannel = new Element("channel", getFeedNamespace());
96 populateChannel(channel,eChannel);
97 checkChannelConstraints(eChannel);
98 parent.addContent(eChannel);
99 generateFeedModules(channel.getModules(),eChannel);
100 }
101
102 /***
103 * Populates the given channel with parsed data from the ROME element that holds the
104 * channel data.
105 *
106 * @param channel the channel into which parsed data will be added.
107 * @param eChannel the XML element that holds the data for the channel.
108 */
109 protected void populateChannel(Channel channel,Element eChannel) {
110 String title = channel.getTitle();
111 if (title!=null) {
112 eChannel.addContent(generateSimpleElement("title",title));
113 }
114 String link = channel.getLink();
115 if (link!=null) {
116 eChannel.addContent(generateSimpleElement("link",link));
117 }
118 String description = channel.getDescription();
119 if (description!=null) {
120 eChannel.addContent(generateSimpleElement("description",description));
121 }
122 }
123
124
125 protected void checkNotNullAndLength(Element parent, String childName, int minLen, int maxLen) throws FeedException {
126 Element child = parent.getChild(childName,getFeedNamespace());
127 if (child == null) {
128 throw new FeedException("Invalid "+getType()+" feed, missing "+parent.getName()+" "+childName);
129 }
130 checkLength(parent,childName,minLen,maxLen);
131 }
132
133
134 protected void checkLength(Element parent, String childName, int minLen, int maxLen) throws FeedException {
135 Element child = parent.getChild(childName,getFeedNamespace());
136 if (child != null) {
137 if (minLen>0 && child.getText().length()<minLen) {
138 throw new FeedException("Invalid "+getType()+" feed, "+parent.getName()+" "+childName + "short of "+minLen+" length");
139 }
140 if (maxLen>-1 && child.getText().length()>maxLen) {
141 throw new FeedException("Invalid "+getType()+" feed, "+parent.getName()+" "+childName + "exceeds "+maxLen+" length");
142 }
143 }
144 }
145
146
147 protected void addImage(Channel channel,Element parent) throws FeedException {
148 Image image = channel.getImage();
149 if (image!=null) {
150 Element eImage = new Element("image", getFeedNamespace());
151 populateImage(image,eImage);
152 checkImageConstraints(eImage);
153 parent.addContent(eImage);
154 }
155 }
156
157 protected void populateImage(Image image,Element eImage) {
158 String title = image.getTitle();
159 if (title!=null) {
160 eImage.addContent(generateSimpleElement("title",title));
161 }
162 String url = image.getUrl();
163 if (url!=null) {
164 eImage.addContent(generateSimpleElement("url",url));
165 }
166 String link = image.getLink();
167 if (link!=null) {
168 eImage.addContent(generateSimpleElement("link",link));
169 }
170 }
171
172
173 protected String getTextInputLabel() {
174 return "textInput";
175 }
176
177 protected void addTextInput(Channel channel,Element parent) throws FeedException {
178 TextInput textInput = channel.getTextInput();
179 if (textInput!=null) {
180 Element eTextInput = new Element(getTextInputLabel(), getFeedNamespace());
181 populateTextInput(textInput,eTextInput);
182 checkTextInputConstraints(eTextInput);
183 parent.addContent(eTextInput);
184 }
185 }
186
187 protected void populateTextInput(TextInput textInput,Element eTextInput) {
188 String title = textInput.getTitle();
189 if (title!=null) {
190 eTextInput.addContent(generateSimpleElement("title",title));
191 }
192 String description = textInput.getDescription();
193 if (description!=null) {
194 eTextInput.addContent(generateSimpleElement("description",description));
195 }
196 String name = textInput.getName();
197 if (name!=null) {
198 eTextInput.addContent(generateSimpleElement("name",name));
199 }
200 String link = textInput.getLink();
201 if (link!=null) {
202 eTextInput.addContent(generateSimpleElement("link",link));
203 }
204 }
205
206 protected void addItems(Channel channel,Element parent) throws FeedException {
207 List items = channel.getItems();
208 for (int i=0;i<items.size();i++) {
209 addItem((Item)items.get(i),parent, i);
210 }
211 checkItemsConstraints(parent);
212 }
213
214 protected void addItem(Item item, Element parent, int index) throws FeedException {
215 Element eItem = new Element("item", getFeedNamespace());
216 populateItem(item,eItem, index);
217 checkItemConstraints(eItem);
218 generateItemModules(item.getModules(),eItem);
219 parent.addContent(eItem);
220 }
221
222 protected void populateItem(Item item, Element eItem, int index) {
223 String title = item.getTitle();
224 if (title!=null) {
225 eItem.addContent(generateSimpleElement("title",title));
226 }
227 String link = item.getLink();
228 if (link!=null) {
229 eItem.addContent(generateSimpleElement("link",link));
230 }
231 generateForeignMarkup(eItem, (List)item.getForeignMarkup());
232 }
233
234 protected Element generateSimpleElement(String name, String value) {
235 Element element = new Element(name, getFeedNamespace());
236 element.addContent(value);
237 return element;
238 }
239
240 protected void checkChannelConstraints(Element eChannel) throws FeedException {
241 checkNotNullAndLength(eChannel,"title", 0, 40);
242 checkNotNullAndLength(eChannel,"description", 0, 500);
243 checkNotNullAndLength(eChannel,"link", 0, 500);
244 }
245
246 protected void checkImageConstraints(Element eImage) throws FeedException {
247 checkNotNullAndLength(eImage,"title", 0, 40);
248 checkNotNullAndLength(eImage,"url", 0, 500);
249 checkNotNullAndLength(eImage,"link", 0, 500);
250 }
251
252 protected void checkTextInputConstraints(Element eTextInput) throws FeedException {
253 checkNotNullAndLength(eTextInput,"title", 0, 40);
254 checkNotNullAndLength(eTextInput,"description", 0, 100);
255 checkNotNullAndLength(eTextInput,"name", 0, 500);
256 checkNotNullAndLength(eTextInput,"link", 0, 500);
257 }
258
259 protected void checkItemsConstraints(Element parent) throws FeedException {
260 int count = parent.getChildren("item",getFeedNamespace()).size();
261 if (count<1 || count>15) {
262 throw new FeedException("Invalid "+getType()+" feed, item count is "+count+" it must be between 1 an 15");
263 }
264 }
265
266 protected void checkItemConstraints(Element eItem) throws FeedException {
267 checkNotNullAndLength(eItem,"title", 0, 100);
268 checkNotNullAndLength(eItem,"link", 0, 500);
269 }
270
271 }