1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.rssaggregator.generator;
35
36 import static info.magnolia.module.rssaggregator.RSSAggregator.*;
37 import static java.lang.String.format;
38
39 import info.magnolia.cms.beans.config.ServerConfiguration;
40 import info.magnolia.jcr.util.PropertyUtil;
41 import info.magnolia.jcr.util.SessionUtil;
42 import info.magnolia.module.data.DataConsts;
43 import info.magnolia.module.data.DataModule;
44 import info.magnolia.module.rssaggregator.util.ContentMapper;
45 import info.magnolia.module.rssaggregator.util.MagnoliaTemplate;
46 import info.magnolia.objectfactory.Components;
47
48 import java.util.List;
49
50 import javax.jcr.Node;
51 import javax.jcr.RepositoryException;
52
53 import org.apache.commons.lang.StringUtils;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57 import com.sun.syndication.feed.synd.SyndContent;
58 import com.sun.syndication.feed.synd.SyndContentImpl;
59 import com.sun.syndication.feed.synd.SyndEntry;
60 import com.sun.syndication.feed.synd.SyndEntryImpl;
61 import com.sun.syndication.feed.synd.SyndFeed;
62
63
64
65
66
67
68 public class PlanetFeedGenerator extends AbstractSyndFeedGenerator implements Cloneable {
69
70 private static final ContentMapper<SyndEntry> MAPPER = new FeedEntryMapper();
71
72 private static final Logger log = LoggerFactory.getLogger(PlanetFeedGenerator.class);
73
74 private static final String FEED_TYPE_RSS = "rss_2.0";
75 private static final String FEED_TYPE_ATOM = "atom_1.0";
76
77 private MagnoliaTemplate magnoliaTemplate;
78
79 private String feedPath;
80
81 public PlanetFeedGenerator() {
82 this.magnoliaTemplate = new MagnoliaTemplate();
83 }
84
85 public void setFeedPath(String feedPath) {
86 this.feedPath = feedPath;
87 }
88
89 @Override
90 public Feed generate() throws FeedGenerationException {
91 String feedType = getFeedType();
92
93 try {
94 SyndFeed syndFeed = newSyndFeed();
95 syndFeed.setFeedType(feedType);
96 syndFeed.setEntries(loadFeedEntries());
97 setFeedInfo(syndFeed);
98
99 String xml = syndFeedToXml(syndFeed);
100 return new Feed(xml, DEFAULT_CONTENT_TYPE, DEFAULT_ENCODING);
101 } catch (Exception e) {
102 String message = format("Failed to generate Feed using generator '%s'", getClass().getName());
103 log.error(message, e);
104 throw new FeedGenerationException(message, e);
105 }
106 }
107
108 @Override
109 public List<SyndEntry> loadFeedEntries() {
110 String entriesQuery = format("/jcr:root%s/planetData[1]/*/* order by @pubDate descending", feedPath);
111 return magnoliaTemplate.xpathQueryForList(DataModule.getRepository(), entriesQuery, DataConsts.MODULE_DATA_CONTENT_NODE_TYPE, MAPPER);
112 }
113
114 @Override
115 public void setFeedInfo(SyndFeed feed) {
116
117
118 String link = Components.getComponent(ServerConfiguration.class).getDefaultBaseUrl();
119 Node feedDescr = SessionUtil.getNode(DataModule.getRepository(), feedPath);
120 feed.setTitle(StringUtils.defaultIfEmpty(PropertyUtil.getString(feedDescr, "title"), ""));
121 feed.setLink(link);
122 feed.setDescription(StringUtils.defaultIfEmpty(PropertyUtil.getString(feedDescr, "description"), ""));
123 }
124
125 @Override
126 public Object clone() throws CloneNotSupportedException {
127 return super.clone();
128 }
129
130 protected String getFeedType() {
131 String feedType = "";
132
133 if (StringUtils.endsWith(this.feedPath, "/rss")) {
134 this.feedPath = StringUtils.substringBeforeLast(this.feedPath, "/rss");
135 feedType = FEED_TYPE_RSS;
136 } else {
137 if (StringUtils.endsWith(this.feedPath, "/atom")) {
138 this.feedPath = StringUtils.substringBeforeLast(this.feedPath, "/atom");
139 feedType = FEED_TYPE_ATOM;
140 }
141 }
142
143 if (StringUtils.isBlank(feedType)) {
144 feedType = DEFAULT_FEEDTYPE;
145 }
146
147 return feedType;
148 }
149
150 private static class FeedEntryMapper implements ContentMapper<SyndEntry> {
151
152 @Override
153 public SyndEntry map(Node content) throws RepositoryException {
154
155 SyndEntry entry = new SyndEntryImpl();
156 entry.setAuthor(PropertyUtil.getString(content, "author"));
157 entry.setTitle(PropertyUtil.getString(content, "title"));
158 entry.setLink(PropertyUtil.getString(content, "link"));
159 if (content.hasProperty("pubDate")) {
160 entry.setPublishedDate(PropertyUtil.getDate(content, "pubDate").getTime());
161 }
162 SyndContent description = new SyndContentImpl();
163
164 description.setValue(PropertyUtil.getString(content, "description"));
165 entry.setDescription(description);
166
167
168
169 return entry;
170 }
171 }
172 }