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