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 info.magnolia.commands.MgnlCommand;
37 import info.magnolia.context.Context;
38 import info.magnolia.context.MgnlContext;
39 import info.magnolia.jcr.util.NodeTypes;
40 import info.magnolia.jcr.util.NodeUtil;
41 import info.magnolia.jcr.util.PropertyUtil;
42 import info.magnolia.module.rssaggregator.RSSAggregatorConstants;
43 import info.magnolia.module.rssaggregator.RSSAggregatorNodeTypes;
44 import info.magnolia.module.rssaggregator.util.PlanetUtil;
45
46 import java.util.Calendar;
47 import java.util.Date;
48
49 import javax.jcr.Node;
50 import javax.jcr.NodeIterator;
51 import javax.jcr.RepositoryException;
52 import javax.jcr.Session;
53
54 import org.apache.commons.lang.StringUtils;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58
59
60
61
62
63 public class CollectStatisticsCommand extends MgnlCommand {
64
65 private static final Logger log = LoggerFactory.getLogger(CollectStatisticsCommand.class);
66
67 private static final String FEED_DATA_NAME = "planetData";
68 private static final String STATISTICS_NODE = "statistics";
69 private static final String STATS_AUTHORS_NODE = "authors";
70
71 private Session session;
72 private Date statisticsStartDate;
73 private int authorCount;
74
75 @Override
76 public boolean execute(Context context) throws Exception {
77 log.info("Starting command for creating Planet data statistics.");
78 session = MgnlContext.getJCRSession(RSSAggregatorConstants.WORKSPACE);
79 this.statisticsStartDate = getStatisticsStartDate();
80 log.info("Statistics will be build on content with date " + statisticsStartDate + " or later.");
81 traverseFeedEntries(session.getRootNode());
82 log.info("Finished generating Planet data statistics.");
83 return true;
84 }
85
86 protected Date getStatisticsStartDate() {
87 info.magnolia.module.rssaggregator.RSSAggregator module = info.magnolia.module.rssaggregator.RSSAggregator.getInstance();
88 int lastMonthsIncluded = module.getMonthsIncluded();
89
90 Calendar calendar = Calendar.getInstance();
91 calendar.setTime(new Date());
92 calendar.add(Calendar.MONTH, (lastMonthsIncluded) * -1);
93
94 return calendar.getTime();
95 }
96
97 private void traverseFeedEntries(Node rssParent) throws RepositoryException {
98 NodeIterator feeds = rssParent.getNodes();
99 while (feeds.hasNext()) {
100 this.authorCount = 0;
101 Node feedOrFolderNode = feeds.nextNode();
102 if (NodeUtil.isNodeType(feedOrFolderNode, RSSAggregatorNodeTypes.RSSAggregator.NAME)) {
103 processRSSAggregator(feedOrFolderNode);
104 } else if (NodeUtil.isNodeType(feedOrFolderNode, NodeTypes.Folder.NAME)) {
105 traverseFeedEntries(feedOrFolderNode);
106 }
107 }
108 }
109
110 private void processRSSAggregator(Node feedNode) throws RepositoryException {
111 if (PlanetUtil.isPlanetNode(feedNode)) {
112 log.info("Creating statistics for planet feed: " + feedNode.getName());
113
114
115 if (feedNode.hasNode(STATISTICS_NODE)) {
116 String absPath = feedNode.getNode(STATISTICS_NODE).getPath();
117 feedNode.getSession().removeItem(absPath);
118 }
119
120
121 Node authors = NodeUtil.createPath(feedNode, STATISTICS_NODE + "/" + STATS_AUTHORS_NODE, NodeTypes.Content.NAME, true);
122 NodeIterator postArchives = feedNode.getNode(FEED_DATA_NAME).getNodes();
123
124 while (postArchives.hasNext()) {
125 Node archive = postArchives.nextNode();
126
127
128 NodeIterator entries = archive.getNodes();
129 while (entries.hasNext()) {
130 Node entry = entries.nextNode();
131
132 String author = PlanetUtil.formatName(entry, "author");
133 String channel = PlanetUtil.formatName(entry, "channelTitle");
134
135 try {
136 authorCount++;
137 String feedLink = PropertyUtil.getString(entry, "rssLink", "");
138
139 Node trgNode;
140 if (StringUtils.isNotBlank(author)) {
141
142 trgNode = PlanetUtil.findAuthorNode(authors, author, feedLink, authorCount);
143 PropertyUtil.setProperty(trgNode, "author", author);
144 } else {
145
146 trgNode = PlanetUtil.findAuthorNode(authors, author, feedLink, authorCount);
147 PropertyUtil.setProperty(trgNode, "author", channel);
148 }
149
150 Node countedPosts = NodeUtil.createPath(trgNode, "countedPosts", NodeTypes.Content.NAME, true);
151
152
153 if (entry.hasProperty("pubDate")) {
154 try {
155 Date pubDate = new Date(entry.getProperty("pubDate").getLong());
156
157 if (pubDate.after(statisticsStartDate)) {
158 if (!countedPosts.hasNode(entry.getIdentifier())) {
159 NodeUtil.createPath(countedPosts, entry.getIdentifier(), NodeTypes.Content.NAME, true);
160 }
161 long postCount = countedPosts.getNodes().getSize();
162 PropertyUtil.setProperty(trgNode, "postCount", postCount);
163 }
164 } catch (Exception e) {
165 log.error("Problem while adding post counter: " + e.getMessage());
166 }
167 }
168 PropertyUtil.setProperty(trgNode, "blogLink", PropertyUtil.getString(entry, "authorLink", ""));
169 PropertyUtil.setProperty(trgNode, "feedLink", feedLink);
170
171 session.save();
172 } catch (RepositoryException re) {
173 log.error("Exception while parsing entries: " + re.getMessage());
174 }
175 }
176 }
177 } else {
178 log.info("Statistics for feed " + feedNode.getName() + " will not be created because the feed is not marked as Planet feed.");
179 }
180 }
181 }