1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.services.cms.timeline.impl;
18
19 import org.exoplatform.container.xml.InitParams;
20 import org.exoplatform.services.cms.templates.TemplateService;
21 import org.exoplatform.services.cms.timeline.TimelineService;
22 import org.exoplatform.services.jcr.RepositoryService;
23 import org.exoplatform.services.jcr.core.ManageableRepository;
24 import org.exoplatform.services.jcr.ext.common.SessionProvider;
25 import org.exoplatform.services.jcr.impl.core.query.QueryImpl;
26 import org.exoplatform.services.log.ExoLogger;
27 import org.exoplatform.services.log.Log;
28
29 import javax.jcr.Node;
30 import javax.jcr.NodeIterator;
31 import javax.jcr.RepositoryException;
32 import javax.jcr.Session;
33 import javax.jcr.query.Query;
34 import javax.jcr.query.QueryManager;
35 import javax.jcr.query.QueryResult;
36 import java.time.LocalDateTime;
37 import java.time.format.DateTimeFormatter;
38 import java.util.ArrayList;
39 import java.util.Calendar;
40 import java.util.GregorianCalendar;
41 import java.util.List;
42
43
44
45
46
47
48
49
50 public class TimelineServiceImpl implements TimelineService {
51
52 private static final Log LOG = ExoLogger.getLogger(TimelineServiceImpl.class.getName());
53 private static final String EXO_DATETIME = "exo:datetime";
54 private static final String EXO_MODIFIED_DATE = "exo:dateModified";
55 private static final String EXO_OWNER = "exo:owner";
56 private static final String SELECT_QUERY = "SELECT * FROM " + EXO_DATETIME + " WHERE ";
57 private static final String TIME_FORMAT_TAIL = "T00:00:00.000";
58 private static final DateTimeFormatter formatDateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd");
59 private RepositoryService repositoryService_;
60 private TemplateService templateService_;
61 private int itemPerTimeline = 5;
62
63 public TimelineServiceImpl(RepositoryService repoService, TemplateService templateService,
64 InitParams initParams) throws Exception {
65 repositoryService_ = repoService;
66 templateService_ = templateService;
67 itemPerTimeline = Integer.parseInt(initParams.getValueParam("itemPerTimeline").getValue());
68 }
69
70
71
72
73 public List<Node> getDocumentsOfEarlierThisYear(String nodePath,
74 String workspace,
75 SessionProvider sessionProvider,
76 String userName,
77 boolean byUser) throws Exception {
78 return getDocumentsOfEarlierThisYear(nodePath, workspace, sessionProvider, userName, byUser, true);
79 }
80
81
82
83
84 public List<Node> getDocumentsOfEarlierThisYear(String nodePath,
85 String workspace,
86 SessionProvider sessionProvider,
87 String userName,
88 boolean byUser,
89 boolean isLimit) throws Exception {
90
91 List<Node> documentsOfYear = new ArrayList<Node>();
92 Session session = getSession(sessionProvider, workspace);
93 Calendar currentTime = new GregorianCalendar();
94 String strBeginningOfThisMonthTime = getStrBeginningOfThisMonthTime(currentTime);
95 String strBeginningOfThisYearTime = getStrBeginningOfThisYearTime(currentTime);
96 StringBuilder sb = new StringBuilder();
97 String pathPattern = buildPathPattern(nodePath);
98 sb.append(SELECT_QUERY);
99 if (pathPattern.length() > 0) {
100 sb.append(pathPattern).append(" AND ");
101 }
102 sb.append("((" + buildDocumentTypePattern() + ")")
103 .append(" OR (jcr:primaryType='exo:symlink' AND (" + buildSymlinkDocumentTypePattern() + ")))")
104 .append(" AND ")
105 .append(" (" + EXO_MODIFIED_DATE + " >= TIMESTAMP '" + strBeginningOfThisYearTime + "')")
106 .append(" AND ")
107 .append(" (" + EXO_MODIFIED_DATE + " < TIMESTAMP '" + strBeginningOfThisMonthTime + "')");
108
109 if (byUser) {
110 sb.append(" AND ").append(" (" + EXO_OWNER + " = '" + userName + "')");
111 }
112 sb.append(" ORDER BY ").append(EXO_MODIFIED_DATE);
113
114 QueryResult result = executeQuery(session, sb.toString(), Query.SQL, isLimit);
115 NodeIterator nodeIter = result.getNodes();
116 while (nodeIter.hasNext()) {
117 documentsOfYear.add(nodeIter.nextNode());
118 }
119 return documentsOfYear;
120 }
121
122
123
124
125 public List<Node> getDocumentsOfEarlierThisMonth(String nodePath,
126 String workspace,
127 SessionProvider sessionProvider,
128 String userName,
129 boolean byUser) throws Exception {
130 return getDocumentsOfEarlierThisMonth(nodePath, workspace, sessionProvider, userName, byUser, true);
131 }
132
133
134
135 public List<Node> getDocumentsOfEarlierThisMonth(String nodePath,
136 String workspace,
137 SessionProvider sessionProvider,
138 String userName,
139 boolean byUser,
140 boolean isLimit) throws Exception {
141
142 List<Node> documentsOfMonth = new ArrayList<Node>();
143 Session session = getSession(sessionProvider, workspace);
144 Calendar currentTime = new GregorianCalendar();
145 String strBeginningOfThisWeekTime = getStrBeginningOfThisWeekTime(currentTime);
146 String strBeginningOfThisMonthTime = getStrBeginningOfThisMonthTime(currentTime);
147 StringBuilder sb = new StringBuilder();
148 String pathPattern = buildPathPattern(nodePath);
149 sb.append(SELECT_QUERY);
150 if (pathPattern.length() > 0) {
151 sb.append(pathPattern).append(" AND ");
152 }
153 sb.append("((" + buildDocumentTypePattern() + ")")
154 .append(" OR (jcr:primaryType='exo:symlink' AND (" + buildSymlinkDocumentTypePattern() + ")))")
155 .append(" AND ")
156 .append(" (" + EXO_MODIFIED_DATE + " >= TIMESTAMP '" + strBeginningOfThisMonthTime + "')")
157 .append(" AND ")
158 .append(" (" + EXO_MODIFIED_DATE + " < TIMESTAMP '" + strBeginningOfThisWeekTime + "')");
159
160 if (byUser) {
161 sb.append(" AND ").append(" (" + EXO_OWNER + " = '" + userName + "')");
162 }
163 sb.append(" ORDER BY ").append(EXO_MODIFIED_DATE);
164
165 QueryResult result = executeQuery(session, sb.toString(), Query.SQL, isLimit);
166 NodeIterator nodeIter = result.getNodes();
167 while (nodeIter.hasNext()) {
168 documentsOfMonth.add(nodeIter.nextNode());
169 }
170 return documentsOfMonth;
171 }
172
173
174
175
176 public List<Node> getDocumentsOfEarlierThisWeek(String nodePath,
177 String workspace,
178 SessionProvider sessionProvider,
179 String userName,
180 boolean byUser) throws Exception {
181 return getDocumentsOfEarlierThisWeek(nodePath, workspace, sessionProvider, userName, byUser, true);
182 }
183
184
185
186 public List<Node> getDocumentsOfEarlierThisWeek(String nodePath,
187 String workspace,
188 SessionProvider sessionProvider,
189 String userName,
190 boolean byUser,
191 boolean isLimit) throws Exception {
192
193 List<Node> documentsOfWeek = new ArrayList<Node>();
194 Session session = getSession(sessionProvider, workspace);
195 Calendar currentTime = new GregorianCalendar();
196 String strYesterdayTime = getStrYesterdayTime(currentTime);
197 String strBeginningOfThisWeekTime = getStrBeginningOfThisWeekTime(currentTime);
198 StringBuilder sb = new StringBuilder();
199 String pathPattern = buildPathPattern(nodePath);
200 sb.append(SELECT_QUERY);
201 if(pathPattern.length() > 0) {
202 sb.append(pathPattern).append(" AND ");
203 }
204 sb.append("((" + buildDocumentTypePattern() + ")")
205 .append(" OR (jcr:primaryType='exo:symlink' AND (" + buildSymlinkDocumentTypePattern() + ")))")
206 .append(" AND ")
207 .append(" (" + EXO_MODIFIED_DATE + " >= TIMESTAMP '" + strBeginningOfThisWeekTime + "')")
208 .append(" AND ")
209 .append(" (" + EXO_MODIFIED_DATE + " < TIMESTAMP '" + strYesterdayTime + "')");
210
211 if (byUser) {
212 sb.append(" AND ").append(" (" + EXO_OWNER + " = '" + userName + "')");
213 }
214 sb.append(" ORDER BY ").append(EXO_MODIFIED_DATE);
215
216 QueryResult result = executeQuery(session, sb.toString(), Query.SQL, isLimit);
217 NodeIterator nodeIter = result.getNodes();
218 while(nodeIter.hasNext()) {
219 documentsOfWeek.add(nodeIter.nextNode());
220 }
221 return documentsOfWeek;
222 }
223
224
225
226
227 public List<Node> getDocumentsOfYesterday(String nodePath,
228 String workspace,
229 SessionProvider sessionProvider,
230 String userName,
231 boolean byUser) throws Exception {
232 return getDocumentsOfYesterday(nodePath, workspace, sessionProvider, userName, byUser, true);
233 }
234
235
236
237
238 public List<Node> getDocumentsOfYesterday(String nodePath,
239 String workspace,
240 SessionProvider sessionProvider,
241 String userName,
242 boolean byUser,
243 boolean isLimit) throws Exception {
244
245 List<Node> documentsOfYesterday = new ArrayList<Node>();
246 Session session = getSession(sessionProvider, workspace);
247 Calendar currentTime = new GregorianCalendar();
248 String strTodayTime = getStrTodayTime(currentTime);
249 String strYesterdayTime = getStrYesterdayTime(currentTime);
250 StringBuilder sb = new StringBuilder();
251 String pathPattern = buildPathPattern(nodePath);
252 sb.append(SELECT_QUERY);
253 if(pathPattern.length() > 0) {
254 sb.append(pathPattern).append(" AND ");
255 }
256 sb.append("((" + buildDocumentTypePattern() + ")")
257 .append(" OR (jcr:primaryType='exo:symlink' AND (" + buildSymlinkDocumentTypePattern() + ")))")
258 .append(" AND ")
259 .append(" (" + EXO_MODIFIED_DATE + " >= TIMESTAMP '" + strYesterdayTime + "')")
260 .append(" AND ")
261 .append(" (" + EXO_MODIFIED_DATE + " < TIMESTAMP '" + strTodayTime + "')");
262
263 if (byUser) {
264 sb.append(" AND ").append(" (" + EXO_OWNER + " = '" + userName + "')");
265 }
266 sb.append(" ORDER BY ").append(EXO_MODIFIED_DATE);
267
268 QueryResult result = executeQuery(session, sb.toString(), Query.SQL, isLimit);
269 NodeIterator nodeIter = result.getNodes();
270 while(nodeIter.hasNext()) {
271 documentsOfYesterday.add(nodeIter.nextNode());
272 }
273 return documentsOfYesterday;
274 }
275
276
277
278
279 public List<Node> getDocumentsOfToday(String nodePath,
280 String workspace,
281 SessionProvider sessionProvider,
282 String userName,
283 boolean byUser) throws Exception {
284 return getDocumentsOfToday(nodePath, workspace, sessionProvider, userName, byUser, true);
285 }
286
287
288
289
290 public List<Node> getDocumentsOfToday(String nodePath,
291 String workspace,
292 SessionProvider sessionProvider,
293 String userName,
294 boolean byUser,
295 boolean isLimit) throws Exception {
296 List<Node> documentsOfToday = new ArrayList<Node>();
297 Session session = getSession(sessionProvider, workspace);
298 Calendar currentTime = new GregorianCalendar();
299 String strTodayTime = getStrTodayTime(currentTime);
300 StringBuilder sb = new StringBuilder();
301 String pathPattern = buildPathPattern(nodePath);
302 sb.append(SELECT_QUERY);
303 if(pathPattern.length() > 0) {
304 sb.append(pathPattern).append(" AND ");
305 }
306 sb.append("((" + buildDocumentTypePattern() + ")")
307 .append(" OR (jcr:primaryType='exo:symlink' AND (" + buildSymlinkDocumentTypePattern() + ")))")
308 .append(" AND ")
309 .append(" (" + EXO_MODIFIED_DATE + " >= TIMESTAMP '" + strTodayTime + "')");
310 if (byUser) {
311 sb.append(" AND ").append(" (" + EXO_OWNER + " = '" + userName + "')");
312 }
313 sb.append(" ORDER BY ").append(EXO_MODIFIED_DATE).append(" DESC");
314
315 QueryResult result = executeQuery(session, sb.toString(), Query.SQL, isLimit);
316 NodeIterator nodeIter = result.getNodes();
317 while(nodeIter.hasNext()) {
318 documentsOfToday.add(nodeIter.nextNode());
319 }
320 return documentsOfToday;
321 }
322
323 private Session getSession(SessionProvider sessionProvider, String workspace) throws RepositoryException {
324 ManageableRepository manageableRepository = repositoryService_.getCurrentRepository();
325 return sessionProvider.getSession(workspace, manageableRepository);
326 }
327
328 private QueryResult executeQuery(Session session,
329 String statement,
330 String language,
331 boolean isLimt) throws Exception {
332 try {
333 QueryManager queryManager = session.getWorkspace().getQueryManager();
334 QueryImpl query = (QueryImpl) queryManager.createQuery(statement, language);
335 if (isLimt) {
336 query.setLimit(itemPerTimeline);
337 }
338 return query.execute();
339 } catch (Exception e) {
340 if (LOG.isErrorEnabled()) {
341 LOG.error("Can not execute query", e);
342 }
343 return null;
344 }
345 }
346
347 private String buildDocumentTypePattern() throws Exception {
348 List<String> documentFileTypes = templateService_.getAllDocumentNodeTypes();
349 StringBuilder sb = new StringBuilder();
350 for(String documentType : documentFileTypes) {
351 if(sb.length() > 0) sb.append(" OR ");
352 sb.append("jcr:primaryType='"+documentType+"'");
353 }
354 return sb.toString();
355 }
356
357 private String buildSymlinkDocumentTypePattern() throws Exception {
358 List<String> documentFileTypes = templateService_.getAllDocumentNodeTypes();
359 StringBuilder sb = new StringBuilder();
360 for(String documentType : documentFileTypes) {
361 if(sb.length() > 0) sb.append(" OR ");
362 sb.append("exo:primaryType='" + documentType + "'");
363 }
364 return sb.toString();
365 }
366
367 private String getStrTodayTime(Calendar calendar) {
368 String currentDate = LocalDateTime.ofInstant(calendar.getTime().toInstant(), calendar.getTimeZone().toZoneId()).format(formatDateTime);
369 return currentDate + TIME_FORMAT_TAIL;
370 }
371
372 private String buildPathPattern(String nodePath) {
373 if(nodePath.equals("/")) return "";
374 return "jcr:path LIKE '" + nodePath + "/%" + "'";
375 }
376
377 private String getStrYesterdayTime(Calendar calendar) {
378 Calendar yesterday = (Calendar)calendar.clone();
379 yesterday.add(Calendar.DATE, -1);
380 String yesterdayDate = LocalDateTime.ofInstant(yesterday.getTime().toInstant(), yesterday.getTimeZone().toZoneId()).format(formatDateTime);
381 return yesterdayDate + TIME_FORMAT_TAIL;
382 }
383
384 private String getStrBeginningOfThisWeekTime(Calendar calendar) {
385 Calendar monday = (Calendar)calendar.clone();
386 while (monday.get(Calendar.WEEK_OF_YEAR) == calendar.get(Calendar.WEEK_OF_YEAR)) {
387 monday.add(Calendar.DATE, -1);
388 }
389 monday.add(Calendar.DATE, 1);
390 String mondayDate = LocalDateTime.ofInstant(monday.getTime().toInstant(), monday.getTimeZone().toZoneId()).format(formatDateTime);
391 return mondayDate + TIME_FORMAT_TAIL;
392 }
393
394 private String getStrBeginningOfThisMonthTime(Calendar calendar) {
395 Calendar theFirst = (Calendar)calendar.clone();
396 theFirst.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 1, 0, 0, 0);
397 String theFirstDate = LocalDateTime.ofInstant(theFirst.getTime().toInstant(), theFirst.getTimeZone().toZoneId()).format(formatDateTime);
398 return theFirstDate + TIME_FORMAT_TAIL;
399 }
400
401 private String getStrBeginningOfThisYearTime(Calendar calendar) {
402 Calendar theFirst = (Calendar)calendar.clone();
403 theFirst.set(calendar.get(Calendar.YEAR), 0, 1, 0, 0, 0);
404 String theFirstDate = LocalDateTime.ofInstant(theFirst.getTime().toInstant(), theFirst.getTimeZone().toZoneId()).format(formatDateTime);
405 return theFirstDate + TIME_FORMAT_TAIL;
406 }
407
408
409
410
411
412
413
414
415 public int getItemPerTimeline() {
416 if (itemPerTimeline <= 0) {
417 return 5;
418 }
419 return itemPerTimeline;
420 }
421 }