001
014
015 package com.liferay.portlet.bookmarks.service.impl;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.json.JSONFactoryUtil;
020 import com.liferay.portal.kernel.json.JSONObject;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.search.Indexable;
024 import com.liferay.portal.kernel.search.IndexableType;
025 import com.liferay.portal.kernel.util.ArrayUtil;
026 import com.liferay.portal.kernel.util.ContentTypes;
027 import com.liferay.portal.kernel.util.OrderByComparator;
028 import com.liferay.portal.kernel.util.StringPool;
029 import com.liferay.portal.kernel.util.Validator;
030 import com.liferay.portal.kernel.workflow.WorkflowConstants;
031 import com.liferay.portal.model.ResourceConstants;
032 import com.liferay.portal.model.User;
033 import com.liferay.portal.service.ServiceContext;
034 import com.liferay.portal.service.ServiceContextUtil;
035 import com.liferay.portal.util.Portal;
036 import com.liferay.portal.util.PortletKeys;
037 import com.liferay.portal.util.SubscriptionSender;
038 import com.liferay.portlet.asset.model.AssetEntry;
039 import com.liferay.portlet.asset.model.AssetLinkConstants;
040 import com.liferay.portlet.bookmarks.EntryURLException;
041 import com.liferay.portlet.bookmarks.model.BookmarksEntry;
042 import com.liferay.portlet.bookmarks.model.BookmarksFolder;
043 import com.liferay.portlet.bookmarks.model.BookmarksFolderConstants;
044 import com.liferay.portlet.bookmarks.service.base.BookmarksEntryLocalServiceBaseImpl;
045 import com.liferay.portlet.bookmarks.social.BookmarksActivityKeys;
046 import com.liferay.portlet.bookmarks.util.BookmarksUtil;
047 import com.liferay.portlet.bookmarks.util.comparator.EntryModifiedDateComparator;
048 import com.liferay.portlet.social.model.SocialActivityConstants;
049 import com.liferay.portlet.trash.model.TrashEntry;
050
051 import java.util.Date;
052 import java.util.List;
053 import java.util.Locale;
054 import java.util.Map;
055
056 import javax.portlet.PortletPreferences;
057
058
063 public class BookmarksEntryLocalServiceImpl
064 extends BookmarksEntryLocalServiceBaseImpl {
065
066 @Indexable(type = IndexableType.REINDEX)
067 public BookmarksEntry addEntry(
068 long userId, long groupId, long folderId, String name, String url,
069 String description, ServiceContext serviceContext)
070 throws PortalException, SystemException {
071
072
073
074 User user = userPersistence.findByPrimaryKey(userId);
075
076 if (Validator.isNull(name)) {
077 name = url;
078 }
079
080 Date now = new Date();
081
082 validate(url);
083
084 long entryId = counterLocalService.increment();
085
086 BookmarksEntry entry = bookmarksEntryPersistence.create(entryId);
087
088 entry.setUuid(serviceContext.getUuid());
089 entry.setGroupId(groupId);
090 entry.setCompanyId(user.getCompanyId());
091 entry.setUserId(user.getUserId());
092 entry.setUserName(user.getFullName());
093 entry.setCreateDate(serviceContext.getCreateDate(now));
094 entry.setModifiedDate(serviceContext.getModifiedDate(now));
095 entry.setFolderId(folderId);
096 entry.setName(name);
097 entry.setUrl(url);
098 entry.setDescription(description);
099 entry.setExpandoBridgeAttributes(serviceContext);
100
101 bookmarksEntryPersistence.update(entry);
102
103
104
105 resourceLocalService.addModelResources(entry, serviceContext);
106
107
108
109 updateAsset(
110 userId, entry, serviceContext.getAssetCategoryIds(),
111 serviceContext.getAssetTagNames(),
112 serviceContext.getAssetLinkEntryIds());
113
114
115
116 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
117
118 extraDataJSONObject.put("title", entry.getName());
119
120 socialActivityLocalService.addActivity(
121 userId, groupId, BookmarksEntry.class.getName(), entryId,
122 BookmarksActivityKeys.ADD_ENTRY, extraDataJSONObject.toString(), 0);
123
124
125
126 notifySubscribers(entry, serviceContext);
127
128 return entry;
129 }
130
131 public void deleteEntries(long groupId, long folderId)
132 throws PortalException, SystemException {
133
134 deleteEntries(groupId, folderId, true);
135 }
136
137 public void deleteEntries(
138 long groupId, long folderId, boolean includeTrashedEntries)
139 throws PortalException, SystemException {
140
141 List<BookmarksEntry> entries = bookmarksEntryPersistence.findByG_F(
142 groupId, folderId);
143
144 for (BookmarksEntry entry : entries) {
145 if (includeTrashedEntries || !entry.isInTrash()) {
146 bookmarksEntryLocalService.deleteEntry(entry);
147 }
148 }
149 }
150
151 @Indexable(type = IndexableType.DELETE)
152 public BookmarksEntry deleteEntry(BookmarksEntry entry)
153 throws PortalException, SystemException {
154
155
156
157 bookmarksEntryPersistence.remove(entry);
158
159
160
161 resourceLocalService.deleteResource(
162 entry, ResourceConstants.SCOPE_INDIVIDUAL);
163
164
165
166 assetEntryLocalService.deleteEntry(
167 BookmarksEntry.class.getName(), entry.getEntryId());
168
169
170
171 expandoValueLocalService.deleteValues(
172 BookmarksEntry.class.getName(), entry.getEntryId());
173
174
175
176 subscriptionLocalService.deleteSubscriptions(
177 entry.getCompanyId(), BookmarksEntry.class.getName(),
178 entry.getEntryId());
179
180
181
182 trashEntryLocalService.deleteEntry(
183 BookmarksEntry.class.getName(), entry.getEntryId());
184
185 return entry;
186 }
187
188 @Indexable(type = IndexableType.DELETE)
189 public BookmarksEntry deleteEntry(long entryId)
190 throws PortalException, SystemException {
191
192 BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(
193 entryId);
194
195 return deleteEntry(entry);
196 }
197
198 public List<BookmarksEntry> getEntries(
199 long groupId, long folderId, int start, int end)
200 throws SystemException {
201
202 return bookmarksEntryPersistence.findByG_F_S(
203 groupId, folderId, WorkflowConstants.STATUS_APPROVED, start, end);
204 }
205
206 public List<BookmarksEntry> getEntries(
207 long groupId, long folderId, int start, int end,
208 OrderByComparator orderByComparator)
209 throws SystemException {
210
211 return bookmarksEntryPersistence.findByG_F_S(
212 groupId, folderId, WorkflowConstants.STATUS_APPROVED, start, end,
213 orderByComparator);
214 }
215
216 public int getEntriesCount(long groupId, long folderId)
217 throws SystemException {
218
219 return bookmarksEntryPersistence.countByG_F_S(
220 groupId, folderId, WorkflowConstants.STATUS_APPROVED);
221 }
222
223 public BookmarksEntry getEntry(long entryId)
224 throws PortalException, SystemException {
225
226 return bookmarksEntryPersistence.findByPrimaryKey(entryId);
227 }
228
229 public int getFoldersEntriesCount(long groupId, List<Long> folderIds)
230 throws SystemException {
231
232 return bookmarksEntryPersistence.countByG_F_S(
233 groupId,
234 ArrayUtil.toArray(folderIds.toArray(new Long[folderIds.size()])),
235 WorkflowConstants.STATUS_APPROVED);
236 }
237
238 public List<BookmarksEntry> getGroupEntries(
239 long groupId, int start, int end)
240 throws SystemException {
241
242 return bookmarksEntryPersistence.findByG_S(
243 groupId, WorkflowConstants.STATUS_APPROVED, start, end,
244 new EntryModifiedDateComparator());
245 }
246
247 public List<BookmarksEntry> getGroupEntries(
248 long groupId, long userId, int start, int end)
249 throws SystemException {
250
251 OrderByComparator orderByComparator = new EntryModifiedDateComparator();
252
253 if (userId <= 0) {
254 return bookmarksEntryPersistence.findByG_S(
255 groupId, WorkflowConstants.STATUS_APPROVED, start, end,
256 orderByComparator);
257 }
258 else {
259 return bookmarksEntryPersistence.findByG_U_S(
260 groupId, userId, WorkflowConstants.STATUS_APPROVED, start, end,
261 orderByComparator);
262 }
263 }
264
265 public int getGroupEntriesCount(long groupId) throws SystemException {
266 return bookmarksEntryPersistence.countByG_S(
267 groupId, WorkflowConstants.STATUS_APPROVED);
268 }
269
270 public int getGroupEntriesCount(long groupId, long userId)
271 throws SystemException {
272
273 if (userId <= 0) {
274 return getGroupEntriesCount(groupId);
275 }
276 else {
277 return bookmarksEntryPersistence.countByG_U_S(
278 groupId, userId, WorkflowConstants.STATUS_APPROVED);
279 }
280 }
281
282 public List<BookmarksEntry> getNoAssetEntries() throws SystemException {
283 return bookmarksEntryFinder.findByNoAssets();
284 }
285
286 @Indexable(type = IndexableType.REINDEX)
287 public BookmarksEntry moveEntry(long entryId, long parentFolderId)
288 throws PortalException, SystemException {
289
290 BookmarksEntry entry = getBookmarksEntry(entryId);
291
292 entry.setFolderId(parentFolderId);
293
294 bookmarksEntryPersistence.update(entry);
295
296 return entry;
297 }
298
299 public BookmarksEntry moveEntryFromTrash(
300 long userId, long entryId, long parentFolderId)
301 throws PortalException, SystemException {
302
303 BookmarksEntry entry = getBookmarksEntry(entryId);
304
305 if (entry.isInTrash()) {
306 restoreEntryFromTrash(userId, entryId);
307 }
308 else {
309 updateStatus(userId, entry, entry.getStatus());
310 }
311
312 return bookmarksEntryLocalService.moveEntry(entryId, parentFolderId);
313 }
314
315 @Indexable(type = IndexableType.REINDEX)
316 public BookmarksEntry moveEntryToTrash(long userId, BookmarksEntry entry)
317 throws PortalException, SystemException {
318
319 return updateStatus(userId, entry, WorkflowConstants.STATUS_IN_TRASH);
320 }
321
322 @Indexable(type = IndexableType.REINDEX)
323 public BookmarksEntry moveEntryToTrash(long userId, long entryId)
324 throws PortalException, SystemException {
325
326 BookmarksEntry entry = getEntry(entryId);
327
328 return moveEntryToTrash(userId, entry);
329 }
330
331 public BookmarksEntry openEntry(long userId, BookmarksEntry entry)
332 throws SystemException {
333
334 entry.setVisits(entry.getVisits() + 1);
335
336 bookmarksEntryPersistence.update(entry);
337
338 assetEntryLocalService.incrementViewCounter(
339 userId, BookmarksEntry.class.getName(), entry.getEntryId(), 1);
340
341 return entry;
342 }
343
344 public BookmarksEntry openEntry(long userId, long entryId)
345 throws PortalException, SystemException {
346
347 BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(
348 entryId);
349
350 return openEntry(userId, entry);
351 }
352
353 @Indexable(type = IndexableType.REINDEX)
354 public BookmarksEntry restoreEntryFromTrash(long userId, long entryId)
355 throws PortalException, SystemException {
356
357 BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(
358 entryId);
359
360 TrashEntry trashEntry = trashEntryLocalService.getEntry(
361 BookmarksEntry.class.getName(), entryId);
362
363 return updateStatus(userId, entry, trashEntry.getStatus());
364 }
365
366 public void subscribeEntry(long userId, long entryId)
367 throws PortalException, SystemException {
368
369 BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(
370 entryId);
371
372 subscriptionLocalService.addSubscription(
373 userId, entry.getGroupId(), BookmarksEntry.class.getName(),
374 entryId);
375 }
376
377 public void unsubscribeEntry(long userId, long entryId)
378 throws PortalException, SystemException {
379
380 subscriptionLocalService.deleteSubscription(
381 userId, BookmarksEntry.class.getName(), entryId);
382 }
383
384 public void updateAsset(
385 long userId, BookmarksEntry entry, long[] assetCategoryIds,
386 String[] assetTagNames, long[] assetLinkEntryIds)
387 throws PortalException, SystemException {
388
389 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
390 userId, entry.getGroupId(), entry.getCreateDate(),
391 entry.getModifiedDate(), BookmarksEntry.class.getName(),
392 entry.getEntryId(), entry.getUuid(), 0, assetCategoryIds,
393 assetTagNames, true, null, null, null, ContentTypes.TEXT_PLAIN,
394 entry.getName(), entry.getDescription(), null, entry.getUrl(), null,
395 0, 0, null, false);
396
397 assetLinkLocalService.updateLinks(
398 userId, assetEntry.getEntryId(), assetLinkEntryIds,
399 AssetLinkConstants.TYPE_RELATED);
400 }
401
402 @Indexable(type = IndexableType.REINDEX)
403 public BookmarksEntry updateEntry(
404 long userId, long entryId, long groupId, long folderId, String name,
405 String url, String description, ServiceContext serviceContext)
406 throws PortalException, SystemException {
407
408
409
410 BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(
411 entryId);
412
413 if (Validator.isNull(name)) {
414 name = url;
415 }
416
417 validate(url);
418
419 entry.setModifiedDate(serviceContext.getModifiedDate(null));
420 entry.setFolderId(folderId);
421 entry.setName(name);
422 entry.setUrl(url);
423 entry.setDescription(description);
424 entry.setExpandoBridgeAttributes(serviceContext);
425
426 bookmarksEntryPersistence.update(entry);
427
428
429
430 updateAsset(
431 userId, entry, serviceContext.getAssetCategoryIds(),
432 serviceContext.getAssetTagNames(),
433 serviceContext.getAssetLinkEntryIds());
434
435
436
437 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
438
439 extraDataJSONObject.put("title", entry.getName());
440
441 socialActivityLocalService.addActivity(
442 userId, entry.getGroupId(), BookmarksEntry.class.getName(), entryId,
443 BookmarksActivityKeys.UPDATE_ENTRY, extraDataJSONObject.toString(),
444 0);
445
446
447
448 notifySubscribers(entry, serviceContext);
449
450 return entry;
451 }
452
453 public BookmarksEntry updateStatus(
454 long userId, BookmarksEntry entry, int status)
455 throws PortalException, SystemException {
456
457
458
459 User user = userPersistence.findByPrimaryKey(userId);
460
461 int oldStatus = entry.getStatus();
462
463 entry.setStatus(status);
464 entry.setStatusByUserId(userId);
465 entry.setStatusByUserName(user.getScreenName());
466 entry.setStatusDate(new Date());
467
468 bookmarksEntryPersistence.update(entry);
469
470 if (status == WorkflowConstants.STATUS_APPROVED) {
471
472
473
474 assetEntryLocalService.updateVisible(
475 BookmarksEntry.class.getName(), entry.getEntryId(), true);
476
477
478
479 socialActivityCounterLocalService.enableActivityCounters(
480 BookmarksEntry.class.getName(), entry.getEntryId());
481
482 socialActivityLocalService.addActivity(
483 userId, entry.getGroupId(), BookmarksEntry.class.getName(),
484 entry.getEntryId(),
485 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
486 StringPool.BLANK, 0);
487 }
488 else if (status == WorkflowConstants.STATUS_IN_TRASH) {
489
490
491
492 assetEntryLocalService.updateVisible(
493 BookmarksEntry.class.getName(), entry.getEntryId(), false);
494
495
496
497 socialActivityCounterLocalService.disableActivityCounters(
498 BookmarksEntry.class.getName(), entry.getEntryId());
499
500 socialActivityLocalService.addActivity(
501 userId, entry.getGroupId(), BookmarksEntry.class.getName(),
502 entry.getEntryId(), SocialActivityConstants.TYPE_MOVE_TO_TRASH,
503 StringPool.BLANK, 0);
504 }
505
506
507
508 if (oldStatus == WorkflowConstants.STATUS_IN_TRASH) {
509 trashEntryLocalService.deleteEntry(
510 BookmarksEntry.class.getName(), entry.getEntryId());
511 }
512 else if (status == WorkflowConstants.STATUS_IN_TRASH) {
513 trashEntryLocalService.addTrashEntry(
514 userId, entry.getGroupId(), BookmarksEntry.class.getName(),
515 entry.getEntryId(), oldStatus, null, null);
516 }
517
518 return entry;
519 }
520
521 protected long getFolder(BookmarksEntry entry, long folderId)
522 throws SystemException {
523
524 if ((entry.getFolderId() != folderId) &&
525 (folderId != BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID)) {
526
527 BookmarksFolder newFolder =
528 bookmarksFolderPersistence.fetchByPrimaryKey(folderId);
529
530 if ((newFolder == null) ||
531 (entry.getGroupId() != newFolder.getGroupId())) {
532
533 folderId = entry.getFolderId();
534 }
535 }
536
537 return folderId;
538 }
539
540 protected void notifySubscribers(
541 BookmarksEntry entry, ServiceContext serviceContext)
542 throws PortalException, SystemException {
543
544 String layoutFullURL = serviceContext.getLayoutFullURL();
545
546 if (Validator.isNull(layoutFullURL)) {
547 return;
548 }
549
550 PortletPreferences preferences =
551 ServiceContextUtil.getPortletPreferences(serviceContext);
552
553 if (preferences == null) {
554 long ownerId = entry.getGroupId();
555 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
556 long plid = PortletKeys.PREFS_PLID_SHARED;
557 String portletId = PortletKeys.BOOKMARKS;
558 String defaultPreferences = null;
559
560 preferences = portletPreferencesLocalService.getPreferences(
561 entry.getCompanyId(), ownerId, ownerType, plid, portletId,
562 defaultPreferences);
563 }
564
565 if ((serviceContext.isCommandAdd() &&
566 !BookmarksUtil.getEmailEntryAddedEnabled(preferences)) ||
567 (serviceContext.isCommandUpdate() &&
568 !BookmarksUtil.getEmailEntryUpdatedEnabled(preferences))) {
569
570 return;
571 }
572
573 String statusByUserName = StringPool.BLANK;
574
575 try {
576 User user = userLocalService.getUserById(
577 serviceContext.getGuestOrUserId());
578
579 statusByUserName = user.getFullName();
580 }
581 catch (Exception e) {
582 _log.error(e, e);
583 }
584
585 String entryURL =
586 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "bookmarks" +
587 StringPool.SLASH + entry.getEntryId();
588
589 String fromAddress = BookmarksUtil.getEmailFromAddress(
590 preferences, entry.getCompanyId());
591 String fromName = BookmarksUtil.getEmailFromName(
592 preferences, entry.getCompanyId());
593
594 Map<Locale, String> localizedSubjectMap = null;
595 Map<Locale, String> localizedBodyMap = null;
596
597 if (serviceContext.isCommandUpdate()) {
598 localizedSubjectMap = BookmarksUtil.getEmailEntryUpdatedSubjectMap(
599 preferences);
600 localizedBodyMap = BookmarksUtil.getEmailEntryUpdatedBodyMap(
601 preferences);
602 }
603 else {
604 localizedSubjectMap = BookmarksUtil.getEmailEntryAddedSubjectMap(
605 preferences);
606 localizedBodyMap = BookmarksUtil.getEmailEntryAddedBodyMap(
607 preferences);
608 }
609
610 SubscriptionSender subscriptionSender = new SubscriptionSender();
611
612 subscriptionSender.setCompanyId(entry.getCompanyId());
613 subscriptionSender.setContextAttributes(
614 "[$BOOKMARKS_ENTRY_STATUS_BY_USER_NAME$]", statusByUserName,
615 "[$BOOKMARKS_ENTRY_URL$]", entryURL);
616 subscriptionSender.setContextUserPrefix("BOOKMARKS_ENTRY");
617 subscriptionSender.setFrom(fromAddress, fromName);
618 subscriptionSender.setHtmlFormat(true);
619 subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
620 subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
621 subscriptionSender.setMailId("bookmarks_entry", entry.getEntryId());
622 subscriptionSender.setPortletId(PortletKeys.BOOKMARKS);
623 subscriptionSender.setReplyToAddress(fromAddress);
624 subscriptionSender.setScopeGroupId(entry.getGroupId());
625 subscriptionSender.setServiceContext(serviceContext);
626 subscriptionSender.setUserId(entry.getUserId());
627
628 subscriptionSender.addPersistedSubscribers(
629 BookmarksEntry.class.getName(), entry.getEntryId());
630
631 BookmarksFolder folder = entry.getFolder();
632
633 if (folder.getFolderId() !=
634 BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
635
636 subscriptionSender.addPersistedSubscribers(
637 BookmarksFolder.class.getName(), folder.getFolderId());
638
639 for (BookmarksFolder ancestor : folder.getAncestors()) {
640 subscriptionSender.addPersistedSubscribers(
641 BookmarksFolder.class.getName(), ancestor.getFolderId());
642 }
643 }
644
645 subscriptionSender.addPersistedSubscribers(
646 BookmarksFolder.class.getName(), folder.getGroupId());
647
648 subscriptionSender.flushNotificationsAsync();
649 }
650
651 protected void validate(String url) throws PortalException {
652 if (!Validator.isUrl(url)) {
653 throw new EntryURLException();
654 }
655 }
656
657 private static Log _log = LogFactoryUtil.getLog(
658 BookmarksEntryLocalServiceImpl.class);
659
660 }