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.cms.util.QueryUtil;
37 import info.magnolia.commands.MgnlCommand;
38 import info.magnolia.context.Context;
39 import info.magnolia.context.MgnlContext;
40 import info.magnolia.jcr.util.NodeTypes;
41 import info.magnolia.jcr.util.NodeUtil;
42 import info.magnolia.jcr.util.PropertyUtil;
43 import info.magnolia.module.rssaggregator.RSSAggregator;
44 import info.magnolia.module.rssaggregator.RSSAggregatorConstants;
45 import info.magnolia.module.rssaggregator.RSSAggregatorNodeTypes;
46 import info.magnolia.module.rssaggregator.util.PlanetUtil;
47
48 import java.util.ArrayList;
49 import java.util.Calendar;
50 import java.util.Date;
51 import java.util.List;
52
53 import javax.jcr.Node;
54 import javax.jcr.NodeIterator;
55 import javax.jcr.RepositoryException;
56 import javax.jcr.Session;
57
58 import org.apache.commons.collections.MapIterator;
59 import org.apache.commons.collections.keyvalue.MultiKey;
60 import org.apache.commons.collections.map.MultiKeyMap;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64
65
66
67
68
69 public class CollectStatisticsCommand extends MgnlCommand {
70
71 private static final Logger log = LoggerFactory.getLogger(CollectStatisticsCommand.class);
72
73 private static final String FEED_DATA_NAME = "planetData";
74 private static final String STATISTICS_NODE = "statistics";
75 private static final String STATS_AUTHORS_NODE = "authors";
76
77 private Session session;
78 private Date statisticsStartDate;
79 private int authorCount;
80
81 @Override
82 public boolean execute(Context context) throws Exception {
83 log.info("Starting command for creating Planet data statistics.");
84
85 session = MgnlContext.getJCRSession(RSSAggregatorConstants.WORKSPACE);
86
87 traverseFeedEntries(session.getRootNode());
88
89 log.info("Finished generating Planet data statistics.");
90
91 return true;
92 }
93
94
95
96
97
98
99 protected Date getStatisticsStartDate() {
100 RSSAggregator module = RSSAggregator.getInstance();
101 int lastMonthsIncluded = module.getMonthsIncluded();
102
103 Calendar calendar = Calendar.getInstance();
104 calendar.setTime(new Date());
105 calendar.add(Calendar.MONTH, -lastMonthsIncluded);
106
107 return calendar.getTime();
108 }
109
110 private void traverseFeedEntries(Node rssParent) throws RepositoryException {
111 List<Node> feeds = NodeUtil.asList(NodeUtil.getNodes(rssParent, NodeTypes.Folder.NAME));
112 feeds.add(rssParent);
113 for (Node rootOrFolder : feeds) {
114 this.authorCount = 0;
115 doTraverseFeedEntries(rootOrFolder);
116 }
117 }
118
119
120
121
122 private void doTraverseFeedEntries(Node rssParent) throws RepositoryException {
123 Date startDate = getStatisticsStartDate();
124 log.info("Statistics will be build on content with date " + startDate + " or later.");
125
126 if (rssParent != null) {
127 NodeIterator feeds = rssParent.getNodes();
128 while (feeds.hasNext()) {
129 Node feedNode = feeds.nextNode();
130 if (NodeUtil.isNodeType(feedNode, RSSAggregatorNodeTypes.RSSAggregator.NAME) && PlanetUtil.isPlanetNode(feedNode)) {
131 log.info("Creating statistics for planet feed: " + feedNode.getName());
132
133 MultiKeyMap entryMap = new MultiKeyMap();
134
135 String sql2 = "select * from [mgnl:content] as t where ISDESCENDANTNODE([" + feedNode.getPath() + "/"
136 + FEED_DATA_NAME + "]) and t.rssLink IS NOT NULL AND t.author IS NOT NULL ORDER BY t.author, t.rssLink";
137
138 NodeIterator entries = QueryUtil.search(RSSAggregatorConstants.WORKSPACE, sql2);
139 while (entries.hasNext()) {
140 Node entry = entries.nextNode();
141 createMapEntry(entryMap, entry);
142 }
143 createStatisticsNodes(entryMap, feedNode);
144 }
145 }
146 } else {
147 log.info("Could not find parent node for data/rssaggregator feed entries.");
148 }
149 }
150
151
152
153
154
155
156
157 @SuppressWarnings("unchecked")
158 protected void createMapEntry(MultiKeyMap mkm, Node blogEntry) {
159 List<Node> blogEntries = new ArrayList<Node>();
160
161 try {
162 String author = PlanetUtil.formatName(blogEntry, "author");
163 String rssLink = PropertyUtil.getString(blogEntry, "rssLink", "");
164
165 if (mkm.containsKey(author, rssLink)) {
166 blogEntries = (List<Node>) mkm.get(author, rssLink);
167 }
168
169 if (blogEntry.hasProperty("pubDate")) {
170 blogEntries.add(blogEntry);
171 mkm.put(author, rssLink, blogEntries);
172 }
173 } catch (Exception e) {
174 log.error("Could not add blog entry to statistics list: " + e.getMessage());
175 }
176 }
177
178
179
180
181
182
183
184 @SuppressWarnings("unchecked")
185 protected void createStatisticsNodes(MultiKeyMap statEntries, Node topNode) {
186 Date startDate = getStatisticsStartDate();
187 try {
188
189 if (topNode.hasNode(STATISTICS_NODE)) {
190 String absPath = topNode.getNode(STATISTICS_NODE).getPath();
191 topNode.getSession().removeItem(absPath);
192 }
193
194 Node authors = NodeUtil.createPath(topNode, STATISTICS_NODE + "/" + STATS_AUTHORS_NODE,
195 NodeTypes.Content.NAME, false);
196
197 int authorCount = 0;
198 MapIterator mit = statEntries.mapIterator();
199 while (mit.hasNext()) {
200 mit.next();
201
202 MultiKey mk = (MultiKey) mit.getKey();
203 String author = (String) mk.getKey(0);
204 String rssLink = (String) mk.getKey(1);
205
206 Node trgNode = PlanetUtil.findAuthorNode(authors, author, rssLink, authorCount);
207 PropertyUtil.setProperty(trgNode, "author", author);
208 PropertyUtil.setProperty(trgNode, "feedLink", rssLink);
209
210 Node countedPosts = NodeUtil.createPath(trgNode, "countedPosts", NodeTypes.Content.NAME, false);
211
212 List<Node> blogEntries = (List<Node>) mit.getValue();
213
214 long postCount = 0;
215 for (Node entry : blogEntries) {
216 PropertyUtil.setProperty(trgNode, "blogLink", PropertyUtil.getString(entry, "authorLink", ""));
217
218 Date pubDate = new Date(entry.getProperty("pubDate").getLong());
219 if (pubDate.after(startDate)) {
220 NodeUtil.createPath(countedPosts, entry.getIdentifier(), NodeTypes.Content.NAME, false);
221 postCount++;
222 }
223 }
224
225 PropertyUtil.setProperty(trgNode, "postCount", postCount);
226 authorCount++;
227
228 session.save();
229 }
230 } catch (Exception e) {
231 log.error("Problem while creating nodes for statistics: " + e.getMessage());
232 }
233 }
234
235 }