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.templates.components;
35
36 import info.magnolia.cms.util.QueryUtil;
37 import info.magnolia.context.MgnlContext;
38 import info.magnolia.jcr.iterator.FilteringNodeIterator;
39 import info.magnolia.jcr.predicate.NodeTypePredicate;
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.jcr.util.SessionUtil;
44 import info.magnolia.module.rssaggregator.RSSAggregatorConstants;
45 import info.magnolia.rendering.model.RenderingModel;
46 import info.magnolia.rendering.model.RenderingModelImpl;
47 import info.magnolia.rendering.template.RenderableDefinition;
48 import info.magnolia.templating.functions.TemplatingFunctions;
49
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.Date;
53 import java.util.List;
54
55 import javax.inject.Inject;
56 import javax.jcr.Node;
57 import javax.jcr.NodeIterator;
58 import javax.jcr.RepositoryException;
59 import javax.jcr.query.Query;
60 import javax.jcr.query.QueryManager;
61 import javax.jcr.query.QueryResult;
62
63 import org.apache.commons.lang.StringUtils;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66
67
68
69
70
71
72 public abstract class AbstractFeedModel<RD extends RenderableDefinition> extends RenderingModelImpl<RD> implements RenderingModel<RD> {
73 protected final static Logger log = LoggerFactory.getLogger(AbstractFeedModel.class);
74
75 public static final String ORDER_BY_PUBLICATION_DATE = "@pubDate";
76 public static final String ORDER_BY_TITLE_NAME = "@title";
77 public static final String SORT_ASCENDING = "ascending";
78 public static final String SORT_DESCENDING = "descending";
79
80 protected static final String FEEDS_NODE = "feeds";
81
82 protected static final int MAX_RESULTS = 20;
83
84 protected final TemplatingFunctions templatingFunctions;
85
86 @Inject
87 public AbstractFeedModel(Node content, RD definition, RenderingModel<?> parent, TemplatingFunctions templatingFunctions) {
88 super(content, definition, parent);
89 this.templatingFunctions = templatingFunctions;
90 }
91
92
93
94
95
96 @SuppressWarnings("unused")
97 public Date convertPubDate(Object timestamp) {
98 if (timestamp == null) {
99 return null;
100 }
101 if (timestamp instanceof String) {
102 if (StringUtils.isEmpty((String) timestamp)) {
103 return null;
104 }
105 return new Date(Long.parseLong((String) timestamp));
106 }
107
108 return new Date((Long) timestamp);
109 }
110
111
112
113
114
115
116
117
118
119 public Collection<Node> getPlanetItems(String feedPath, String condition, String order, boolean limit) {
120 int maxResults = MAX_RESULTS;
121
122 List<Node> results = new ArrayList<Node>();
123 try {
124 if (limit && content.hasProperty("maxResults")) {
125 maxResults = (int) content.getProperty("maxResults").getLong();
126 }
127 String feedName = SessionUtil.getNode(RSSAggregatorConstants.WORKSPACE, PropertyUtil.getString(content, "feed")).getName();
128
129 String sql = "select * from [mgnl:content] as t where ISDESCENDANTNODE([/" + feedName + "/" + feedPath + "])";
130 if (StringUtils.isNotBlank(condition)) {
131 sql += " " + condition;
132 }
133 if (StringUtils.isNotBlank(order)) {
134 sql += " " + order;
135 }
136 NodeIterator nit = QueryUtil.search(RSSAggregatorConstants.WORKSPACE, sql);
137
138 int resCount = 0;
139 while (nit.hasNext()) {
140 resCount++;
141 Node statNode = nit.nextNode();
142 if (limit) {
143 if (resCount <= maxResults) {
144 results.add(statNode);
145 } else {
146 break;
147 }
148
149 } else {
150 results.add(statNode);
151 }
152 }
153 return results;
154 } catch (RepositoryException e) {
155 log.error(e.getLocalizedMessage(), e);
156 }
157 return null;
158 }
159
160
161
162
163
164
165
166 @SuppressWarnings("unused")
167 public String getFeedTitle(String feedLink) {
168 try {
169 if (content.hasProperty("feed")) {
170 Node rssParent = SessionUtil.getNode(RSSAggregatorConstants.WORKSPACE, content.getProperty("feed").getString());
171 return getFeedProperty(rssParent, FEEDS_NODE, "link", feedLink, "title");
172 }
173 } catch (RepositoryException e) {
174 log.error("Problem while fetching feed title for statistics: " + e.getMessage());
175 }
176 return null;
177 }
178
179
180
181
182
183
184
185
186
187
188 public String getFeedProperty(Node parentNode, String subNode, String searchProperty, String searchValue, String resultProperty) {
189 String propertyValue = null;
190 try {
191 if (parentNode != null) {
192 String searchNode = "/" + parentNode.getName() + "/" + subNode;
193 String sql = "select * from [nt:base] as t where ISDESCENDANTNODE([" + searchNode + "]) "
194 + "and t." + searchProperty + "='" + searchValue + "'";
195
196
197 NodeIterator nit = QueryUtil.search(RSSAggregatorConstants.WORKSPACE, sql);
198
199 if (nit != null && nit.hasNext()) {
200 Node fsn = nit.nextNode();
201
202 if (NodeUtil.getCollectionFromNodeIterator(nit).size() == 0) {
203 if (fsn.hasProperty(resultProperty)) {
204 propertyValue = fsn.getProperty(resultProperty).getString();
205 }
206 }
207 }
208 }
209 } catch (RepositoryException e) {
210 log.error("Problem while getting node property: " + e.getMessage());
211 }
212 return propertyValue;
213 }
214
215 public String getContextPath() {
216 return MgnlContext.getContextPath();
217 }
218
219 protected NodeIterator runQuery(String queryString) throws RepositoryException {
220 QueryManager qm = MgnlContext.getJCRSession(RSSAggregatorConstants.WORKSPACE).getWorkspace().getQueryManager();
221 log.debug(queryString);
222 Query q = qm.createQuery(queryString, "xpath");
223 QueryResult res = q.execute();
224 NodeIterator feeds = res.getNodes();
225 FilteringNodeIterator iterator = new FilteringNodeIterator(feeds, new NodeTypePredicate(NodeTypes.Content.NAME));
226 return iterator;
227 }
228 }