001
014
015 package com.liferay.portlet.journal.service.impl;
016
017 import com.liferay.portal.LocaleException;
018 import com.liferay.portal.NoSuchImageException;
019 import com.liferay.portal.kernel.dao.orm.QueryDefinition;
020 import com.liferay.portal.kernel.dao.orm.QueryUtil;
021 import com.liferay.portal.kernel.dao.orm.Session;
022 import com.liferay.portal.kernel.exception.PortalException;
023 import com.liferay.portal.kernel.exception.SystemException;
024 import com.liferay.portal.kernel.json.JSONFactoryUtil;
025 import com.liferay.portal.kernel.json.JSONObject;
026 import com.liferay.portal.kernel.language.LanguageUtil;
027 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
028 import com.liferay.portal.kernel.log.Log;
029 import com.liferay.portal.kernel.log.LogFactoryUtil;
030 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
031 import com.liferay.portal.kernel.search.Field;
032 import com.liferay.portal.kernel.search.Hits;
033 import com.liferay.portal.kernel.search.Indexable;
034 import com.liferay.portal.kernel.search.IndexableType;
035 import com.liferay.portal.kernel.search.Indexer;
036 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
037 import com.liferay.portal.kernel.search.QueryConfig;
038 import com.liferay.portal.kernel.search.SearchContext;
039 import com.liferay.portal.kernel.search.Sort;
040 import com.liferay.portal.kernel.systemevent.SystemEvent;
041 import com.liferay.portal.kernel.systemevent.SystemEventHierarchyEntryThreadLocal;
042 import com.liferay.portal.kernel.util.ArrayUtil;
043 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
044 import com.liferay.portal.kernel.util.CharPool;
045 import com.liferay.portal.kernel.util.Constants;
046 import com.liferay.portal.kernel.util.ContentTypes;
047 import com.liferay.portal.kernel.util.FileUtil;
048 import com.liferay.portal.kernel.util.GetterUtil;
049 import com.liferay.portal.kernel.util.HtmlUtil;
050 import com.liferay.portal.kernel.util.HttpUtil;
051 import com.liferay.portal.kernel.util.ListUtil;
052 import com.liferay.portal.kernel.util.LocaleUtil;
053 import com.liferay.portal.kernel.util.LocalizationUtil;
054 import com.liferay.portal.kernel.util.MathUtil;
055 import com.liferay.portal.kernel.util.ObjectValuePair;
056 import com.liferay.portal.kernel.util.OrderByComparator;
057 import com.liferay.portal.kernel.util.ParamUtil;
058 import com.liferay.portal.kernel.util.PropsKeys;
059 import com.liferay.portal.kernel.util.StringPool;
060 import com.liferay.portal.kernel.util.StringUtil;
061 import com.liferay.portal.kernel.util.Time;
062 import com.liferay.portal.kernel.util.TreePathUtil;
063 import com.liferay.portal.kernel.util.UnicodeProperties;
064 import com.liferay.portal.kernel.util.Validator;
065 import com.liferay.portal.kernel.workflow.WorkflowConstants;
066 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
067 import com.liferay.portal.kernel.xml.Document;
068 import com.liferay.portal.kernel.xml.DocumentException;
069 import com.liferay.portal.kernel.xml.Element;
070 import com.liferay.portal.kernel.xml.Node;
071 import com.liferay.portal.kernel.xml.SAXReaderUtil;
072 import com.liferay.portal.kernel.xml.XPath;
073 import com.liferay.portal.model.Company;
074 import com.liferay.portal.model.Group;
075 import com.liferay.portal.model.Image;
076 import com.liferay.portal.model.ResourceConstants;
077 import com.liferay.portal.model.SystemEventConstants;
078 import com.liferay.portal.model.User;
079 import com.liferay.portal.service.ServiceContext;
080 import com.liferay.portal.service.ServiceContextUtil;
081 import com.liferay.portal.servlet.filters.cache.CacheUtil;
082 import com.liferay.portal.theme.ThemeDisplay;
083 import com.liferay.portal.util.PortalUtil;
084 import com.liferay.portal.util.PortletKeys;
085 import com.liferay.portal.util.PrefsPropsUtil;
086 import com.liferay.portal.util.PropsValues;
087 import com.liferay.portal.util.SubscriptionSender;
088 import com.liferay.portal.webserver.WebServerServletTokenUtil;
089 import com.liferay.portlet.asset.model.AssetEntry;
090 import com.liferay.portlet.asset.model.AssetLink;
091 import com.liferay.portlet.asset.model.AssetLinkConstants;
092 import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
093 import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
094 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
095 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
096 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
097 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
098 import com.liferay.portlet.journal.ArticleContentException;
099 import com.liferay.portlet.journal.ArticleDisplayDateException;
100 import com.liferay.portlet.journal.ArticleExpirationDateException;
101 import com.liferay.portlet.journal.ArticleIdException;
102 import com.liferay.portlet.journal.ArticleReviewDateException;
103 import com.liferay.portlet.journal.ArticleSmallImageNameException;
104 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
105 import com.liferay.portlet.journal.ArticleTitleException;
106 import com.liferay.portlet.journal.ArticleTypeException;
107 import com.liferay.portlet.journal.ArticleVersionException;
108 import com.liferay.portlet.journal.DuplicateArticleIdException;
109 import com.liferay.portlet.journal.NoSuchArticleException;
110 import com.liferay.portlet.journal.StructureXsdException;
111 import com.liferay.portlet.journal.model.JournalArticle;
112 import com.liferay.portlet.journal.model.JournalArticleConstants;
113 import com.liferay.portlet.journal.model.JournalArticleDisplay;
114 import com.liferay.portlet.journal.model.JournalArticleResource;
115 import com.liferay.portlet.journal.model.JournalFolder;
116 import com.liferay.portlet.journal.model.impl.JournalArticleDisplayImpl;
117 import com.liferay.portlet.journal.model.impl.JournalArticleModelImpl;
118 import com.liferay.portlet.journal.model.impl.JournalFolderModelImpl;
119 import com.liferay.portlet.journal.service.base.JournalArticleLocalServiceBaseImpl;
120 import com.liferay.portlet.journal.social.JournalActivityKeys;
121 import com.liferay.portlet.journal.util.JournalUtil;
122 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
123 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
124 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
125 import com.liferay.portlet.social.model.SocialActivityConstants;
126 import com.liferay.portlet.trash.model.TrashEntry;
127 import com.liferay.portlet.trash.model.TrashVersion;
128 import com.liferay.portlet.trash.util.TrashUtil;
129
130 import java.io.File;
131 import java.io.IOException;
132 import java.io.Serializable;
133
134 import java.util.ArrayList;
135 import java.util.Calendar;
136 import java.util.Date;
137 import java.util.HashMap;
138 import java.util.HashSet;
139 import java.util.LinkedHashMap;
140 import java.util.List;
141 import java.util.Locale;
142 import java.util.Map;
143 import java.util.Set;
144
145 import javax.portlet.PortletPreferences;
146
147
176 public class JournalArticleLocalServiceImpl
177 extends JournalArticleLocalServiceBaseImpl {
178
179
262 @Indexable(type = IndexableType.REINDEX)
263 @Override
264 public JournalArticle addArticle(
265 long userId, long groupId, long folderId, long classNameId,
266 long classPK, String articleId, boolean autoArticleId,
267 double version, Map<Locale, String> titleMap,
268 Map<Locale, String> descriptionMap, String content, String type,
269 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
270 int displayDateMonth, int displayDateDay, int displayDateYear,
271 int displayDateHour, int displayDateMinute, int expirationDateMonth,
272 int expirationDateDay, int expirationDateYear,
273 int expirationDateHour, int expirationDateMinute,
274 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
275 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
276 boolean neverReview, boolean indexable, boolean smallImage,
277 String smallImageURL, File smallImageFile,
278 Map<String, byte[]> images, String articleURL,
279 ServiceContext serviceContext)
280 throws PortalException, SystemException {
281
282
283
284 User user = userPersistence.findByPrimaryKey(userId);
285 articleId = StringUtil.toUpperCase(articleId.trim());
286
287 Date displayDate = null;
288 Date expirationDate = null;
289 Date reviewDate = null;
290
291 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
292 displayDate = PortalUtil.getDate(
293 displayDateMonth, displayDateDay, displayDateYear,
294 displayDateHour, displayDateMinute, user.getTimeZone(),
295 ArticleDisplayDateException.class);
296
297 if (!neverExpire) {
298 expirationDate = PortalUtil.getDate(
299 expirationDateMonth, expirationDateDay, expirationDateYear,
300 expirationDateHour, expirationDateMinute,
301 user.getTimeZone(), ArticleExpirationDateException.class);
302 }
303
304 if (!neverReview) {
305 reviewDate = PortalUtil.getDate(
306 reviewDateMonth, reviewDateDay, reviewDateYear,
307 reviewDateHour, reviewDateMinute, user.getTimeZone(),
308 ArticleReviewDateException.class);
309 }
310 }
311
312 byte[] smallImageBytes = null;
313
314 try {
315 smallImageBytes = FileUtil.getBytes(smallImageFile);
316 }
317 catch (IOException ioe) {
318 }
319
320 Date now = new Date();
321
322 validate(
323 user.getCompanyId(), groupId, classNameId, articleId, autoArticleId,
324 version, titleMap, content, type, ddmStructureKey, ddmTemplateKey,
325 expirationDate, smallImage, smallImageURL, smallImageFile,
326 smallImageBytes);
327
328 if (autoArticleId) {
329 articleId = String.valueOf(counterLocalService.increment());
330 }
331
332 long id = counterLocalService.increment();
333
334 long resourcePrimKey =
335 journalArticleResourceLocalService.getArticleResourcePrimKey(
336 serviceContext.getUuid(), groupId, articleId);
337
338 JournalArticle article = journalArticlePersistence.create(id);
339
340 Locale locale = LocaleUtil.getSiteDefault();
341
342 String defaultLanguageId = ParamUtil.getString(
343 serviceContext, "defaultLanguageId");
344
345 if (Validator.isNull(defaultLanguageId)) {
346 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
347 }
348
349 if (Validator.isNotNull(defaultLanguageId)) {
350 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
351 }
352
353 String title = titleMap.get(locale);
354
355 content = format(
356 user, groupId, articleId, version, false, content, ddmStructureKey,
357 images);
358
359 article.setResourcePrimKey(resourcePrimKey);
360 article.setGroupId(groupId);
361 article.setCompanyId(user.getCompanyId());
362 article.setUserId(user.getUserId());
363 article.setUserName(user.getFullName());
364 article.setCreateDate(serviceContext.getCreateDate(now));
365 article.setModifiedDate(serviceContext.getModifiedDate(now));
366 article.setFolderId(folderId);
367 article.setClassNameId(classNameId);
368 article.setClassPK(classPK);
369 article.setTreePath(article.buildTreePath());
370 article.setArticleId(articleId);
371 article.setVersion(version);
372 article.setTitleMap(titleMap, locale);
373 article.setUrlTitle(
374 getUniqueUrlTitle(id, articleId, title, null, serviceContext));
375 article.setDescriptionMap(descriptionMap, locale);
376 article.setContent(content);
377 article.setType(type);
378 article.setStructureId(ddmStructureKey);
379 article.setTemplateId(ddmTemplateKey);
380 article.setLayoutUuid(layoutUuid);
381 article.setDisplayDate(displayDate);
382 article.setExpirationDate(expirationDate);
383 article.setReviewDate(reviewDate);
384 article.setIndexable(indexable);
385 article.setSmallImage(smallImage);
386 article.setSmallImageId(counterLocalService.increment());
387 article.setSmallImageURL(smallImageURL);
388
389 if ((expirationDate == null) || expirationDate.after(now)) {
390 article.setStatus(WorkflowConstants.STATUS_DRAFT);
391 }
392 else {
393 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
394 }
395
396 article.setStatusByUserId(userId);
397 article.setStatusDate(serviceContext.getModifiedDate(now));
398 article.setExpandoBridgeAttributes(serviceContext);
399
400 journalArticlePersistence.update(article);
401
402
403
404 if (serviceContext.isAddGroupPermissions() ||
405 serviceContext.isAddGuestPermissions()) {
406
407 addArticleResources(
408 article, serviceContext.isAddGroupPermissions(),
409 serviceContext.isAddGuestPermissions());
410 }
411 else {
412 addArticleResources(
413 article, serviceContext.getGroupPermissions(),
414 serviceContext.getGuestPermissions());
415 }
416
417
418
419 saveImages(
420 smallImage, article.getSmallImageId(), smallImageFile,
421 smallImageBytes);
422
423
424
425 updateAsset(
426 userId, article, serviceContext.getAssetCategoryIds(),
427 serviceContext.getAssetTagNames(),
428 serviceContext.getAssetLinkEntryIds());
429
430
431
432 if (PortalUtil.getClassNameId(DDMStructure.class) == classNameId) {
433 updateDDMStructureXSD(classPK, content, serviceContext);
434 }
435
436
437
438 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
439 mbMessageLocalService.addDiscussionMessage(
440 userId, article.getUserName(), groupId,
441 JournalArticle.class.getName(), resourcePrimKey,
442 WorkflowConstants.ACTION_PUBLISH);
443 }
444
445
446
447 PortletPreferences preferences =
448 ServiceContextUtil.getPortletPreferences(serviceContext);
449
450 sendEmail(
451 article, articleURL, preferences, "requested", serviceContext);
452
453
454
455 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
456 WorkflowHandlerRegistryUtil.startWorkflowInstance(
457 user.getCompanyId(), groupId, userId,
458 JournalArticle.class.getName(), article.getId(), article,
459 serviceContext);
460 }
461 else {
462 updateStatus(
463 userId, article, WorkflowConstants.STATUS_APPROVED, null,
464 new HashMap<String, Serializable>(), serviceContext);
465 }
466
467 return journalArticlePersistence.findByPrimaryKey(article.getId());
468 }
469
470
499 @Override
500 public JournalArticle addArticle(
501 long userId, long groupId, long folderId,
502 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
503 String content, String ddmStructureKey, String ddmTemplateKey,
504 ServiceContext serviceContext)
505 throws PortalException, SystemException {
506
507 Calendar calendar = CalendarFactoryUtil.getCalendar();
508
509 int displayDateMonth = calendar.get(Calendar.MONTH);
510 int displayDateDay = calendar.get(Calendar.DAY_OF_MONTH);
511 int displayDateYear = calendar.get(Calendar.YEAR);
512 int displayDateHour = calendar.get(Calendar.HOUR_OF_DAY);
513 int displayDateMinute = calendar.get(Calendar.MINUTE);
514
515 return journalArticleLocalService.addArticle(
516 userId, groupId, folderId,
517 JournalArticleConstants.CLASSNAME_ID_DEFAULT, 0, StringPool.BLANK,
518 true, 1, titleMap, descriptionMap, content, "general",
519 ddmStructureKey, ddmTemplateKey, null, displayDateMonth,
520 displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
521 0, 0, 0, 0, 0, true, 0, 0, 0, 0, 0, true, true, false, null, null,
522 null, null, serviceContext);
523 }
524
525
535 @Override
536 public void addArticleResources(
537 JournalArticle article, boolean addGroupPermissions,
538 boolean addGuestPermissions)
539 throws PortalException, SystemException {
540
541 resourceLocalService.addResources(
542 article.getCompanyId(), article.getGroupId(), article.getUserId(),
543 JournalArticle.class.getName(), article.getResourcePrimKey(), false,
544 addGroupPermissions, addGuestPermissions);
545 }
546
547
556 @Override
557 public void addArticleResources(
558 JournalArticle article, String[] groupPermissions,
559 String[] guestPermissions)
560 throws PortalException, SystemException {
561
562 resourceLocalService.addModelResources(
563 article.getCompanyId(), article.getGroupId(), article.getUserId(),
564 JournalArticle.class.getName(), article.getResourcePrimKey(),
565 groupPermissions, guestPermissions);
566 }
567
568
578 @Override
579 public void addArticleResources(
580 long groupId, String articleId, boolean addGroupPermissions,
581 boolean addGuestPermissions)
582 throws PortalException, SystemException {
583
584 JournalArticle article = getLatestArticle(groupId, articleId);
585
586 addArticleResources(article, addGroupPermissions, addGuestPermissions);
587 }
588
589
600 @Override
601 public void addArticleResources(
602 long groupId, String articleId, String[] groupPermissions,
603 String[] guestPermissions)
604 throws PortalException, SystemException {
605
606 JournalArticle article = getLatestArticle(groupId, articleId);
607
608 addArticleResources(article, groupPermissions, guestPermissions);
609 }
610
611
624 @Override
625 public JournalArticle checkArticleResourcePrimKey(
626 long groupId, String articleId, double version)
627 throws PortalException, SystemException {
628
629 JournalArticle article = journalArticlePersistence.findByG_A_V(
630 groupId, articleId, version);
631
632 if (article.getResourcePrimKey() > 0) {
633 return article;
634 }
635
636 long resourcePrimKey =
637 journalArticleResourceLocalService.getArticleResourcePrimKey(
638 groupId, articleId);
639
640 article.setResourcePrimKey(resourcePrimKey);
641
642 journalArticlePersistence.update(article);
643
644 return article;
645 }
646
647
654 @Override
655 public void checkArticles() throws PortalException, SystemException {
656 Date now = new Date();
657
658 checkArticlesByExpirationDate(now);
659
660 checkArticlesByReviewDate(now);
661
662 checkArticlesByDisplayDate(now);
663
664 _previousCheckDate = now;
665 }
666
667
679 @Override
680 public void checkNewLine(long groupId, String articleId, double version)
681 throws PortalException, SystemException {
682
683 JournalArticle article = journalArticlePersistence.findByG_A_V(
684 groupId, articleId, version);
685
686 String content = GetterUtil.getString(article.getContent());
687
688 if (content.contains("\\n")) {
689 content = StringUtil.replace(
690 content, new String[] {"\\n", "\\r"},
691 new String[] {"\n", "\r"});
692
693 article.setContent(content);
694
695 journalArticlePersistence.update(article);
696 }
697 }
698
699
712 @Override
713 public void checkStructure(long groupId, String articleId, double version)
714 throws PortalException, SystemException {
715
716 JournalArticle article = journalArticlePersistence.findByG_A_V(
717 groupId, articleId, version);
718
719 if (Validator.isNull(article.getStructureId())) {
720 return;
721 }
722
723 checkStructure(article);
724 }
725
726
742 @Indexable(type = IndexableType.REINDEX)
743 @Override
744 public JournalArticle copyArticle(
745 long userId, long groupId, String oldArticleId, String newArticleId,
746 boolean autoArticleId, double version)
747 throws PortalException, SystemException {
748
749
750
751 User user = userPersistence.findByPrimaryKey(userId);
752 oldArticleId = StringUtil.toUpperCase(oldArticleId.trim());
753 newArticleId = StringUtil.toUpperCase(newArticleId.trim());
754 Date now = new Date();
755
756 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
757 groupId, oldArticleId, version);
758
759 if (autoArticleId) {
760 newArticleId = String.valueOf(counterLocalService.increment());
761 }
762 else {
763 validate(newArticleId);
764
765 if (journalArticlePersistence.countByG_A(
766 groupId, newArticleId) > 0) {
767
768 throw new DuplicateArticleIdException();
769 }
770 }
771
772 long id = counterLocalService.increment();
773
774 long resourcePrimKey =
775 journalArticleResourceLocalService.getArticleResourcePrimKey(
776 groupId, newArticleId);
777
778 JournalArticle newArticle = journalArticlePersistence.create(id);
779
780 newArticle.setResourcePrimKey(resourcePrimKey);
781 newArticle.setGroupId(groupId);
782 newArticle.setCompanyId(user.getCompanyId());
783 newArticle.setUserId(user.getUserId());
784 newArticle.setUserName(user.getFullName());
785 newArticle.setCreateDate(now);
786 newArticle.setModifiedDate(now);
787 newArticle.setFolderId(oldArticle.getFolderId());
788 newArticle.setTreePath(oldArticle.getTreePath());
789 newArticle.setArticleId(newArticleId);
790 newArticle.setVersion(JournalArticleConstants.VERSION_DEFAULT);
791 newArticle.setTitle(oldArticle.getTitle());
792 newArticle.setUrlTitle(
793 getUniqueUrlTitle(
794 id, groupId, newArticleId, oldArticle.getTitleCurrentValue()));
795 newArticle.setDescription(oldArticle.getDescription());
796
797 try {
798 copyArticleImages(oldArticle, newArticle);
799 }
800 catch (Exception e) {
801 newArticle.setContent(oldArticle.getContent());
802 }
803
804 newArticle.setType(oldArticle.getType());
805 newArticle.setStructureId(oldArticle.getStructureId());
806 newArticle.setTemplateId(oldArticle.getTemplateId());
807 newArticle.setLayoutUuid(oldArticle.getLayoutUuid());
808 newArticle.setDisplayDate(oldArticle.getDisplayDate());
809 newArticle.setExpirationDate(oldArticle.getExpirationDate());
810 newArticle.setReviewDate(oldArticle.getReviewDate());
811 newArticle.setIndexable(oldArticle.isIndexable());
812 newArticle.setSmallImage(oldArticle.isSmallImage());
813 newArticle.setSmallImageId(counterLocalService.increment());
814 newArticle.setSmallImageURL(oldArticle.getSmallImageURL());
815
816 if (oldArticle.isPending() ||
817 workflowDefinitionLinkLocalService.hasWorkflowDefinitionLink(
818 user.getCompanyId(), groupId, JournalArticle.class.getName())) {
819
820 newArticle.setStatus(WorkflowConstants.STATUS_DRAFT);
821 }
822 else {
823 newArticle.setStatus(oldArticle.getStatus());
824 }
825
826 newArticle.setExpandoBridgeAttributes(oldArticle);
827
828 journalArticlePersistence.update(newArticle);
829
830
831
832 addArticleResources(newArticle, true, true);
833
834
835
836 if (oldArticle.getSmallImage()) {
837 Image image = imageLocalService.getImage(
838 oldArticle.getSmallImageId());
839
840 byte[] smallImageBytes = image.getTextObj();
841
842 imageLocalService.updateImage(
843 newArticle.getSmallImageId(), smallImageBytes);
844 }
845
846
847
848 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
849 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
850 String[] assetTagNames = assetTagLocalService.getTagNames(
851 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
852
853 updateAsset(userId, newArticle, assetCategoryIds, assetTagNames, null);
854
855 return newArticle;
856 }
857
858
865 @Override
866 @SystemEvent(
867 action = SystemEventConstants.ACTION_SKIP, send = false)
868 public JournalArticle deleteArticle(JournalArticle article)
869 throws PortalException, SystemException {
870
871 return journalArticleLocalService.deleteArticle(
872 article, StringPool.BLANK, null);
873 }
874
875
889 @Indexable(type = IndexableType.DELETE)
890 @Override
891 @SystemEvent(
892 action = SystemEventConstants.ACTION_SKIP, send = false)
893 public JournalArticle deleteArticle(
894 JournalArticle article, String articleURL,
895 ServiceContext serviceContext)
896 throws PortalException, SystemException {
897
898 JournalArticleResource articleResource =
899 journalArticleResourceLocalService.fetchArticleResource(
900 article.getGroupId(), article.getArticleId());
901
902 if (article.isApproved() &&
903 isLatestVersion(
904 article.getGroupId(), article.getArticleId(),
905 article.getVersion(), WorkflowConstants.STATUS_APPROVED)) {
906
907 updatePreviousApprovedArticle(article);
908 }
909
910
911
912 if ((serviceContext != null) && Validator.isNotNull(articleURL)) {
913 PortletPreferences preferences =
914 ServiceContextUtil.getPortletPreferences(serviceContext);
915
916 if ((preferences != null) && !article.isApproved() &&
917 isLatestVersion(
918 article.getGroupId(), article.getArticleId(),
919 article.getVersion())) {
920
921 sendEmail(
922 article, articleURL, preferences, "denied", serviceContext);
923 }
924 }
925
926
927
928 journalArticleImageLocalService.deleteImages(
929 article.getGroupId(), article.getArticleId(), article.getVersion());
930
931
932
933 expandoRowLocalService.deleteRows(article.getId());
934
935
936
937 if (article.isInTrash()) {
938 TrashEntry trashEntry = article.getTrashEntry();
939
940 if (trashEntry != null) {
941 trashVersionLocalService.deleteTrashVersion(
942 trashEntry.getEntryId(), JournalArticle.class.getName(),
943 article.getId());
944 }
945 }
946
947
948
949 if (!article.isDraft()) {
950 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
951 article.getCompanyId(), article.getGroupId(),
952 JournalArticle.class.getName(), article.getId());
953 }
954
955 int articlesCount = journalArticlePersistence.countByG_A(
956 article.getGroupId(), article.getArticleId());
957
958 if (articlesCount == 1) {
959
960
961
962 subscriptionLocalService.deleteSubscriptions(
963 article.getCompanyId(), JournalArticle.class.getName(),
964 article.getResourcePrimKey());
965
966
967
968 ratingsStatsLocalService.deleteStats(
969 JournalArticle.class.getName(), article.getResourcePrimKey());
970
971
972
973 mbMessageLocalService.deleteDiscussionMessages(
974 JournalArticle.class.getName(), article.getResourcePrimKey());
975
976
977
978 assetEntryLocalService.deleteEntry(
979 JournalArticle.class.getName(), article.getResourcePrimKey());
980
981
982
983 journalContentSearchLocalService.deleteArticleContentSearches(
984 article.getGroupId(), article.getArticleId());
985
986
987
988 imageLocalService.deleteImage(article.getSmallImageId());
989
990
991
992 trashEntryLocalService.deleteEntry(
993 JournalArticle.class.getName(), article.getResourcePrimKey());
994
995
996
997 resourceLocalService.deleteResource(
998 article.getCompanyId(), JournalArticle.class.getName(),
999 ResourceConstants.SCOPE_INDIVIDUAL,
1000 article.getResourcePrimKey());
1001
1002
1003
1004 if (articleResource != null) {
1005 journalArticleResourceLocalService.deleteJournalArticleResource(
1006 articleResource);
1007 }
1008 }
1009
1010
1011
1012 journalArticlePersistence.remove(article);
1013
1014
1015
1016 if (articleResource != null) {
1017 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1018
1019 extraDataJSONObject.put("version", article.getVersion());
1020
1021 systemEventLocalService.addSystemEvent(
1022 0, article.getGroupId(), article.getModelClassName(),
1023 article.getPrimaryKey(), articleResource.getUuid(), null,
1024 SystemEventConstants.TYPE_DELETE,
1025 extraDataJSONObject.toString());
1026 }
1027
1028 return article;
1029 }
1030
1031
1047 @Override
1048 public JournalArticle deleteArticle(
1049 long groupId, String articleId, double version, String articleURL,
1050 ServiceContext serviceContext)
1051 throws PortalException, SystemException {
1052
1053 JournalArticle article = journalArticlePersistence.findByG_A_V(
1054 groupId, articleId, version);
1055
1056 return journalArticleLocalService.deleteArticle(
1057 article, articleURL, serviceContext);
1058 }
1059
1060
1073 @Override
1074 public void deleteArticle(
1075 long groupId, String articleId, ServiceContext serviceContext)
1076 throws PortalException, SystemException {
1077
1078 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1079
1080 JournalArticleResource articleResource =
1081 journalArticleResourceLocalService.fetchArticleResource(
1082 groupId, articleId);
1083
1084 try {
1085 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1086 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1087 new ArticleVersionComparator(true));
1088
1089 for (JournalArticle article : articles) {
1090 journalArticleLocalService.deleteArticle(
1091 article, null, serviceContext);
1092 }
1093 }
1094 finally {
1095 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1096 }
1097
1098 if (articleResource != null) {
1099 systemEventLocalService.addSystemEvent(
1100 0, groupId, JournalArticle.class.getName(),
1101 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1102 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1103 }
1104 }
1105
1106
1113 @Override
1114 public void deleteArticles(long groupId)
1115 throws PortalException, SystemException {
1116
1117 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1118
1119 List<JournalArticleResource> articleResources =
1120 new ArrayList<JournalArticleResource>();
1121
1122 try {
1123 JournalArticleResource articleResource = null;
1124
1125 for (JournalArticle article :
1126 journalArticlePersistence.findByGroupId(groupId)) {
1127
1128 if ((articleResource == null) ||
1129 (articleResource.getPrimaryKey() !=
1130 article.getResourcePrimKey())) {
1131
1132 articleResource =
1133 journalArticleResourceLocalService.getArticleResource(
1134 article.getResourcePrimKey());
1135
1136 articleResources.add(articleResource);
1137 }
1138
1139 journalArticleLocalService.deleteArticle(article, null, null);
1140 }
1141 }
1142 finally {
1143 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1144 }
1145
1146 for (JournalArticleResource articleResource : articleResources) {
1147 systemEventLocalService.addSystemEvent(
1148 0, groupId, JournalArticle.class.getName(),
1149 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1150 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1151 }
1152 }
1153
1154
1163 @Override
1164 public void deleteArticles(long groupId, long folderId)
1165 throws PortalException, SystemException {
1166
1167 deleteArticles(groupId, folderId, true);
1168 }
1169
1170
1181 @Override
1182 public void deleteArticles(
1183 long groupId, long folderId, boolean includeTrashedEntries)
1184 throws PortalException, SystemException {
1185
1186 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1187
1188 List<JournalArticleResource> articleResources =
1189 new ArrayList<JournalArticleResource>();
1190
1191 try {
1192 JournalArticleResource articleResource = null;
1193
1194 for (JournalArticle article :
1195 journalArticlePersistence.findByG_F(groupId, folderId)) {
1196
1197 if ((articleResource == null) ||
1198 (articleResource.getPrimaryKey() !=
1199 article.getResourcePrimKey())) {
1200
1201 articleResource =
1202 journalArticleResourceLocalService.getArticleResource(
1203 article.getResourcePrimKey());
1204
1205 articleResources.add(articleResource);
1206 }
1207
1208 if (includeTrashedEntries || !article.isInTrash()) {
1209 journalArticleLocalService.deleteArticle(
1210 article, null, null);
1211 }
1212 else {
1213 articleResources.remove(articleResource);
1214 }
1215 }
1216 }
1217 finally {
1218 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1219 }
1220
1221 for (JournalArticleResource articleResource : articleResources) {
1222 systemEventLocalService.addSystemEvent(
1223 0, groupId, JournalArticle.class.getName(),
1224 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1225 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1226 }
1227 }
1228
1229
1238 @Override
1239 public void deleteLayoutArticleReferences(long groupId, String layoutUuid)
1240 throws SystemException {
1241
1242 List<JournalArticle> articles = journalArticlePersistence.findByG_L(
1243 groupId, layoutUuid);
1244
1245 for (JournalArticle article : articles) {
1246 article.setLayoutUuid(StringPool.BLANK);
1247
1248 journalArticlePersistence.update(article);
1249 }
1250 }
1251
1252
1275 @Indexable(type = IndexableType.REINDEX)
1276 @Override
1277 public JournalArticle expireArticle(
1278 long userId, long groupId, String articleId, double version,
1279 String articleURL, ServiceContext serviceContext)
1280 throws PortalException, SystemException {
1281
1282 return updateStatus(
1283 userId, groupId, articleId, version,
1284 WorkflowConstants.STATUS_EXPIRED, articleURL,
1285 new HashMap<String, Serializable>(), serviceContext);
1286 }
1287
1288
1311 @Override
1312 public void expireArticle(
1313 long userId, long groupId, String articleId, String articleURL,
1314 ServiceContext serviceContext)
1315 throws PortalException, SystemException {
1316
1317 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
1318 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1319 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1320 new ArticleVersionComparator(true));
1321
1322 for (JournalArticle article : articles) {
1323 journalArticleLocalService.expireArticle(
1324 userId, groupId, article.getArticleId(),
1325 article.getVersion(), articleURL, serviceContext);
1326 }
1327 }
1328 else {
1329 JournalArticle article = getLatestArticle(
1330 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1331
1332 journalArticleLocalService.expireArticle(
1333 userId, groupId, article.getArticleId(), article.getVersion(),
1334 articleURL, serviceContext);
1335 }
1336 }
1337
1338 @Override
1339 public JournalArticle fetchArticle(
1340 long groupId, String articleId, double version)
1341 throws SystemException {
1342
1343 return journalArticlePersistence.fetchByG_A_V(
1344 groupId, articleId, version);
1345 }
1346
1347 @Override
1348 public JournalArticle fetchLatestArticle(
1349 long resourcePrimKey, int status, boolean preferApproved)
1350 throws SystemException {
1351
1352 JournalArticle article = null;
1353
1354 OrderByComparator orderByComparator = new ArticleVersionComparator();
1355
1356 if (status == WorkflowConstants.STATUS_ANY) {
1357 if (preferApproved) {
1358 article = journalArticlePersistence.fetchByR_ST_First(
1359 resourcePrimKey, WorkflowConstants.STATUS_APPROVED,
1360 orderByComparator);
1361 }
1362
1363 if (article == null) {
1364 article =
1365 journalArticlePersistence.fetchByResourcePrimKey_First(
1366 resourcePrimKey, orderByComparator);
1367 }
1368 }
1369 else {
1370 article = journalArticlePersistence.fetchByR_ST_First(
1371 resourcePrimKey, status, orderByComparator);
1372 }
1373
1374 return article;
1375 }
1376
1377 @Override
1378 public JournalArticle fetchLatestArticle(
1379 long groupId, String articleId, int status)
1380 throws SystemException {
1381
1382 OrderByComparator orderByComparator = new ArticleVersionComparator();
1383
1384 if (status == WorkflowConstants.STATUS_ANY) {
1385 return journalArticlePersistence.fetchByG_A_NotST_First(
1386 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH,
1387 orderByComparator);
1388 }
1389
1390 return journalArticlePersistence.fetchByG_A_ST_First(
1391 groupId, articleId, status, orderByComparator);
1392 }
1393
1394 @Override
1395 public JournalArticle fetchLatestIndexableArticle(long resourcePrimKey)
1396 throws SystemException {
1397
1398 OrderByComparator orderByComparator = new ArticleVersionComparator();
1399
1400 int[] statuses = new int[] {
1401 WorkflowConstants.STATUS_APPROVED, WorkflowConstants.STATUS_IN_TRASH
1402 };
1403
1404 List<JournalArticle> articles =
1405 journalArticlePersistence.findByR_I_S(
1406 resourcePrimKey, true, statuses, 0, 1, orderByComparator);
1407
1408 if (articles.isEmpty()) {
1409 return null;
1410 }
1411
1412 return articles.get(0);
1413 }
1414
1415
1424 @Override
1425 public JournalArticle getArticle(long id)
1426 throws PortalException, SystemException {
1427
1428 return journalArticlePersistence.findByPrimaryKey(id);
1429 }
1430
1431
1443 @Override
1444 public JournalArticle getArticle(long groupId, String articleId)
1445 throws PortalException, SystemException {
1446
1447
1448
1449
1450 try {
1451 return getLatestArticle(
1452 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1453 }
1454 catch (NoSuchArticleException nsae) {
1455 return getLatestArticle(
1456 groupId, articleId, WorkflowConstants.STATUS_ANY);
1457 }
1458 }
1459
1460
1472 @Override
1473 public JournalArticle getArticle(
1474 long groupId, String articleId, double version)
1475 throws PortalException, SystemException {
1476
1477 return journalArticlePersistence.findByG_A_V(
1478 groupId, articleId, version);
1479 }
1480
1481
1499 @Override
1500 public JournalArticle getArticle(
1501 long groupId, String className, long classPK)
1502 throws PortalException, SystemException {
1503
1504 long classNameId = PortalUtil.getClassNameId(className);
1505
1506 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1507 groupId, classNameId, classPK);
1508
1509 if (articles.isEmpty()) {
1510 throw new NoSuchArticleException(
1511 "No approved JournalArticle exists with the key {groupId=" +
1512 groupId + ", className=" + className + ", classPK=" +
1513 classPK + "}");
1514 }
1515
1516 return articles.get(0);
1517 }
1518
1519
1530 @Override
1531 public JournalArticle getArticleByUrlTitle(long groupId, String urlTitle)
1532 throws PortalException, SystemException {
1533
1534
1535
1536
1537 try {
1538 return getLatestArticleByUrlTitle(
1539 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
1540 }
1541 catch (NoSuchArticleException nsae) {
1542 return getLatestArticleByUrlTitle(
1543 groupId, urlTitle, WorkflowConstants.STATUS_PENDING);
1544 }
1545 }
1546
1547
1564 @Override
1565 public String getArticleContent(
1566 JournalArticle article, String ddmTemplateKey, String viewMode,
1567 String languageId, ThemeDisplay themeDisplay)
1568 throws PortalException, SystemException {
1569
1570 JournalArticleDisplay articleDisplay = getArticleDisplay(
1571 article, ddmTemplateKey, viewMode, languageId, 1, null,
1572 themeDisplay);
1573
1574 if (articleDisplay == null) {
1575 return StringPool.BLANK;
1576 }
1577 else {
1578 return articleDisplay.getContent();
1579 }
1580 }
1581
1582
1601 @Override
1602 public String getArticleContent(
1603 long groupId, String articleId, double version, String viewMode,
1604 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1605 throws PortalException, SystemException {
1606
1607 JournalArticleDisplay articleDisplay = getArticleDisplay(
1608 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
1609 themeDisplay);
1610
1611 if (articleDisplay == null) {
1612 return StringPool.BLANK;
1613 }
1614 else {
1615 return articleDisplay.getContent();
1616 }
1617 }
1618
1619
1633 @Override
1634 public String getArticleContent(
1635 long groupId, String articleId, double version, String viewMode,
1636 String languageId, ThemeDisplay themeDisplay)
1637 throws PortalException, SystemException {
1638
1639 return getArticleContent(
1640 groupId, articleId, version, viewMode, null, languageId,
1641 themeDisplay);
1642 }
1643
1644
1662 @Override
1663 public String getArticleContent(
1664 long groupId, String articleId, String viewMode,
1665 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1666 throws PortalException, SystemException {
1667
1668 JournalArticleDisplay articleDisplay = getArticleDisplay(
1669 groupId, articleId, ddmTemplateKey, viewMode, languageId,
1670 themeDisplay);
1671
1672 return articleDisplay.getContent();
1673 }
1674
1675
1688 @Override
1689 public String getArticleContent(
1690 long groupId, String articleId, String viewMode, String languageId,
1691 ThemeDisplay themeDisplay)
1692 throws PortalException, SystemException {
1693
1694 return getArticleContent(
1695 groupId, articleId, viewMode, null, languageId, themeDisplay);
1696 }
1697
1698
1722 @Override
1723 public JournalArticleDisplay getArticleDisplay(
1724 JournalArticle article, String ddmTemplateKey, String viewMode,
1725 String languageId, int page, String xmlRequest,
1726 ThemeDisplay themeDisplay)
1727 throws PortalException, SystemException {
1728
1729 String content = null;
1730
1731 if (page < 1) {
1732 page = 1;
1733 }
1734
1735 int numberOfPages = 1;
1736 boolean paginate = false;
1737 boolean pageFlow = false;
1738
1739 boolean cacheable = true;
1740
1741 if (Validator.isNull(xmlRequest)) {
1742 xmlRequest = "<request />";
1743 }
1744
1745 Map<String, String> tokens = JournalUtil.getTokens(
1746 article.getGroupId(), themeDisplay, xmlRequest);
1747
1748 if ((themeDisplay == null) && xmlRequest.equals("<request />")) {
1749 tokens.put("company_id", String.valueOf(article.getCompanyId()));
1750
1751 Group companyGroup = groupLocalService.getCompanyGroup(
1752 article.getCompanyId());
1753
1754 tokens.put(
1755 "article_group_id", String.valueOf(article.getGroupId()));
1756 tokens.put(
1757 "company_group_id", String.valueOf(companyGroup.getGroupId()));
1758
1759
1760
1761 tokens.put("group_id", String.valueOf(article.getGroupId()));
1762 }
1763
1764 tokens.put(
1765 "article_resource_pk",
1766 String.valueOf(article.getResourcePrimKey()));
1767
1768 String defaultDDMTemplateKey = article.getTemplateId();
1769
1770 if (article.isTemplateDriven()) {
1771 if (Validator.isNull(ddmTemplateKey)) {
1772 ddmTemplateKey = defaultDDMTemplateKey;
1773 }
1774
1775 tokens.put("structure_id", article.getStructureId());
1776 tokens.put("template_id", ddmTemplateKey);
1777 }
1778
1779 String xml = article.getContent();
1780
1781 try {
1782 Document document = null;
1783
1784 Element rootElement = null;
1785
1786 if (article.isTemplateDriven()) {
1787 document = SAXReaderUtil.read(xml);
1788
1789 rootElement = document.getRootElement();
1790
1791 Document requestDocument = SAXReaderUtil.read(xmlRequest);
1792
1793 List<Element> pages = rootElement.elements("page");
1794
1795 if (!pages.isEmpty()) {
1796 pageFlow = true;
1797
1798 String targetPage = requestDocument.valueOf(
1799 "/request/parameters/parameter[name='targetPage']/" +
1800 "value");
1801
1802 Element pageElement = null;
1803
1804 if (Validator.isNotNull(targetPage)) {
1805 targetPage = HtmlUtil.escapeXPathAttribute(targetPage);
1806
1807 XPath xPathSelector = SAXReaderUtil.createXPath(
1808 "/root/page[@id = " + targetPage + "]");
1809
1810 pageElement = (Element)xPathSelector.selectSingleNode(
1811 document);
1812 }
1813
1814 if (pageElement != null) {
1815 document = SAXReaderUtil.createDocument(pageElement);
1816
1817 rootElement = document.getRootElement();
1818
1819 numberOfPages = pages.size();
1820 }
1821 else {
1822 if (page > pages.size()) {
1823 page = 1;
1824 }
1825
1826 pageElement = pages.get(page - 1);
1827
1828 document = SAXReaderUtil.createDocument(pageElement);
1829
1830 rootElement = document.getRootElement();
1831
1832 numberOfPages = pages.size();
1833 paginate = true;
1834 }
1835 }
1836
1837 rootElement.add(requestDocument.getRootElement().createCopy());
1838
1839 JournalUtil.addAllReservedEls(
1840 rootElement, tokens, article, languageId, themeDisplay);
1841
1842 xml = DDMXMLUtil.formatXML(document);
1843 }
1844 }
1845 catch (DocumentException de) {
1846 throw new SystemException(de);
1847 }
1848
1849 try {
1850 if (_log.isDebugEnabled()) {
1851 _log.debug(
1852 "Transforming " + article.getArticleId() + " " +
1853 article.getVersion() + " " + languageId);
1854 }
1855
1856 String script = null;
1857 String langType = null;
1858
1859 if (article.isTemplateDriven()) {
1860
1861
1862
1863
1864
1865
1866
1867 DDMTemplate ddmTemplate = null;
1868
1869 try {
1870 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1871 PortalUtil.getSiteGroupId(article.getGroupId()),
1872 PortalUtil.getClassNameId(DDMStructure.class),
1873 ddmTemplateKey);
1874 }
1875 catch (NoSuchTemplateException nste1) {
1876 try {
1877 Group companyGroup = groupLocalService.getCompanyGroup(
1878 article.getCompanyId());
1879
1880 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1881 companyGroup.getGroupId(),
1882 PortalUtil.getClassNameId(DDMStructure.class),
1883 ddmTemplateKey);
1884
1885 tokens.put(
1886 "company_group_id",
1887 String.valueOf(companyGroup.getGroupId()));
1888 }
1889 catch (NoSuchTemplateException nste2) {
1890 if (!defaultDDMTemplateKey.equals(ddmTemplateKey)) {
1891 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1892 PortalUtil.getSiteGroupId(article.getGroupId()),
1893 PortalUtil.getClassNameId(DDMStructure.class),
1894 defaultDDMTemplateKey);
1895 }
1896 else {
1897 throw nste1;
1898 }
1899 }
1900 }
1901
1902 script = ddmTemplate.getScript();
1903 langType = ddmTemplate.getLanguage();
1904 cacheable = ddmTemplate.isCacheable();
1905 }
1906
1907 content = JournalUtil.transform(
1908 themeDisplay, tokens, viewMode, languageId, xml, script,
1909 langType);
1910
1911 if (!pageFlow) {
1912 String[] pieces = StringUtil.split(
1913 content, PropsValues.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
1914
1915 if (pieces.length > 1) {
1916 if (page > pieces.length) {
1917 page = 1;
1918 }
1919
1920 content = pieces[page - 1];
1921 numberOfPages = pieces.length;
1922 paginate = true;
1923 }
1924 }
1925 }
1926 catch (Exception e) {
1927 throw new SystemException(e);
1928 }
1929
1930 return new JournalArticleDisplayImpl(
1931 article.getCompanyId(), article.getId(),
1932 article.getResourcePrimKey(), article.getGroupId(),
1933 article.getUserId(), article.getArticleId(), article.getVersion(),
1934 article.getTitle(languageId), article.getUrlTitle(),
1935 article.getDescription(languageId),
1936 article.getAvailableLanguageIds(), content, article.getType(),
1937 article.getStructureId(), ddmTemplateKey, article.isSmallImage(),
1938 article.getSmallImageId(), article.getSmallImageURL(),
1939 numberOfPages, page, paginate, cacheable);
1940 }
1941
1942
1969 @Override
1970 public JournalArticleDisplay getArticleDisplay(
1971 long groupId, String articleId, double version,
1972 String ddmTemplateKey, String viewMode, String languageId, int page,
1973 String xmlRequest, ThemeDisplay themeDisplay)
1974 throws PortalException, SystemException {
1975
1976 Date now = new Date();
1977
1978 JournalArticle article = journalArticlePersistence.findByG_A_V(
1979 groupId, articleId, version);
1980
1981 if (article.isExpired()) {
1982 Date expirationDate = article.getExpirationDate();
1983
1984 if ((expirationDate != null) && expirationDate.before(now)) {
1985 return null;
1986 }
1987 }
1988
1989 Date displayDate = article.getDisplayDate();
1990
1991 if (displayDate.after(now)) {
1992 return null;
1993 }
1994
1995 return getArticleDisplay(
1996 article, ddmTemplateKey, viewMode, languageId, page, xmlRequest,
1997 themeDisplay);
1998 }
1999
2000
2024 @Override
2025 public JournalArticleDisplay getArticleDisplay(
2026 long groupId, String articleId, double version,
2027 String ddmTemplateKey, String viewMode, String languageId,
2028 ThemeDisplay themeDisplay)
2029 throws PortalException, SystemException {
2030
2031 return getArticleDisplay(
2032 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
2033 1, null, themeDisplay);
2034 }
2035
2036
2058 @Override
2059 public JournalArticleDisplay getArticleDisplay(
2060 long groupId, String articleId, String viewMode, String languageId,
2061 int page, String xmlRequest, ThemeDisplay themeDisplay)
2062 throws PortalException, SystemException {
2063
2064 return getArticleDisplay(
2065 groupId, articleId, null, viewMode, languageId, page, xmlRequest,
2066 themeDisplay);
2067 }
2068
2069
2096 @Override
2097 public JournalArticleDisplay getArticleDisplay(
2098 long groupId, String articleId, String ddmTemplateKey,
2099 String viewMode, String languageId, int page, String xmlRequest,
2100 ThemeDisplay themeDisplay)
2101 throws PortalException, SystemException {
2102
2103 JournalArticle article = getDisplayArticle(groupId, articleId);
2104
2105 return getArticleDisplay(
2106 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2107 languageId, page, xmlRequest, themeDisplay);
2108 }
2109
2110
2133 @Override
2134 public JournalArticleDisplay getArticleDisplay(
2135 long groupId, String articleId, String ddmTemplateKey,
2136 String viewMode, String languageId, ThemeDisplay themeDisplay)
2137 throws PortalException, SystemException {
2138
2139 JournalArticle article = getDisplayArticle(groupId, articleId);
2140
2141 return getArticleDisplay(
2142 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2143 languageId, themeDisplay);
2144 }
2145
2146
2164 @Override
2165 public JournalArticleDisplay getArticleDisplay(
2166 long groupId, String articleId, String viewMode, String languageId,
2167 ThemeDisplay themeDisplay)
2168 throws PortalException, SystemException {
2169
2170 return getArticleDisplay(
2171 groupId, articleId, null, viewMode, languageId, themeDisplay);
2172 }
2173
2174
2180 @Override
2181 public List<JournalArticle> getArticles() throws SystemException {
2182 return journalArticlePersistence.findAll();
2183 }
2184
2185
2192 @Override
2193 public List<JournalArticle> getArticles(long groupId)
2194 throws SystemException {
2195
2196 return journalArticlePersistence.findByGroupId(groupId);
2197 }
2198
2199
2219 @Override
2220 public List<JournalArticle> getArticles(long groupId, int start, int end)
2221 throws SystemException {
2222
2223 return journalArticlePersistence.findByGroupId(groupId, start, end);
2224 }
2225
2226
2249 @Override
2250 public List<JournalArticle> getArticles(
2251 long groupId, int start, int end, OrderByComparator obc)
2252 throws SystemException {
2253
2254 return journalArticlePersistence.findByGroupId(
2255 groupId, start, end, obc);
2256 }
2257
2258
2266 @Override
2267 public List<JournalArticle> getArticles(long groupId, long folderId)
2268 throws SystemException {
2269
2270 return journalArticlePersistence.findByG_F(groupId, folderId);
2271 }
2272
2273
2295 @Override
2296 public List<JournalArticle> getArticles(
2297 long groupId, long folderId, int start, int end)
2298 throws SystemException {
2299
2300 return journalArticlePersistence.findByG_F(
2301 groupId, folderId, start, end);
2302 }
2303
2304 @Override
2305 public List<JournalArticle> getArticles(
2306 long groupId, long folderId, int status, int start, int end)
2307 throws SystemException {
2308
2309 return journalArticlePersistence.findByG_F_ST(
2310 groupId, folderId, status, start, end);
2311 }
2312
2313
2338 @Override
2339 public List<JournalArticle> getArticles(
2340 long groupId, long folderId, int start, int end,
2341 OrderByComparator orderByComparator)
2342 throws SystemException {
2343
2344 return journalArticlePersistence.findByG_F(
2345 groupId, folderId, start, end, orderByComparator);
2346 }
2347
2348
2356 @Override
2357 public List<JournalArticle> getArticles(long groupId, String articleId)
2358 throws SystemException {
2359
2360 return journalArticlePersistence.findByG_A(groupId, articleId);
2361 }
2362
2363 @Override
2364 public List<JournalArticle> getArticlesByResourcePrimKey(
2365 long resourcePrimKey)
2366 throws SystemException {
2367
2368 return journalArticlePersistence.findByResourcePrimKey(resourcePrimKey);
2369 }
2370
2371
2379 @Override
2380 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId)
2381 throws SystemException {
2382
2383 return journalArticlePersistence.findBySmallImageId(smallImageId);
2384 }
2385
2386
2393 @Override
2394 public int getArticlesCount(long groupId) throws SystemException {
2395 return journalArticlePersistence.countByGroupId(groupId);
2396 }
2397
2398
2406 @Override
2407 public int getArticlesCount(long groupId, long folderId)
2408 throws SystemException {
2409
2410 return journalArticlePersistence.countByG_F(groupId, folderId);
2411 }
2412
2413 @Override
2414 public int getArticlesCount(long groupId, long folderId, int status)
2415 throws SystemException {
2416
2417 return journalArticlePersistence.countByG_F_ST(
2418 groupId, folderId, status);
2419 }
2420
2421
2446 @Override
2447 public List<JournalArticle> getCompanyArticles(
2448 long companyId, double version, int status, int start, int end)
2449 throws SystemException {
2450
2451 if (status == WorkflowConstants.STATUS_ANY) {
2452 return journalArticlePersistence.findByC_V(
2453 companyId, version, start, end, new ArticleIDComparator(true));
2454 }
2455 else {
2456 return journalArticlePersistence.findByC_V_ST(
2457 companyId, version, status, start, end,
2458 new ArticleIDComparator(true));
2459 }
2460 }
2461
2462
2486 @Override
2487 public List<JournalArticle> getCompanyArticles(
2488 long companyId, int status, int start, int end)
2489 throws SystemException {
2490
2491 if (status == WorkflowConstants.STATUS_ANY) {
2492 return journalArticlePersistence.findByCompanyId(
2493 companyId, start, end, new ArticleIDComparator(true));
2494 }
2495 else {
2496 return journalArticlePersistence.findByC_ST(
2497 companyId, status, start, end, new ArticleIDComparator(true));
2498 }
2499 }
2500
2501
2526 @Override
2527 public int getCompanyArticlesCount(
2528 long companyId, double version, int status, int start, int end)
2529 throws SystemException {
2530
2531 if (status == WorkflowConstants.STATUS_ANY) {
2532 return journalArticlePersistence.countByC_V(companyId, version);
2533 }
2534 else {
2535 return journalArticlePersistence.countByC_V_ST(
2536 companyId, version, status);
2537 }
2538 }
2539
2540
2551 @Override
2552 public int getCompanyArticlesCount(long companyId, int status)
2553 throws SystemException {
2554
2555 if (status == WorkflowConstants.STATUS_ANY) {
2556 return journalArticlePersistence.countByCompanyId(companyId);
2557 }
2558 else {
2559 return journalArticlePersistence.countByC_ST(companyId, status);
2560 }
2561 }
2562
2563
2576 @Override
2577 public JournalArticle getDisplayArticle(long groupId, String articleId)
2578 throws PortalException, SystemException {
2579
2580 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
2581 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
2582
2583 if (articles.isEmpty()) {
2584 throw new NoSuchArticleException(
2585 "No approved JournalArticle exists with the key {groupId=" +
2586 groupId + ", " + "articleId=" + articleId + "}");
2587 }
2588
2589 Date now = new Date();
2590
2591 for (int i = 0; i < articles.size(); i++) {
2592 JournalArticle article = articles.get(i);
2593
2594 Date displayDate = article.getDisplayDate();
2595 Date expirationDate = article.getExpirationDate();
2596
2597 if (((displayDate == null) || displayDate.before(now)) &&
2598 ((expirationDate == null) || expirationDate.after(now))) {
2599
2600 return article;
2601 }
2602 }
2603
2604 return articles.get(0);
2605 }
2606
2607
2620 @Override
2621 public JournalArticle getDisplayArticleByUrlTitle(
2622 long groupId, String urlTitle)
2623 throws PortalException, SystemException {
2624
2625 List<JournalArticle> articles = null;
2626
2627 OrderByComparator orderByComparator = new ArticleVersionComparator();
2628
2629 articles = journalArticlePersistence.findByG_UT_ST(
2630 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED,
2631 QueryUtil.ALL_POS, QueryUtil.ALL_POS, orderByComparator);
2632
2633 if (articles.isEmpty()) {
2634 throw new NoSuchArticleException(
2635 "No JournalArticle exists with the key {groupId=" + groupId +
2636 ", urlTitle=" + urlTitle + "}");
2637 }
2638
2639 Date now = new Date();
2640
2641 for (JournalArticle article : articles) {
2642 Date displayDate = article.getDisplayDate();
2643 Date expirationDate = article.getExpirationDate();
2644
2645 if (((displayDate != null) && displayDate.before(now)) &&
2646 ((expirationDate == null) || expirationDate.after(now)) ) {
2647
2648 return article;
2649 }
2650 }
2651
2652 return articles.get(0);
2653 }
2654
2655 @Override
2656 public List<JournalArticle> getIndexableArticlesByResourcePrimKey(
2657 long resourcePrimKey)
2658 throws SystemException {
2659
2660 return journalArticlePersistence.findByR_I(resourcePrimKey, true);
2661 }
2662
2663
2674 @Override
2675 public JournalArticle getLatestArticle(long resourcePrimKey)
2676 throws PortalException, SystemException {
2677
2678 return getLatestArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);
2679 }
2680
2681
2696 @Override
2697 public JournalArticle getLatestArticle(long resourcePrimKey, int status)
2698 throws PortalException, SystemException {
2699
2700 return getLatestArticle(resourcePrimKey, status, true);
2701 }
2702
2703
2723 @Override
2724 public JournalArticle getLatestArticle(
2725 long resourcePrimKey, int status, boolean preferApproved)
2726 throws PortalException, SystemException {
2727
2728 List<JournalArticle> articles = null;
2729
2730 OrderByComparator orderByComparator = new ArticleVersionComparator();
2731
2732 if (status == WorkflowConstants.STATUS_ANY) {
2733 if (preferApproved) {
2734 articles = journalArticlePersistence.findByR_ST(
2735 resourcePrimKey, WorkflowConstants.STATUS_APPROVED, 0, 1,
2736 orderByComparator);
2737 }
2738
2739 if ((articles == null) || (articles.size() == 0)) {
2740 articles = journalArticlePersistence.findByResourcePrimKey(
2741 resourcePrimKey, 0, 1, orderByComparator);
2742 }
2743 }
2744 else {
2745 articles = journalArticlePersistence.findByR_ST(
2746 resourcePrimKey, status, 0, 1, orderByComparator);
2747 }
2748
2749 if (articles.isEmpty()) {
2750 throw new NoSuchArticleException(
2751 "No JournalArticle exists with the key {resourcePrimKey=" +
2752 resourcePrimKey + "}");
2753 }
2754
2755 return articles.get(0);
2756 }
2757
2758
2768 @Override
2769 public JournalArticle getLatestArticle(long groupId, String articleId)
2770 throws PortalException, SystemException {
2771
2772 return getLatestArticle(
2773 groupId, articleId, WorkflowConstants.STATUS_ANY);
2774 }
2775
2776
2790 @Override
2791 public JournalArticle getLatestArticle(
2792 long groupId, String articleId, int status)
2793 throws PortalException, SystemException {
2794
2795 List<JournalArticle> articles = null;
2796
2797 OrderByComparator orderByComparator = new ArticleVersionComparator();
2798
2799 if (status == WorkflowConstants.STATUS_ANY) {
2800 articles = journalArticlePersistence.findByG_A_NotST(
2801 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH, 0, 1,
2802 orderByComparator);
2803 }
2804 else {
2805 articles = journalArticlePersistence.findByG_A_ST(
2806 groupId, articleId, status, 0, 1, orderByComparator);
2807 }
2808
2809 if (articles.isEmpty()) {
2810 throw new NoSuchArticleException(
2811 "No JournalArticle exists with the key {groupId=" + groupId +
2812 ", articleId=" + articleId + ", status=" + status + "}");
2813 }
2814
2815 return articles.get(0);
2816 }
2817
2818
2836 @Override
2837 public JournalArticle getLatestArticle(
2838 long groupId, String className, long classPK)
2839 throws PortalException, SystemException {
2840
2841 long classNameId = PortalUtil.getClassNameId(className);
2842
2843 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
2844 groupId, classNameId, classPK, 0, 1,
2845 new ArticleVersionComparator());
2846
2847 if (articles.isEmpty()) {
2848 throw new NoSuchArticleException(
2849 "No JournalArticle exists with the key {groupId=" + groupId +
2850 ", className=" + className + ", classPK =" + classPK + "}");
2851 }
2852
2853 return articles.get(0);
2854 }
2855
2856
2870 @Override
2871 public JournalArticle getLatestArticleByUrlTitle(
2872 long groupId, String urlTitle, int status)
2873 throws PortalException, SystemException {
2874
2875 List<JournalArticle> articles = null;
2876
2877 OrderByComparator orderByComparator = new ArticleVersionComparator();
2878
2879 if (status == WorkflowConstants.STATUS_ANY) {
2880 articles = journalArticlePersistence.findByG_UT(
2881 groupId, urlTitle, 0, 1, orderByComparator);
2882 }
2883 else {
2884 articles = journalArticlePersistence.findByG_UT_ST(
2885 groupId, urlTitle, status, 0, 1, orderByComparator);
2886 }
2887
2888 if (articles.isEmpty()) {
2889 throw new NoSuchArticleException(
2890 "No JournalArticle exists with the key {groupId=" + groupId +
2891 ", urlTitle=" + urlTitle + ", status=" + status + "}");
2892 }
2893
2894 return articles.get(0);
2895 }
2896
2897
2908 @Override
2909 public double getLatestVersion(long groupId, String articleId)
2910 throws PortalException, SystemException {
2911
2912 JournalArticle article = getLatestArticle(groupId, articleId);
2913
2914 return article.getVersion();
2915 }
2916
2917
2931 @Override
2932 public double getLatestVersion(long groupId, String articleId, int status)
2933 throws PortalException, SystemException {
2934
2935 JournalArticle article = getLatestArticle(groupId, articleId, status);
2936
2937 return article.getVersion();
2938 }
2939
2940
2948 @Override
2949 public int getNotInTrashArticlesCount(long groupId, long folderId)
2950 throws SystemException {
2951
2952 QueryDefinition queryDefinition = new QueryDefinition(
2953 WorkflowConstants.STATUS_ANY);
2954
2955 List<Long> folderIds = new ArrayList<Long>();
2956
2957 folderIds.add(folderId);
2958
2959 return journalArticleFinder.countByG_F(
2960 groupId, folderIds, queryDefinition);
2961 }
2962
2963
2973 @Override
2974 public List<JournalArticle> getStructureArticles(
2975 long groupId, String ddmStructureKey)
2976 throws SystemException {
2977
2978 return journalArticlePersistence.findByG_S(groupId, ddmStructureKey);
2979 }
2980
2981
3006 @Override
3007 public List<JournalArticle> getStructureArticles(
3008 long groupId, String ddmStructureKey, int start, int end,
3009 OrderByComparator obc)
3010 throws SystemException {
3011
3012 return journalArticlePersistence.findByG_S(
3013 groupId, ddmStructureKey, start, end, obc);
3014 }
3015
3016 @Override
3017 public List<JournalArticle> getStructureArticles(String[] ddmStructureKeys)
3018 throws SystemException {
3019
3020 return journalArticlePersistence.findByStructureId(ddmStructureKeys);
3021 }
3022
3023
3033 @Override
3034 public int getStructureArticlesCount(long groupId, String ddmStructureKey)
3035 throws SystemException {
3036
3037 return journalArticlePersistence.countByG_S(groupId, ddmStructureKey);
3038 }
3039
3040
3051 @Override
3052 public List<JournalArticle> getTemplateArticles(
3053 long groupId, String ddmTemplateKey)
3054 throws SystemException {
3055
3056 return journalArticlePersistence.findByG_T(groupId, ddmTemplateKey);
3057 }
3058
3059
3086 @Override
3087 public List<JournalArticle> getTemplateArticles(
3088 long groupId, String ddmTemplateKey, int start, int end,
3089 OrderByComparator obc)
3090 throws SystemException {
3091
3092 return journalArticlePersistence.findByG_T(
3093 groupId, ddmTemplateKey, start, end, obc);
3094 }
3095
3096
3108 @Override
3109 public int getTemplateArticlesCount(long groupId, String ddmTemplateKey)
3110 throws SystemException {
3111
3112 return journalArticlePersistence.countByG_T(groupId, ddmTemplateKey);
3113 }
3114
3115 @Override
3116 public String getUniqueUrlTitle(
3117 long groupId, String articleId, String urlTitle)
3118 throws PortalException, SystemException {
3119
3120 for (int i = 1;; i++) {
3121 JournalArticle article = null;
3122
3123 try {
3124 article = getArticleByUrlTitle(groupId, urlTitle);
3125 }
3126 catch (NoSuchArticleException nsae) {
3127 }
3128
3129 if ((article == null) || articleId.equals(article.getArticleId())) {
3130 break;
3131 }
3132 else {
3133 String suffix = StringPool.DASH + i;
3134
3135 String prefix = urlTitle;
3136
3137 if (urlTitle.length() > suffix.length()) {
3138 prefix = urlTitle.substring(
3139 0, urlTitle.length() - suffix.length());
3140 }
3141
3142 urlTitle = prefix + suffix;
3143 }
3144 }
3145
3146 return urlTitle;
3147 }
3148
3149
3158 @Override
3159 public boolean hasArticle(long groupId, String articleId)
3160 throws SystemException {
3161
3162 try {
3163 getArticle(groupId, articleId);
3164
3165 return true;
3166 }
3167 catch (PortalException pe) {
3168 return false;
3169 }
3170 }
3171
3172
3185 @Override
3186 public boolean isLatestVersion(
3187 long groupId, String articleId, double version)
3188 throws PortalException, SystemException {
3189
3190 if (getLatestVersion(groupId, articleId) == version) {
3191 return true;
3192 }
3193 else {
3194 return false;
3195 }
3196 }
3197
3198
3214 @Override
3215 public boolean isLatestVersion(
3216 long groupId, String articleId, double version, int status)
3217 throws PortalException, SystemException {
3218
3219 if (getLatestVersion(groupId, articleId, status) == version) {
3220 return true;
3221 }
3222 else {
3223 return false;
3224 }
3225 }
3226
3227
3240 @Indexable(type = IndexableType.REINDEX)
3241 @Override
3242 public JournalArticle moveArticle(
3243 long groupId, String articleId, long newFolderId)
3244 throws PortalException, SystemException {
3245
3246 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3247 groupId, articleId);
3248
3249 for (JournalArticle article : articles) {
3250 article.setFolderId(newFolderId);
3251 article.setTreePath(article.buildTreePath());
3252
3253 journalArticlePersistence.update(article);
3254 }
3255
3256 return getArticle(groupId, articleId);
3257 }
3258
3259
3282 @Indexable(type = IndexableType.REINDEX)
3283 @Override
3284 public JournalArticle moveArticleFromTrash(
3285 long userId, long groupId, JournalArticle article, long newFolderId,
3286 ServiceContext serviceContext)
3287 throws PortalException, SystemException {
3288
3289 TrashEntry trashEntry = article.getTrashEntry();
3290
3291 if (trashEntry.isTrashEntry(
3292 JournalArticle.class, article.getResourcePrimKey())) {
3293
3294 restoreArticleFromTrash(userId, article);
3295 }
3296 else {
3297
3298
3299
3300 TrashVersion trashVersion =
3301 trashVersionLocalService.fetchVersion(
3302 trashEntry.getEntryId(), JournalArticle.class.getName(),
3303 article.getResourcePrimKey());
3304
3305 int status = WorkflowConstants.STATUS_APPROVED;
3306
3307 if (trashVersion != null) {
3308 status = trashVersion.getStatus();
3309 }
3310
3311 updateStatus(
3312 userId, article, status, null,
3313 new HashMap<String, Serializable>(), serviceContext);
3314
3315
3316
3317 if (trashVersion != null) {
3318 trashVersionLocalService.deleteTrashVersion(trashVersion);
3319 }
3320 }
3321
3322 return moveArticle(groupId, article.getArticleId(), newFolderId);
3323 }
3324
3325
3338 @Indexable(type = IndexableType.REINDEX)
3339 @Override
3340 public JournalArticle moveArticleToTrash(
3341 long userId, JournalArticle article)
3342 throws PortalException, SystemException {
3343
3344
3345
3346 int oldStatus = article.getStatus();
3347
3348 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3349 article.setStatus(WorkflowConstants.STATUS_DRAFT);
3350
3351 journalArticlePersistence.update(article);
3352 }
3353
3354 List<JournalArticle> articleVersions =
3355 journalArticlePersistence.findByG_A(
3356 article.getGroupId(), article.getArticleId());
3357
3358 articleVersions = ListUtil.sort(
3359 articleVersions, new ArticleVersionComparator());
3360
3361 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
3362 new ArrayList<ObjectValuePair<Long, Integer>>();
3363
3364 if ((articleVersions != null) && !articleVersions.isEmpty()) {
3365 articleVersionStatusOVPs = getArticleVersionStatuses(
3366 articleVersions);
3367 }
3368
3369 article = updateStatus(
3370 userId, article.getId(), WorkflowConstants.STATUS_IN_TRASH,
3371 new HashMap<String, Serializable>(), new ServiceContext());
3372
3373
3374
3375 JournalArticleResource articleResource =
3376 journalArticleResourceLocalService.getArticleResource(
3377 article.getResourcePrimKey());
3378
3379 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
3380
3381 typeSettingsProperties.put("title", article.getArticleId());
3382
3383 TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
3384 userId, article.getGroupId(), JournalArticle.class.getName(),
3385 article.getResourcePrimKey(), articleResource.getUuid(), null,
3386 oldStatus, articleVersionStatusOVPs, typeSettingsProperties);
3387
3388 String trashArticleId = TrashUtil.getTrashTitle(
3389 trashEntry.getEntryId());
3390
3391 for (JournalArticle articleVersion : articleVersions) {
3392 articleVersion.setArticleId(trashArticleId);
3393 articleVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
3394
3395 journalArticlePersistence.update(articleVersion);
3396 }
3397
3398 articleResource.setArticleId(trashArticleId);
3399
3400 journalArticleResourcePersistence.update(articleResource);
3401
3402 article.setArticleId(trashArticleId);
3403
3404 article = journalArticlePersistence.update(article);
3405
3406
3407
3408 assetEntryLocalService.updateVisible(
3409 JournalArticle.class.getName(), article.getResourcePrimKey(),
3410 false);
3411
3412
3413
3414 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3415
3416 extraDataJSONObject.put("title", article.getTitle());
3417
3418 socialActivityLocalService.addActivity(
3419 userId, article.getGroupId(), JournalArticle.class.getName(),
3420 article.getResourcePrimKey(),
3421 SocialActivityConstants.TYPE_MOVE_TO_TRASH,
3422 extraDataJSONObject.toString(), 0);
3423
3424 if (!articleVersions.isEmpty()) {
3425 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3426 JournalArticle.class);
3427
3428 for (JournalArticle articleVersion : articleVersions) {
3429 indexer.reindex(articleVersion);
3430 }
3431 }
3432
3433 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3434 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
3435 article.getCompanyId(), article.getGroupId(),
3436 JournalArticle.class.getName(), article.getId());
3437 }
3438
3439 return article;
3440 }
3441
3442
3456 @Override
3457 public JournalArticle moveArticleToTrash(
3458 long userId, long groupId, String articleId)
3459 throws PortalException, SystemException {
3460
3461 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3462 groupId, articleId, 0, 1, new ArticleVersionComparator());
3463
3464 if (!articles.isEmpty()) {
3465 return journalArticleLocalService.moveArticleToTrash(
3466 userId, articles.get(0));
3467 }
3468
3469 return null;
3470 }
3471
3472 @Override
3473 public void rebuildTree(long companyId) throws SystemException {
3474 journalFolderLocalService.rebuildTree(companyId);
3475
3476 Session session = journalArticlePersistence.openSession();
3477
3478 try {
3479 TreePathUtil.rebuildTree(
3480 session, companyId, JournalArticleModelImpl.TABLE_NAME,
3481 JournalFolderModelImpl.TABLE_NAME, "folderId", true);
3482 }
3483 finally {
3484 journalArticlePersistence.closeSession(session);
3485
3486 journalArticlePersistence.clearCache();
3487 }
3488 }
3489
3490
3503 @Indexable(type = IndexableType.REINDEX)
3504 @Override
3505 public JournalArticle removeArticleLocale(
3506 long groupId, String articleId, double version, String languageId)
3507 throws PortalException, SystemException {
3508
3509 JournalArticle article = journalArticlePersistence.findByG_A_V(
3510 groupId, articleId, version);
3511
3512 String title = article.getTitle();
3513
3514 title = LocalizationUtil.removeLocalization(
3515 title, "static-content", languageId, true);
3516
3517 article.setTitle(title);
3518
3519 String description = article.getDescription();
3520
3521 description = LocalizationUtil.removeLocalization(
3522 description, "static-content", languageId, true);
3523
3524 article.setDescription(description);
3525
3526 String content = article.getContent();
3527
3528 if (article.isTemplateDriven()) {
3529 content = JournalUtil.removeArticleLocale(content, languageId);
3530 }
3531 else {
3532 content = LocalizationUtil.removeLocalization(
3533 content, "static-content", languageId, true);
3534 }
3535
3536 article.setContent(content);
3537
3538 journalArticlePersistence.update(article);
3539
3540 return article;
3541 }
3542
3543
3555 @Indexable(type = IndexableType.REINDEX)
3556 @Override
3557 public JournalArticle restoreArticleFromTrash(
3558 long userId, JournalArticle article)
3559 throws PortalException, SystemException {
3560
3561
3562
3563 String trashArticleId = TrashUtil.getOriginalTitle(
3564 article.getArticleId());
3565
3566 List<JournalArticle> articleVersions =
3567 journalArticlePersistence.findByG_A(
3568 article.getGroupId(), article.getArticleId());
3569
3570 for (JournalArticle articleVersion : articleVersions) {
3571 articleVersion.setArticleId(trashArticleId);
3572
3573 journalArticlePersistence.update(articleVersion);
3574 }
3575
3576 article.setArticleId(trashArticleId);
3577
3578 journalArticlePersistence.update(article);
3579
3580 JournalArticleResource articleResource =
3581 journalArticleResourcePersistence.fetchByPrimaryKey(
3582 article.getResourcePrimKey());
3583
3584 articleResource.setArticleId(trashArticleId);
3585
3586 journalArticleResourcePersistence.update(articleResource);
3587
3588 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3589 JournalArticle.class.getName(), article.getResourcePrimKey());
3590
3591 ServiceContext serviceContext = new ServiceContext();
3592
3593 serviceContext.setScopeGroupId(article.getGroupId());
3594
3595 updateStatus(
3596 userId, article, trashEntry.getStatus(), null,
3597 new HashMap<String, Serializable>(), serviceContext);
3598
3599
3600
3601 List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
3602 trashEntry.getEntryId());
3603
3604 for (TrashVersion trashVersion : trashVersions) {
3605 JournalArticle trashArticleVersion =
3606 journalArticlePersistence.findByPrimaryKey(
3607 trashVersion.getClassPK());
3608
3609 trashArticleVersion.setStatus(trashVersion.getStatus());
3610
3611 journalArticlePersistence.update(trashArticleVersion);
3612 }
3613
3614 trashEntryLocalService.deleteEntry(
3615 JournalArticle.class.getName(), article.getResourcePrimKey());
3616
3617
3618
3619 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3620
3621 extraDataJSONObject.put("title", article.getTitle());
3622
3623 socialActivityLocalService.addActivity(
3624 userId, article.getGroupId(), JournalArticle.class.getName(),
3625 article.getResourcePrimKey(),
3626 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
3627 extraDataJSONObject.toString(), 0);
3628
3629 if (!articleVersions.isEmpty()) {
3630 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3631 JournalArticle.class);
3632
3633 for (JournalArticle articleVersion : articleVersions) {
3634 indexer.reindex(articleVersion);
3635 }
3636 }
3637
3638 return article;
3639 }
3640
3641 @Override
3642 public List<JournalArticle> search(
3643 long groupId, List<Long> folderIds, int status, int start, int end)
3644 throws SystemException {
3645
3646 QueryDefinition queryDefinition = new QueryDefinition(
3647 status, start, end, null);
3648
3649 return journalArticleFinder.findByG_F(
3650 groupId, folderIds, queryDefinition);
3651 }
3652
3653 @Override
3654 public List<JournalArticle> search(
3655 long groupId, long folderId, int status, int start, int end)
3656 throws SystemException {
3657
3658 List<Long> folderIds = new ArrayList<Long>();
3659
3660 folderIds.add(folderId);
3661
3662 return search(groupId, folderIds, status, start, end);
3663 }
3664
3665
3727 @Override
3728 public List<JournalArticle> search(
3729 long companyId, long groupId, List<Long> folderIds,
3730 long classNameId, String keywords, Double version, String type,
3731 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3732 Date displayDateLT, int status, Date reviewDate, int start, int end,
3733 OrderByComparator obc)
3734 throws SystemException {
3735
3736 return journalArticleFinder.findByKeywords(
3737 companyId, groupId, folderIds, classNameId, keywords, version, type,
3738 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
3739 status, reviewDate, start, end, obc);
3740 }
3741
3742
3811 @Override
3812 public List<JournalArticle> search(
3813 long companyId, long groupId, List<Long> folderIds,
3814 long classNameId, String articleId, Double version, String title,
3815 String description, String content, String type,
3816 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3817 Date displayDateLT, int status, Date reviewDate,
3818 boolean andOperator, int start, int end, OrderByComparator obc)
3819 throws SystemException {
3820
3821 QueryDefinition queryDefinition = new QueryDefinition(
3822 status, start, end, obc);
3823
3824 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3825 companyId, groupId, folderIds, classNameId, articleId, version,
3826 title, description, content, type, ddmStructureKey, ddmTemplateKey,
3827 displayDateGT, displayDateLT, reviewDate, andOperator,
3828 queryDefinition);
3829 }
3830
3831
3897 @Override
3898 public List<JournalArticle> search(
3899 long companyId, long groupId, List<Long> folderIds,
3900 long classNameId, String articleId, Double version, String title,
3901 String description, String content, String type,
3902 String[] ddmStructureKeys, String[] ddmTemplateKeys,
3903 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
3904 boolean andOperator, int start, int end, OrderByComparator obc)
3905 throws SystemException {
3906
3907 QueryDefinition queryDefinition = new QueryDefinition(
3908 status, start, end, obc);
3909
3910 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3911 companyId, groupId, folderIds, classNameId, articleId, version,
3912 title, description, content, type, ddmStructureKeys,
3913 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
3914 andOperator, queryDefinition);
3915 }
3916
3917
3964 @Override
3965 public Hits search(
3966 long companyId, long groupId, List<Long> folderIds,
3967 long classNameId, String ddmStructureKey, String ddmTemplateKey,
3968 String keywords, LinkedHashMap<String, Object> params, int start,
3969 int end, Sort sort)
3970 throws SystemException {
3971
3972 String articleId = null;
3973 String title = null;
3974 String description = null;
3975 String content = null;
3976 boolean andOperator = false;
3977
3978 if (Validator.isNotNull(keywords)) {
3979 articleId = keywords;
3980 title = keywords;
3981 description = keywords;
3982 content = keywords;
3983 }
3984 else {
3985 andOperator = true;
3986 }
3987
3988 String status = String.valueOf(WorkflowConstants.STATUS_ANY);
3989
3990 if (params != null) {
3991 params.put("keywords", keywords);
3992 }
3993
3994 return search(
3995 companyId, groupId, folderIds, classNameId, articleId, title,
3996 description, content, null, status, ddmStructureKey, ddmTemplateKey,
3997 params, andOperator, start, end, sort);
3998 }
3999
4000
4061 @Override
4062 public Hits search(
4063 long companyId, long groupId, List<Long> folderIds,
4064 long classNameId, String articleId, String title,
4065 String description, String content, String type, String status,
4066 String ddmStructureKey, String ddmTemplateKey,
4067 LinkedHashMap<String, Object> params, boolean andSearch, int start,
4068 int end, Sort sort)
4069 throws SystemException {
4070
4071 try {
4072 SearchContext searchContext = new SearchContext();
4073
4074 searchContext.setAndSearch(andSearch);
4075
4076 Map<String, Serializable> attributes =
4077 new HashMap<String, Serializable>();
4078
4079 attributes.put(Field.CLASS_NAME_ID, classNameId);
4080 attributes.put(Field.CONTENT, content);
4081 attributes.put(Field.DESCRIPTION, description);
4082 attributes.put(Field.STATUS, status);
4083 attributes.put(Field.TITLE, title);
4084 attributes.put(Field.TYPE, type);
4085 attributes.put("articleId", articleId);
4086 attributes.put("ddmStructureKey", ddmStructureKey);
4087 attributes.put("ddmTemplateKey", ddmTemplateKey);
4088 attributes.put("params", params);
4089
4090 searchContext.setAttributes(attributes);
4091
4092 searchContext.setCompanyId(companyId);
4093 searchContext.setEnd(end);
4094 searchContext.setFolderIds(folderIds);
4095 searchContext.setGroupIds(new long[] {groupId});
4096 searchContext.setIncludeDiscussions(
4097 GetterUtil.getBoolean(params.get("includeDiscussions")));
4098
4099 if (params != null) {
4100 String keywords = (String)params.remove("keywords");
4101
4102 if (Validator.isNotNull(keywords)) {
4103 searchContext.setKeywords(keywords);
4104 }
4105 }
4106
4107 QueryConfig queryConfig = new QueryConfig();
4108
4109 queryConfig.setHighlightEnabled(false);
4110 queryConfig.setScoreEnabled(false);
4111
4112 searchContext.setQueryConfig(queryConfig);
4113
4114 if (sort != null) {
4115 searchContext.setSorts(sort);
4116 }
4117
4118 searchContext.setStart(start);
4119
4120 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
4121 JournalArticle.class);
4122
4123 return indexer.search(searchContext);
4124 }
4125 catch (Exception e) {
4126 throw new SystemException(e);
4127 }
4128 }
4129
4130 @Override
4131 public Hits search(
4132 long groupId, long userId, long creatorUserId, int status,
4133 int start, int end)
4134 throws PortalException, SystemException {
4135
4136 Indexer indexer = IndexerRegistryUtil.getIndexer(
4137 JournalArticle.class.getName());
4138
4139 SearchContext searchContext = new SearchContext();
4140
4141 searchContext.setAttribute(Field.STATUS, status);
4142
4143 searchContext.setAttribute("paginationType", "none");
4144
4145 if (creatorUserId > 0) {
4146 searchContext.setAttribute(
4147 Field.USER_ID, String.valueOf(creatorUserId));
4148 }
4149
4150 Group group = groupLocalService.getGroup(groupId);
4151
4152 searchContext.setCompanyId(group.getCompanyId());
4153
4154 searchContext.setEnd(end);
4155 searchContext.setGroupIds(new long[] {groupId});
4156 searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true));
4157 searchContext.setStart(start);
4158 searchContext.setUserId(userId);
4159
4160 return indexer.search(searchContext);
4161 }
4162
4163 @Override
4164 public int searchCount(long groupId, List<Long> folderIds, int status)
4165 throws SystemException {
4166
4167 QueryDefinition queryDefinition = new QueryDefinition(status);
4168
4169 return journalArticleFinder.countByG_F(
4170 groupId, folderIds, queryDefinition);
4171 }
4172
4173 @Override
4174 public int searchCount(long groupId, long folderId, int status)
4175 throws SystemException {
4176
4177 List<Long> folderIds = new ArrayList<Long>();
4178
4179 folderIds.add(folderId);
4180
4181 return searchCount(groupId, folderIds, status);
4182 }
4183
4184
4228 @Override
4229 public int searchCount(
4230 long companyId, long groupId, List<Long> folderIds,
4231 long classNameId, String keywords, Double version, String type,
4232 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4233 Date displayDateLT, int status, Date reviewDate)
4234 throws SystemException {
4235
4236 return journalArticleFinder.countByKeywords(
4237 companyId, groupId, folderIds, classNameId, keywords, version, type,
4238 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
4239 status, reviewDate);
4240 }
4241
4242
4292 @Override
4293 public int searchCount(
4294 long companyId, long groupId, List<Long> folderIds,
4295 long classNameId, String articleId, Double version, String title,
4296 String description, String content, String type,
4297 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4298 Date displayDateLT, int status, Date reviewDate,
4299 boolean andOperator)
4300 throws SystemException {
4301
4302 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4303 companyId, groupId, folderIds, classNameId, articleId, version,
4304 title, description, content, type, ddmStructureKey, ddmTemplateKey,
4305 displayDateGT, displayDateLT, reviewDate, andOperator,
4306 new QueryDefinition(status));
4307 }
4308
4309
4359 @Override
4360 public int searchCount(
4361 long companyId, long groupId, List<Long> folderIds,
4362 long classNameId, String articleId, Double version, String title,
4363 String description, String content, String type,
4364 String[] ddmStructureKeys, String[] ddmTemplateKeys,
4365 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4366 boolean andOperator)
4367 throws SystemException {
4368
4369 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4370 companyId, groupId, folderIds, classNameId, articleId, version,
4371 title, description, content, type, ddmStructureKeys,
4372 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
4373 andOperator, new QueryDefinition(status));
4374 }
4375
4376
4386 @Override
4387 public void subscribe(long userId, long groupId)
4388 throws PortalException, SystemException {
4389
4390 subscriptionLocalService.addSubscription(
4391 userId, groupId, JournalArticle.class.getName(), groupId);
4392 }
4393
4394
4404 @Override
4405 public void unsubscribe(long userId, long groupId)
4406 throws PortalException, SystemException {
4407
4408 subscriptionLocalService.deleteSubscription(
4409 userId, JournalArticle.class.getName(), groupId);
4410 }
4411
4412
4446 @Override
4447 public JournalArticle updateArticle(
4448 long userId, long groupId, long folderId, String articleId,
4449 double version, Map<Locale, String> titleMap,
4450 Map<Locale, String> descriptionMap, String content,
4451 String layoutUuid, ServiceContext serviceContext)
4452 throws PortalException, SystemException {
4453
4454 User user = userPersistence.findByPrimaryKey(userId);
4455
4456 JournalArticle article = journalArticlePersistence.findByG_A_V(
4457 groupId, articleId, version);
4458
4459 Date displayDate = article.getDisplayDate();
4460
4461 int displayDateMonth = 0;
4462 int displayDateDay = 0;
4463 int displayDateYear = 0;
4464 int displayDateHour = 0;
4465 int displayDateMinute = 0;
4466
4467 if (displayDate != null) {
4468 Calendar displayCal = CalendarFactoryUtil.getCalendar(
4469 user.getTimeZone());
4470
4471 displayCal.setTime(displayDate);
4472
4473 displayDateMonth = displayCal.get(Calendar.MONTH);
4474 displayDateDay = displayCal.get(Calendar.DATE);
4475 displayDateYear = displayCal.get(Calendar.YEAR);
4476 displayDateHour = displayCal.get(Calendar.HOUR);
4477 displayDateMinute = displayCal.get(Calendar.MINUTE);
4478
4479 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
4480 displayDateHour += 12;
4481 }
4482 }
4483
4484 Date expirationDate = article.getExpirationDate();
4485
4486 int expirationDateMonth = 0;
4487 int expirationDateDay = 0;
4488 int expirationDateYear = 0;
4489 int expirationDateHour = 0;
4490 int expirationDateMinute = 0;
4491 boolean neverExpire = true;
4492
4493 if (expirationDate != null) {
4494 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
4495 user.getTimeZone());
4496
4497 expirationCal.setTime(expirationDate);
4498
4499 expirationDateMonth = expirationCal.get(Calendar.MONTH);
4500 expirationDateDay = expirationCal.get(Calendar.DATE);
4501 expirationDateYear = expirationCal.get(Calendar.YEAR);
4502 expirationDateHour = expirationCal.get(Calendar.HOUR);
4503 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
4504 neverExpire = false;
4505
4506 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
4507 expirationDateHour += 12;
4508 }
4509 }
4510
4511 Date reviewDate = article.getReviewDate();
4512
4513 int reviewDateMonth = 0;
4514 int reviewDateDay = 0;
4515 int reviewDateYear = 0;
4516 int reviewDateHour = 0;
4517 int reviewDateMinute = 0;
4518 boolean neverReview = true;
4519
4520 if (reviewDate != null) {
4521 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
4522 user.getTimeZone());
4523
4524 reviewCal.setTime(reviewDate);
4525
4526 reviewDateMonth = reviewCal.get(Calendar.MONTH);
4527 reviewDateDay = reviewCal.get(Calendar.DATE);
4528 reviewDateYear = reviewCal.get(Calendar.YEAR);
4529 reviewDateHour = reviewCal.get(Calendar.HOUR);
4530 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
4531 neverReview = false;
4532
4533 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
4534 reviewDateHour += 12;
4535 }
4536 }
4537
4538 return journalArticleLocalService.updateArticle(
4539 userId, groupId, folderId, articleId, version, titleMap,
4540 descriptionMap, content, article.getType(),
4541 article.getStructureId(), article.getTemplateId(), layoutUuid,
4542 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
4543 displayDateMinute, expirationDateMonth, expirationDateDay,
4544 expirationDateYear, expirationDateHour, expirationDateMinute,
4545 neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
4546 reviewDateHour, reviewDateMinute, neverReview,
4547 article.getIndexable(), article.isSmallImage(),
4548 article.getSmallImageURL(), null, null, null, serviceContext);
4549 }
4550
4551
4638 @Indexable(type = IndexableType.REINDEX)
4639 @Override
4640 public JournalArticle updateArticle(
4641 long userId, long groupId, long folderId, String articleId,
4642 double version, Map<Locale, String> titleMap,
4643 Map<Locale, String> descriptionMap, String content, String type,
4644 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
4645 int displayDateMonth, int displayDateDay, int displayDateYear,
4646 int displayDateHour, int displayDateMinute, int expirationDateMonth,
4647 int expirationDateDay, int expirationDateYear,
4648 int expirationDateHour, int expirationDateMinute,
4649 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
4650 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
4651 boolean neverReview, boolean indexable, boolean smallImage,
4652 String smallImageURL, File smallImageFile,
4653 Map<String, byte[]> images, String articleURL,
4654 ServiceContext serviceContext)
4655 throws PortalException, SystemException {
4656
4657
4658
4659 User user = userPersistence.findByPrimaryKey(userId);
4660 articleId = StringUtil.toUpperCase(articleId.trim());
4661
4662 byte[] smallImageBytes = null;
4663
4664 try {
4665 smallImageBytes = FileUtil.getBytes(smallImageFile);
4666 }
4667 catch (IOException ioe) {
4668 }
4669
4670 JournalArticle latestArticle = getLatestArticle(
4671 groupId, articleId, WorkflowConstants.STATUS_ANY);
4672
4673 JournalArticle article = latestArticle;
4674
4675 boolean imported = ExportImportThreadLocal.isImportInProcess();
4676
4677 double latestVersion = latestArticle.getVersion();
4678
4679 boolean addNewVersion = false;
4680
4681 if (imported) {
4682 if (latestVersion > version) {
4683 JournalArticle existingArticle =
4684 journalArticlePersistence.fetchByG_A_V(
4685 groupId, articleId, version);
4686
4687 if (existingArticle != null) {
4688 article = existingArticle;
4689 }
4690 else {
4691 addNewVersion = true;
4692 }
4693 }
4694 else if (latestVersion < version) {
4695 addNewVersion = true;
4696 }
4697 }
4698 else {
4699 if ((version > 0) && (version != latestVersion)) {
4700 throw new ArticleVersionException();
4701 }
4702
4703 serviceContext.validateModifiedDate(
4704 latestArticle, ArticleVersionException.class);
4705
4706 if (latestArticle.isApproved() || latestArticle.isExpired() ||
4707 latestArticle.isScheduled()) {
4708
4709 addNewVersion = true;
4710
4711 version = MathUtil.format(latestVersion + 0.1, 1, 1);
4712 }
4713 }
4714
4715 Date displayDate = null;
4716 Date expirationDate = null;
4717 Date reviewDate = null;
4718
4719 if (article.getClassNameId() ==
4720 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
4721
4722 displayDate = PortalUtil.getDate(
4723 displayDateMonth, displayDateDay, displayDateYear,
4724 displayDateHour, displayDateMinute, user.getTimeZone(),
4725 ArticleDisplayDateException.class);
4726
4727 if (!neverExpire) {
4728 expirationDate = PortalUtil.getDate(
4729 expirationDateMonth, expirationDateDay, expirationDateYear,
4730 expirationDateHour, expirationDateMinute,
4731 user.getTimeZone(), ArticleExpirationDateException.class);
4732 }
4733
4734 if (!neverReview) {
4735 reviewDate = PortalUtil.getDate(
4736 reviewDateMonth, reviewDateDay, reviewDateYear,
4737 reviewDateHour, reviewDateMinute, user.getTimeZone(),
4738 ArticleReviewDateException.class);
4739 }
4740 }
4741
4742 Date now = new Date();
4743
4744 boolean expired = false;
4745
4746 if ((expirationDate != null) && expirationDate.before(now)) {
4747 expired = true;
4748 }
4749
4750 validate(
4751 user.getCompanyId(), groupId, latestArticle.getClassNameId(),
4752 titleMap, content, type, ddmStructureKey, ddmTemplateKey,
4753 expirationDate, smallImage, smallImageURL, smallImageFile,
4754 smallImageBytes);
4755
4756 if (addNewVersion) {
4757 long id = counterLocalService.increment();
4758
4759 article = journalArticlePersistence.create(id);
4760
4761 article.setResourcePrimKey(latestArticle.getResourcePrimKey());
4762 article.setGroupId(latestArticle.getGroupId());
4763 article.setCompanyId(latestArticle.getCompanyId());
4764 article.setUserId(user.getUserId());
4765 article.setUserName(user.getFullName());
4766 article.setCreateDate(serviceContext.getModifiedDate(now));
4767 article.setClassNameId(latestArticle.getClassNameId());
4768 article.setClassPK(latestArticle.getClassPK());
4769 article.setArticleId(articleId);
4770 article.setVersion(version);
4771 article.setSmallImageId(latestArticle.getSmallImageId());
4772 }
4773
4774 Locale locale = LocaleUtil.getSiteDefault();
4775
4776 String defaultLanguageId = ParamUtil.getString(
4777 serviceContext, "defaultLanguageId");
4778
4779 if (Validator.isNull(defaultLanguageId)) {
4780 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
4781 }
4782
4783 if (Validator.isNotNull(defaultLanguageId)) {
4784 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
4785 }
4786
4787 String title = titleMap.get(locale);
4788
4789 content = format(
4790 user, groupId, articleId, article.getVersion(), addNewVersion,
4791 content, ddmStructureKey, images);
4792
4793 article.setModifiedDate(serviceContext.getModifiedDate(now));
4794 article.setFolderId(folderId);
4795 article.setTreePath(article.buildTreePath());
4796 article.setTitleMap(titleMap, locale);
4797 article.setUrlTitle(
4798 getUniqueUrlTitle(
4799 article.getId(), article.getArticleId(), title,
4800 latestArticle.getUrlTitle(), serviceContext));
4801 article.setDescriptionMap(descriptionMap, locale);
4802 article.setContent(content);
4803 article.setType(type);
4804 article.setStructureId(ddmStructureKey);
4805 article.setTemplateId(ddmTemplateKey);
4806 article.setLayoutUuid(layoutUuid);
4807 article.setDisplayDate(displayDate);
4808 article.setExpirationDate(expirationDate);
4809 article.setReviewDate(reviewDate);
4810 article.setIndexable(indexable);
4811 article.setSmallImage(smallImage);
4812
4813 if (smallImage) {
4814 if ((smallImageFile != null) && (smallImageBytes != null)) {
4815 article.setSmallImageId(counterLocalService.increment());
4816 }
4817 }
4818 else {
4819 article.setSmallImageId(0);
4820 }
4821
4822 article.setSmallImageURL(smallImageURL);
4823
4824 if (latestArticle.isPending()) {
4825 article.setStatus(latestArticle.getStatus());
4826 }
4827 else if (!expired) {
4828 article.setStatus(WorkflowConstants.STATUS_DRAFT);
4829 }
4830 else {
4831 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
4832 }
4833
4834 article.setExpandoBridgeAttributes(serviceContext);
4835
4836 journalArticlePersistence.update(article);
4837
4838
4839
4840 updateAsset(
4841 userId, article, serviceContext.getAssetCategoryIds(),
4842 serviceContext.getAssetTagNames(),
4843 serviceContext.getAssetLinkEntryIds());
4844
4845
4846
4847 if (PortalUtil.getClassNameId(DDMStructure.class) ==
4848 article.getClassNameId()) {
4849
4850 updateDDMStructureXSD(
4851 article.getClassPK(), content, serviceContext);
4852 }
4853
4854
4855
4856 saveImages(
4857 smallImage, article.getSmallImageId(), smallImageFile,
4858 smallImageBytes);
4859
4860
4861
4862 PortletPreferences preferences =
4863 ServiceContextUtil.getPortletPreferences(serviceContext);
4864
4865
4866
4867 if (expired && imported) {
4868 updateStatus(
4869 userId, article, article.getStatus(), articleURL,
4870 new HashMap<String, Serializable>(), serviceContext);
4871 }
4872
4873 if (serviceContext.getWorkflowAction() ==
4874 WorkflowConstants.ACTION_PUBLISH) {
4875
4876 sendEmail(
4877 article, articleURL, preferences, "requested", serviceContext);
4878
4879 WorkflowHandlerRegistryUtil.startWorkflowInstance(
4880 user.getCompanyId(), groupId, userId,
4881 JournalArticle.class.getName(), article.getId(), article,
4882 serviceContext);
4883 }
4884
4885 return journalArticlePersistence.findByPrimaryKey(article.getId());
4886 }
4887
4888
4917 @Override
4918 public JournalArticle updateArticle(
4919 long userId, long groupId, long folderId, String articleId,
4920 double version, String content, ServiceContext serviceContext)
4921 throws PortalException, SystemException {
4922
4923 JournalArticle article = journalArticlePersistence.findByG_A_V(
4924 groupId, articleId, version);
4925
4926 return journalArticleLocalService.updateArticle(
4927 userId, groupId, folderId, articleId, version,
4928 article.getTitleMap(), article.getDescriptionMap(), content,
4929 article.getLayoutUuid(), serviceContext);
4930 }
4931
4932
4937 @Override
4938 public JournalArticle updateArticleTranslation(
4939 long groupId, String articleId, double version, Locale locale,
4940 String title, String description, String content,
4941 Map<String, byte[]> images)
4942 throws PortalException, SystemException {
4943
4944 return journalArticleLocalService.updateArticleTranslation(
4945 groupId, articleId, version, locale, title, description, content,
4946 images, null);
4947 }
4948
4949
4971 @Indexable(type = IndexableType.REINDEX)
4972 @Override
4973 public JournalArticle updateArticleTranslation(
4974 long groupId, String articleId, double version, Locale locale,
4975 String title, String description, String content,
4976 Map<String, byte[]> images, ServiceContext serviceContext)
4977 throws PortalException, SystemException {
4978
4979 validateContent(content);
4980
4981 JournalArticle oldArticle = getLatestArticle(
4982 groupId, articleId, WorkflowConstants.STATUS_ANY);
4983
4984 double oldVersion = oldArticle.getVersion();
4985
4986 if ((version > 0) && (version != oldVersion)) {
4987 throw new ArticleVersionException();
4988 }
4989
4990 boolean incrementVersion = false;
4991
4992 if (oldArticle.isApproved() || oldArticle.isExpired()) {
4993 incrementVersion = true;
4994 }
4995
4996 if (serviceContext != null) {
4997 serviceContext.validateModifiedDate(
4998 oldArticle, ArticleVersionException.class);
4999 }
5000
5001 JournalArticle article = null;
5002
5003 User user = userPersistence.findByPrimaryKey(oldArticle.getUserId());
5004
5005 if (incrementVersion) {
5006 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
5007
5008 long id = counterLocalService.increment();
5009
5010 article = journalArticlePersistence.create(id);
5011
5012 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
5013 article.setGroupId(oldArticle.getGroupId());
5014 article.setCompanyId(oldArticle.getCompanyId());
5015 article.setUserId(oldArticle.getUserId());
5016 article.setUserName(user.getFullName());
5017 article.setCreateDate(new Date());
5018 article.setModifiedDate(new Date());
5019 article.setClassNameId(oldArticle.getClassNameId());
5020 article.setClassPK(oldArticle.getClassPK());
5021 article.setArticleId(articleId);
5022 article.setVersion(newVersion);
5023 article.setTitleMap(oldArticle.getTitleMap());
5024 article.setUrlTitle(
5025 getUniqueUrlTitle(
5026 id, articleId, title, oldArticle.getUrlTitle(),
5027 serviceContext));
5028 article.setDescriptionMap(oldArticle.getDescriptionMap());
5029 article.setType(oldArticle.getType());
5030 article.setStructureId(oldArticle.getStructureId());
5031 article.setTemplateId(oldArticle.getTemplateId());
5032 article.setLayoutUuid(oldArticle.getLayoutUuid());
5033 article.setDisplayDate(oldArticle.getDisplayDate());
5034 article.setExpirationDate(oldArticle.getExpirationDate());
5035 article.setReviewDate(oldArticle.getReviewDate());
5036 article.setIndexable(oldArticle.getIndexable());
5037 article.setSmallImage(oldArticle.getSmallImage());
5038 article.setSmallImageId(oldArticle.getSmallImageId());
5039
5040 if (article.getSmallImageId() == 0) {
5041 article.setSmallImageId(counterLocalService.increment());
5042 }
5043
5044 article.setSmallImageURL(oldArticle.getSmallImageURL());
5045
5046 article.setStatus(WorkflowConstants.STATUS_DRAFT);
5047 article.setStatusDate(new Date());
5048 }
5049 else {
5050 article = oldArticle;
5051 }
5052
5053 Map<Locale, String> titleMap = article.getTitleMap();
5054
5055 titleMap.put(locale, title);
5056
5057 article.setTitleMap(titleMap);
5058
5059 Map<Locale, String> descriptionMap = article.getDescriptionMap();
5060
5061 descriptionMap.put(locale, description);
5062
5063 article.setDescriptionMap(descriptionMap);
5064
5065 content = format(
5066 user, groupId, articleId, article.getVersion(),
5067 !oldArticle.isDraft(), content, oldArticle.getStructureId(),
5068 images);
5069
5070 article.setContent(content);
5071
5072 journalArticlePersistence.update(article);
5073
5074 return article;
5075 }
5076
5077
5090 @Override
5091 public void updateAsset(
5092 long userId, JournalArticle article, long[] assetCategoryIds,
5093 String[] assetTagNames, long[] assetLinkEntryIds)
5094 throws PortalException, SystemException {
5095
5096 boolean visible = article.isApproved();
5097
5098 if (article.getClassNameId() !=
5099 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5100
5101 visible = false;
5102 }
5103
5104 boolean addDraftAssetEntry = false;
5105
5106 if (!article.isApproved() &&
5107 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
5108
5109 int approvedArticlesCount = journalArticlePersistence.countByG_A_ST(
5110 article.getGroupId(), article.getArticleId(),
5111 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
5112
5113 if (approvedArticlesCount > 0) {
5114 addDraftAssetEntry = true;
5115 }
5116 }
5117
5118 AssetEntry assetEntry = null;
5119
5120 if (addDraftAssetEntry) {
5121 assetEntry = assetEntryLocalService.updateEntry(
5122 userId, article.getGroupId(), article.getCreateDate(),
5123 article.getModifiedDate(), JournalArticle.class.getName(),
5124 article.getPrimaryKey(), article.getUuid(),
5125 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
5126 null, null, null, ContentTypes.TEXT_HTML, article.getTitle(),
5127 article.getDescription(), article.getDescription(), null,
5128 article.getLayoutUuid(), 0, 0, null, false);
5129 }
5130 else {
5131 JournalArticleResource journalArticleResource =
5132 journalArticleResourceLocalService.getArticleResource(
5133 article.getResourcePrimKey());
5134
5135 assetEntry = assetEntryLocalService.updateEntry(
5136 userId, article.getGroupId(), article.getCreateDate(),
5137 article.getModifiedDate(), JournalArticle.class.getName(),
5138 journalArticleResource.getResourcePrimKey(),
5139 journalArticleResource.getUuid(), getClassTypeId(article),
5140 assetCategoryIds, assetTagNames, visible, null, null, null,
5141 ContentTypes.TEXT_HTML, article.getTitle(),
5142 article.getDescription(), article.getDescription(), null,
5143 article.getLayoutUuid(), 0, 0, null, false);
5144 }
5145
5146 assetLinkLocalService.updateLinks(
5147 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5148 AssetLinkConstants.TYPE_RELATED);
5149 }
5150
5151
5166 @Indexable(type = IndexableType.REINDEX)
5167 @Override
5168 public JournalArticle updateContent(
5169 long groupId, String articleId, double version, String content)
5170 throws PortalException, SystemException {
5171
5172 JournalArticle article = journalArticlePersistence.findByG_A_V(
5173 groupId, articleId, version);
5174
5175 article.setContent(content);
5176
5177 journalArticlePersistence.update(article);
5178
5179 return article;
5180 }
5181
5182
5205 @Indexable(type = IndexableType.REINDEX)
5206 @Override
5207 public JournalArticle updateStatus(
5208 long userId, JournalArticle article, int status, String articleURL,
5209 Map<String, Serializable> workflowContext,
5210 ServiceContext serviceContext)
5211 throws PortalException, SystemException {
5212
5213
5214
5215 User user = userPersistence.findByPrimaryKey(userId);
5216 Date now = new Date();
5217
5218 if ((status == WorkflowConstants.STATUS_APPROVED) &&
5219 (article.getClassNameId() ==
5220 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5221 (article.getDisplayDate() != null) &&
5222 now.before(article.getDisplayDate())) {
5223
5224 status = WorkflowConstants.STATUS_SCHEDULED;
5225 }
5226
5227 int oldStatus = article.getStatus();
5228
5229 article.setModifiedDate(serviceContext.getModifiedDate(now));
5230
5231 boolean neverExpire = false;
5232
5233 if (status == WorkflowConstants.STATUS_APPROVED) {
5234 Date expirationDate = article.getExpirationDate();
5235
5236 if ((expirationDate != null) && expirationDate.before(now)) {
5237 neverExpire = true;
5238
5239 article.setExpirationDate(null);
5240 }
5241 }
5242
5243 if (status == WorkflowConstants.STATUS_EXPIRED) {
5244 article.setExpirationDate(now);
5245 }
5246
5247 article.setStatus(status);
5248 article.setStatusByUserId(user.getUserId());
5249 article.setStatusByUserName(user.getFullName());
5250 article.setStatusDate(serviceContext.getModifiedDate(now));
5251
5252 journalArticlePersistence.update(article);
5253
5254 if (hasModifiedLatestApprovedVersion(
5255 article.getGroupId(), article.getArticleId(),
5256 article.getVersion())) {
5257
5258 if (status == WorkflowConstants.STATUS_APPROVED) {
5259 updateUrlTitles(
5260 article.getGroupId(), article.getArticleId(),
5261 article.getUrlTitle());
5262
5263
5264
5265 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
5266 (article.getVersion() !=
5267 JournalArticleConstants.VERSION_DEFAULT)) {
5268
5269 AssetEntry draftAssetEntry =
5270 assetEntryLocalService.fetchEntry(
5271 JournalArticle.class.getName(),
5272 article.getPrimaryKey());
5273
5274 if (draftAssetEntry != null) {
5275 long[] assetCategoryIds =
5276 draftAssetEntry.getCategoryIds();
5277 String[] assetTagNames = draftAssetEntry.getTagNames();
5278
5279 List<AssetLink> assetLinks =
5280 assetLinkLocalService.getDirectLinks(
5281 draftAssetEntry.getEntryId(),
5282 AssetLinkConstants.TYPE_RELATED);
5283
5284 long[] assetLinkEntryIds = StringUtil.split(
5285 ListUtil.toString(
5286 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
5287
5288 AssetEntry assetEntry =
5289 assetEntryLocalService.updateEntry(
5290 userId, article.getGroupId(),
5291 article.getCreateDate(),
5292 article.getModifiedDate(),
5293 JournalArticle.class.getName(),
5294 article.getResourcePrimKey(), article.getUuid(),
5295 getClassTypeId(article), assetCategoryIds,
5296 assetTagNames, false, null, null, null,
5297 ContentTypes.TEXT_HTML, article.getTitle(),
5298 article.getDescription(),
5299 article.getDescription(), null,
5300 article.getLayoutUuid(), 0, 0, null, false);
5301
5302 assetLinkLocalService.updateLinks(
5303 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5304 AssetLinkConstants.TYPE_RELATED);
5305
5306 SystemEventHierarchyEntryThreadLocal.push(
5307 JournalArticle.class);
5308
5309 try {
5310 assetEntryLocalService.deleteEntry(
5311 JournalArticle.class.getName(),
5312 article.getPrimaryKey());
5313 }
5314 finally {
5315 SystemEventHierarchyEntryThreadLocal.pop(
5316 JournalArticle.class);
5317 }
5318 }
5319 }
5320
5321 if (article.getClassNameId() ==
5322 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5323
5324
5325
5326
5327 Date[] dateInterval = getDateInterval(
5328 article.getGroupId(), article.getArticleId(),
5329 article.getDisplayDate(), article.getExpirationDate());
5330
5331 Date displayDate = dateInterval[0];
5332 Date expirationDate = dateInterval[1];
5333
5334 if (neverExpire) {
5335 expirationDate = null;
5336 }
5337
5338 assetEntryLocalService.updateEntry(
5339 JournalArticle.class.getName(),
5340 article.getResourcePrimKey(), displayDate,
5341 expirationDate, true);
5342 }
5343
5344
5345
5346 JSONObject extraDataJSONObject =
5347 JSONFactoryUtil.createJSONObject();
5348
5349 extraDataJSONObject.put("title", article.getTitle());
5350
5351 if (serviceContext.isCommandUpdate()) {
5352 socialActivityLocalService.addActivity(
5353 user.getUserId(), article.getGroupId(),
5354 JournalArticle.class.getName(),
5355 article.getResourcePrimKey(),
5356 JournalActivityKeys.UPDATE_ARTICLE,
5357 extraDataJSONObject.toString(), 0);
5358 }
5359 else {
5360 socialActivityLocalService.addUniqueActivity(
5361 user.getUserId(), article.getGroupId(),
5362 JournalArticle.class.getName(),
5363 article.getResourcePrimKey(),
5364 JournalActivityKeys.ADD_ARTICLE,
5365 extraDataJSONObject.toString(), 0);
5366 }
5367 }
5368 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
5369 updatePreviousApprovedArticle(article);
5370 }
5371 }
5372
5373 if ((article.getClassNameId() ==
5374 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5375 (oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
5376 (status != WorkflowConstants.STATUS_IN_TRASH)) {
5377
5378
5379
5380 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
5381 ((status == WorkflowConstants.STATUS_APPROVED) ||
5382 (status == WorkflowConstants.STATUS_DENIED))) {
5383
5384 String msg = "granted";
5385
5386 if (status == WorkflowConstants.STATUS_DENIED) {
5387 msg = "denied";
5388 }
5389
5390 try {
5391 PortletPreferences preferences =
5392 ServiceContextUtil.getPortletPreferences(
5393 serviceContext);
5394
5395 sendEmail(
5396 article, articleURL, preferences, msg, serviceContext);
5397 }
5398 catch (Exception e) {
5399 _log.error(
5400 "Unable to send email to notify the change of status " +
5401 " to " + msg + " for article " + article.getId() +
5402 ": " + e.getMessage());
5403 }
5404 }
5405
5406
5407
5408 notifySubscribers(article, serviceContext);
5409 }
5410
5411 return article;
5412 }
5413
5414
5435 @Override
5436 public JournalArticle updateStatus(
5437 long userId, long classPK, int status,
5438 Map<String, Serializable> workflowContext,
5439 ServiceContext serviceContext)
5440 throws PortalException, SystemException {
5441
5442 JournalArticle article = getArticle(classPK);
5443
5444 return journalArticleLocalService.updateStatus(
5445 userId, article, status, null, workflowContext, serviceContext);
5446 }
5447
5448
5470 @Override
5471 public JournalArticle updateStatus(
5472 long userId, long groupId, String articleId, double version,
5473 int status, String articleURL,
5474 Map<String, Serializable> workflowContext,
5475 ServiceContext serviceContext)
5476 throws PortalException, SystemException {
5477
5478 JournalArticle article = journalArticlePersistence.findByG_A_V(
5479 groupId, articleId, version);
5480
5481 return journalArticleLocalService.updateStatus(
5482 userId, article, status, articleURL, workflowContext,
5483 serviceContext);
5484 }
5485
5486
5501 @Override
5502 public void updateTemplateId(
5503 long groupId, long classNameId, String oldDDMTemplateKey,
5504 String newDDMTemplateKey)
5505 throws SystemException {
5506
5507 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
5508 groupId, classNameId, oldDDMTemplateKey);
5509
5510 for (JournalArticle article : articles) {
5511 article.setTemplateId(newDDMTemplateKey);
5512
5513 journalArticlePersistence.update(article);
5514 }
5515 }
5516
5517 protected void checkArticlesByDisplayDate(Date displayDate)
5518 throws PortalException, SystemException {
5519
5520 List<JournalArticle> articles = journalArticlePersistence.findByLtD_S(
5521 displayDate, WorkflowConstants.STATUS_SCHEDULED);
5522
5523 for (JournalArticle article : articles) {
5524 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5525 JournalArticle.class);
5526
5527 indexer.reindex(article);
5528
5529 ServiceContext serviceContext = new ServiceContext();
5530
5531 serviceContext.setCommand(Constants.UPDATE);
5532
5533 String layoutFullURL = PortalUtil.getLayoutFullURL(
5534 article.getGroupId(), PortletKeys.JOURNAL);
5535
5536 serviceContext.setLayoutFullURL(layoutFullURL);
5537
5538 serviceContext.setScopeGroupId(article.getGroupId());
5539
5540 updateStatus(
5541 article.getUserId(), article, WorkflowConstants.STATUS_APPROVED,
5542 null, new HashMap<String, Serializable>(), serviceContext);
5543 }
5544 }
5545
5546 protected void checkArticlesByExpirationDate(Date expirationDate)
5547 throws PortalException, SystemException {
5548
5549 List<JournalArticle> articles =
5550 journalArticleFinder.findByExpirationDate(
5551 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
5552 new Date(
5553 expirationDate.getTime() + _JOURNAL_ARTICLE_CHECK_INTERVAL),
5554 new QueryDefinition(WorkflowConstants.STATUS_APPROVED));
5555
5556 if (_log.isDebugEnabled()) {
5557 _log.debug("Expiring " + articles.size() + " articles");
5558 }
5559
5560 Set<Long> companyIds = new HashSet<Long>();
5561
5562 for (JournalArticle article : articles) {
5563 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
5564 List<JournalArticle> currentArticles =
5565 journalArticlePersistence.findByG_A(
5566 article.getGroupId(), article.getArticleId(),
5567 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
5568 new ArticleVersionComparator(true));
5569
5570 for (JournalArticle currentArticle : currentArticles) {
5571 currentArticle.setExpirationDate(
5572 article.getExpirationDate());
5573 currentArticle.setStatus(WorkflowConstants.STATUS_EXPIRED);
5574
5575 journalArticlePersistence.update(currentArticle);
5576 }
5577 }
5578 else {
5579 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5580
5581 journalArticlePersistence.update(article);
5582 }
5583
5584 updatePreviousApprovedArticle(article);
5585
5586 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5587 JournalArticle.class);
5588
5589 indexer.reindex(article);
5590
5591 JournalContentUtil.clearCache(
5592 article.getGroupId(), article.getArticleId(),
5593 article.getTemplateId());
5594
5595 companyIds.add(article.getCompanyId());
5596 }
5597
5598 for (long companyId : companyIds) {
5599 CacheUtil.clearCache(companyId);
5600 }
5601
5602 if (_previousCheckDate == null) {
5603 _previousCheckDate = new Date(
5604 expirationDate.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL);
5605 }
5606 }
5607
5608 protected void checkArticlesByReviewDate(Date reviewDate)
5609 throws PortalException, SystemException {
5610
5611 List<JournalArticle> articles = journalArticleFinder.findByReviewDate(
5612 JournalArticleConstants.CLASSNAME_ID_DEFAULT, reviewDate,
5613 _previousCheckDate);
5614
5615 if (_log.isDebugEnabled()) {
5616 _log.debug(
5617 "Sending review notifications for " + articles.size() +
5618 " articles");
5619 }
5620
5621 for (JournalArticle article : articles) {
5622 String articleURL = StringPool.BLANK;
5623
5624 long ownerId = article.getGroupId();
5625 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
5626 long plid = PortletKeys.PREFS_PLID_SHARED;
5627 String portletId = PortletKeys.JOURNAL;
5628
5629 PortletPreferences preferences =
5630 portletPreferencesLocalService.getPreferences(
5631 article.getCompanyId(), ownerId, ownerType, plid,
5632 portletId);
5633
5634 sendEmail(
5635 article, articleURL, preferences, "review",
5636 new ServiceContext());
5637 }
5638 }
5639
5640 protected void checkStructure(Document contentDoc, Element root)
5641 throws PortalException {
5642
5643 for (Element el : root.elements()) {
5644 checkStructureField(el, contentDoc);
5645
5646 checkStructure(contentDoc, el);
5647 }
5648 }
5649
5650 protected void checkStructure(JournalArticle article)
5651 throws PortalException, SystemException {
5652
5653 Group companyGroup = groupLocalService.getCompanyGroup(
5654 article.getCompanyId());
5655
5656 DDMStructure structure = null;
5657
5658 try {
5659 structure = ddmStructurePersistence.findByG_C_S(
5660 PortalUtil.getSiteGroupId(article.getGroupId()),
5661 PortalUtil.getClassNameId(JournalArticle.class),
5662 article.getStructureId());
5663 }
5664 catch (NoSuchStructureException nsse) {
5665 structure = ddmStructurePersistence.findByG_C_S(
5666 companyGroup.getGroupId(),
5667 PortalUtil.getClassNameId(JournalArticle.class),
5668 article.getStructureId());
5669 }
5670
5671 String content = GetterUtil.getString(article.getContent());
5672
5673 try {
5674 Document contentDocument = SAXReaderUtil.read(content);
5675 Document xsdDocument = SAXReaderUtil.read(structure.getXsd());
5676
5677 checkStructure(contentDocument, xsdDocument.getRootElement());
5678 }
5679 catch (DocumentException de) {
5680 throw new SystemException(de);
5681 }
5682 catch (StructureXsdException sxsde) {
5683 long groupId = article.getGroupId();
5684 String articleId = article.getArticleId();
5685 double version = article.getVersion();
5686
5687 if (_log.isWarnEnabled()) {
5688 _log.warn(
5689 "Article {groupId=" + groupId + ", articleId=" +
5690 articleId + ", version=" + version +
5691 "} has content that does not match its " +
5692 "structure: " + sxsde.getMessage());
5693 }
5694 }
5695 }
5696
5697 protected void checkStructureField(Element el, Document contentDoc)
5698 throws PortalException {
5699
5700 StringBuilder elPath = new StringBuilder();
5701
5702 elPath.append(el.attributeValue("name"));
5703
5704 Element elParent = el.getParent();
5705
5706 while (true) {
5707 if ((elParent == null) || elParent.getName().equals("root")) {
5708 break;
5709 }
5710
5711 elPath.insert(
5712 0, elParent.attributeValue("name") + StringPool.COMMA);
5713
5714 elParent = elParent.getParent();
5715 }
5716
5717 String[] elPathNames = StringUtil.split(elPath.toString());
5718
5719 Element contentEl = contentDoc.getRootElement();
5720
5721 for (String _elPathName : elPathNames) {
5722 boolean foundEl = false;
5723
5724 for (Element tempEl : contentEl.elements()) {
5725 if (_elPathName.equals(
5726 tempEl.attributeValue("name", StringPool.BLANK))) {
5727
5728 contentEl = tempEl;
5729 foundEl = true;
5730
5731 break;
5732 }
5733 }
5734
5735 if (!foundEl) {
5736 String elType = contentEl.attributeValue(
5737 "type", StringPool.BLANK);
5738
5739 if (!elType.equals("list") && !elType.equals("multi-list")) {
5740 throw new StructureXsdException(elPath.toString());
5741 }
5742
5743 break;
5744 }
5745 }
5746 }
5747
5748 protected void copyArticleImages(
5749 JournalArticle oldArticle, JournalArticle newArticle)
5750 throws Exception {
5751
5752 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
5753
5754 XPath xPathSelector = SAXReaderUtil.createXPath(
5755 "
5756
5757 List<Node> imageNodes = xPathSelector.selectNodes(contentDoc);
5758
5759 for (Node imageNode : imageNodes) {
5760 Element imageEl = (Element)imageNode;
5761
5762 String instanceId = imageEl.attributeValue("instance-id");
5763 String name = imageEl.attributeValue("name");
5764
5765 List<Element> dynamicContentEls = imageEl.elements(
5766 "dynamic-content");
5767
5768 for (Element dynamicContentEl : dynamicContentEls) {
5769 long imageId = GetterUtil.getLong(
5770 dynamicContentEl.attributeValue("id"));
5771 String languageId = dynamicContentEl.attributeValue(
5772 "language-id");
5773
5774 Image oldImage = null;
5775
5776 try {
5777 oldImage = imageLocalService.getImage(imageId);
5778 }
5779 catch (NoSuchImageException nsie) {
5780 continue;
5781 }
5782
5783 imageId = journalArticleImageLocalService.getArticleImageId(
5784 newArticle.getGroupId(), newArticle.getArticleId(),
5785 newArticle.getVersion(), instanceId, name, languageId);
5786
5787 imageLocalService.updateImage(imageId, oldImage.getTextObj());
5788
5789 String elContent =
5790 "/image/journal/article?img_id=" + imageId + "&t=" +
5791 WebServerServletTokenUtil.getToken(imageId);
5792
5793 dynamicContentEl.setText(elContent);
5794 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
5795 }
5796 }
5797
5798 newArticle.setContent(contentDoc.formattedString());
5799 }
5800
5801 protected void format(
5802 User user, long groupId, String articleId, double version,
5803 boolean incrementVersion, Element root, Map<String, byte[]> images)
5804 throws PortalException, SystemException {
5805
5806 for (Element element : root.elements()) {
5807 String elInstanceId = element.attributeValue(
5808 "instance-id", StringPool.BLANK);
5809 String elType = element.attributeValue("type", StringPool.BLANK);
5810
5811 if (elType.equals("image")) {
5812 String elName = element.attributeValue(
5813 "name", StringPool.BLANK);
5814 String elIndex = element.attributeValue(
5815 "index", StringPool.BLANK);
5816
5817 String name = elName + "_" + elIndex;
5818
5819 formatImage(
5820 groupId, articleId, version, incrementVersion, element,
5821 elInstanceId, name, images);
5822 }
5823 else if (elType.equals("text_area") || elType.equals("text") ||
5824 elType.equals("text_box")) {
5825
5826 List<Element> dynamicContentElements = element.elements(
5827 "dynamic-content");
5828
5829 for (Element dynamicContentElement : dynamicContentElements) {
5830 String dynamicContent = dynamicContentElement.getText();
5831
5832 if (Validator.isNotNull(dynamicContent)) {
5833 String contentType = ContentTypes.TEXT_PLAIN;
5834
5835 if (elType.equals("text_area")) {
5836 contentType = ContentTypes.TEXT_HTML;
5837 }
5838
5839 dynamicContent = SanitizerUtil.sanitize(
5840 user.getCompanyId(), groupId, user.getUserId(),
5841 JournalArticle.class.getName(), 0, contentType,
5842 dynamicContent);
5843
5844 dynamicContentElement.clearContent();
5845
5846 dynamicContentElement.addCDATA(dynamicContent);
5847 }
5848 }
5849 }
5850
5851 format(
5852 user, groupId, articleId, version, incrementVersion, element,
5853 images);
5854 }
5855 }
5856
5857 protected String format(
5858 User user, long groupId, String articleId, double version,
5859 boolean incrementVersion, String content, String ddmStructureKey,
5860 Map<String, byte[]> images)
5861 throws PortalException, SystemException {
5862
5863 Document document = null;
5864
5865 try {
5866 document = SAXReaderUtil.read(content);
5867
5868 Element rootElement = document.getRootElement();
5869
5870 if (Validator.isNotNull(ddmStructureKey)) {
5871 format(
5872 user, groupId, articleId, version, incrementVersion,
5873 rootElement, images);
5874 }
5875 else {
5876 List<Element> staticContentElements = rootElement.elements(
5877 "static-content");
5878
5879 for (Element staticContentElement : staticContentElements) {
5880 String staticContent = staticContentElement.getText();
5881
5882 staticContent = SanitizerUtil.sanitize(
5883 user.getCompanyId(), groupId, user.getUserId(),
5884 JournalArticle.class.getName(), 0,
5885 ContentTypes.TEXT_HTML, staticContent);
5886
5887 staticContentElement.clearContent();
5888
5889 staticContentElement.addCDATA(staticContent);
5890 }
5891 }
5892
5893 content = DDMXMLUtil.formatXML(document);
5894 }
5895 catch (DocumentException de) {
5896 _log.error(de, de);
5897 }
5898
5899 content = HtmlUtil.replaceMsWordCharacters(content);
5900
5901 return content;
5902 }
5903
5904 protected void formatImage(
5905 long groupId, String articleId, double version,
5906 boolean incrementVersion, Element el, String elInstanceId,
5907 String elName, Map<String, byte[]> images)
5908 throws PortalException, SystemException {
5909
5910 List<Element> imageContents = el.elements("dynamic-content");
5911
5912 for (Element dynamicContent : imageContents) {
5913 String elLanguage = dynamicContent.attributeValue(
5914 "language-id", StringPool.BLANK);
5915
5916 if (!elLanguage.equals(StringPool.BLANK)) {
5917 elLanguage = "_" + elLanguage;
5918 }
5919
5920 long imageId = journalArticleImageLocalService.getArticleImageId(
5921 groupId, articleId, version, elInstanceId, elName, elLanguage);
5922
5923 if (dynamicContent.getText().equals("delete") ||
5924 Validator.isNull(dynamicContent.getText())) {
5925
5926 dynamicContent.setText(StringPool.BLANK);
5927
5928 imageLocalService.deleteImage(imageId);
5929
5930 String defaultElLanguage = "";
5931
5932 if (Validator.isNull(elLanguage)) {
5933 defaultElLanguage =
5934 "_" +
5935 LocaleUtil.toLanguageId(
5936 LocaleUtil.getSiteDefault());
5937 }
5938
5939 long defaultImageId =
5940 journalArticleImageLocalService.getArticleImageId(
5941 groupId, articleId, version, elInstanceId, elName,
5942 defaultElLanguage);
5943
5944 imageLocalService.deleteImage(defaultImageId);
5945
5946 continue;
5947 }
5948
5949 String elContent =
5950 "/image/journal/article?img_id=" + imageId + "&t=" +
5951 WebServerServletTokenUtil.getToken(imageId);
5952
5953 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
5954
5955 if (ArrayUtil.isNotEmpty(bytes)) {
5956 dynamicContent.setText(elContent);
5957 dynamicContent.addAttribute("id", String.valueOf(imageId));
5958
5959 imageLocalService.updateImage(imageId, bytes);
5960
5961 continue;
5962 }
5963
5964 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
5965 incrementVersion) {
5966
5967 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
5968
5969 long oldImageId = 0;
5970
5971 if ((oldVersion >= 1) && incrementVersion) {
5972 oldImageId =
5973 journalArticleImageLocalService.getArticleImageId(
5974 groupId, articleId, oldVersion, elInstanceId,
5975 elName, elLanguage);
5976 }
5977
5978 Image oldImage = null;
5979
5980 if (oldImageId > 0) {
5981 oldImage = imageLocalService.getImage(oldImageId);
5982 }
5983
5984 if (oldImage != null) {
5985 dynamicContent.setText(elContent);
5986 dynamicContent.addAttribute("id", String.valueOf(imageId));
5987
5988 bytes = oldImage.getTextObj();
5989
5990 imageLocalService.updateImage(imageId, bytes);
5991 }
5992 else if (dynamicContent.getText().equals("update")) {
5993 dynamicContent.setText(StringPool.BLANK);
5994 }
5995
5996 continue;
5997 }
5998
5999 Image image = imageLocalService.getImage(imageId);
6000
6001 if (image != null) {
6002 dynamicContent.setText(elContent);
6003 dynamicContent.addAttribute("id", String.valueOf(imageId));
6004
6005 continue;
6006 }
6007 else if (dynamicContent.getText().equals("update")) {
6008 dynamicContent.setText(StringPool.BLANK);
6009
6010 continue;
6011 }
6012
6013 long contentImageId = GetterUtil.getLong(
6014 HttpUtil.getParameter(dynamicContent.getText(), "img_id"));
6015
6016 if (contentImageId <= 0) {
6017 contentImageId = GetterUtil.getLong(
6018 HttpUtil.getParameter(
6019 dynamicContent.getText(), "img_id", false));
6020 }
6021
6022 if (contentImageId > 0) {
6023 image = imageLocalService.getImage(contentImageId);
6024
6025 if (image != null) {
6026 dynamicContent.addAttribute(
6027 "id", String.valueOf(contentImageId));
6028
6029 continue;
6030 }
6031 }
6032
6033 String defaultElLanguage = "";
6034
6035 if (Validator.isNull(elLanguage)) {
6036 defaultElLanguage =
6037 "_" + LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
6038 }
6039
6040 long defaultImageId =
6041 journalArticleImageLocalService.getArticleImageId(
6042 groupId, articleId, version, elInstanceId, elName,
6043 defaultElLanguage);
6044
6045 Image defaultImage = imageLocalService.getImage(defaultImageId);
6046
6047 if (defaultImage != null) {
6048 dynamicContent.setText(elContent);
6049 dynamicContent.addAttribute(
6050 "id", String.valueOf(defaultImageId));
6051
6052 bytes = defaultImage.getTextObj();
6053
6054 imageLocalService.updateImage(defaultImageId, bytes);
6055
6056 continue;
6057 }
6058
6059 if (Validator.isNotNull(elLanguage)) {
6060 dynamicContent.setText(StringPool.BLANK);
6061 }
6062 }
6063 }
6064
6065 protected List<ObjectValuePair<Long, Integer>> getArticleVersionStatuses(
6066 List<JournalArticle> articles) {
6067
6068 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
6069 new ArrayList<ObjectValuePair<Long, Integer>>(articles.size());
6070
6071 for (JournalArticle article : articles) {
6072 int status = article.getStatus();
6073
6074 if (status == WorkflowConstants.STATUS_PENDING) {
6075 status = WorkflowConstants.STATUS_DRAFT;
6076 }
6077
6078 ObjectValuePair<Long, Integer> articleVersionStatusOVP =
6079 new ObjectValuePair<Long, Integer>(article.getId(), status);
6080
6081 articleVersionStatusOVPs.add(articleVersionStatusOVP);
6082 }
6083
6084 return articleVersionStatusOVPs;
6085 }
6086
6087 protected long getClassTypeId(JournalArticle article) {
6088 long classTypeId = 0;
6089
6090 try {
6091 long classNameId = PortalUtil.getClassNameId(JournalArticle.class);
6092
6093 DDMStructure ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6094 article.getGroupId(), classNameId, article.getStructureId());
6095
6096 if (ddmStructure == null) {
6097 Group companyGroup = groupLocalService.getCompanyGroup(
6098 article.getCompanyId());
6099
6100 ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6101 companyGroup.getGroupId(), classNameId,
6102 article.getStructureId());
6103 }
6104
6105 if (ddmStructure != null) {
6106 classTypeId = ddmStructure.getStructureId();
6107 }
6108 }
6109 catch (Exception e) {
6110 _log.error(e, e);
6111 }
6112
6113 return classTypeId;
6114 }
6115
6116 protected Date[] getDateInterval(
6117 long groupId, String articleId, Date earliestDisplayDate,
6118 Date latestExpirationDate)
6119 throws SystemException {
6120
6121 Date[] dateInterval = new Date[2];
6122
6123 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
6124 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6125
6126 boolean expiringArticle = true;
6127
6128 if (latestExpirationDate == null) {
6129 expiringArticle = false;
6130 }
6131
6132 for (JournalArticle article : articles) {
6133 if ((earliestDisplayDate == null) ||
6134 ((article.getDisplayDate() != null) &&
6135 earliestDisplayDate.after(article.getDisplayDate()))) {
6136
6137 earliestDisplayDate = article.getDisplayDate();
6138 }
6139
6140 if (expiringArticle &&
6141 ((latestExpirationDate == null) ||
6142 ((article.getExpirationDate() != null) &&
6143 latestExpirationDate.before(article.getExpirationDate())))) {
6144
6145 latestExpirationDate = article.getExpirationDate();
6146 }
6147
6148 if (expiringArticle && (article.getExpirationDate() == null) &&
6149 (latestExpirationDate != null)) {
6150
6151 expiringArticle = false;
6152 }
6153 }
6154
6155 dateInterval[0] = earliestDisplayDate;
6156 dateInterval[1] = latestExpirationDate;
6157
6158 return dateInterval;
6159 }
6160
6161 protected String getUniqueUrlTitle(
6162 long id, long groupId, String articleId, String title)
6163 throws PortalException, SystemException {
6164
6165 String urlTitle = JournalUtil.getUrlTitle(id, title);
6166
6167 return getUniqueUrlTitle(groupId, articleId, urlTitle);
6168 }
6169
6170 protected String getUniqueUrlTitle(
6171 long id, String articleId, String title, String oldUrlTitle,
6172 ServiceContext serviceContext)
6173 throws PortalException, SystemException {
6174
6175 String serviceContextUrlTitle = ParamUtil.getString(
6176 serviceContext, "urlTitle");
6177
6178 String urlTitle = null;
6179
6180 if (Validator.isNotNull(serviceContextUrlTitle)) {
6181 urlTitle = JournalUtil.getUrlTitle(id, serviceContextUrlTitle);
6182 }
6183 else if (Validator.isNotNull(oldUrlTitle)) {
6184 return oldUrlTitle;
6185 }
6186 else {
6187 urlTitle = getUniqueUrlTitle(
6188 id, serviceContext.getScopeGroupId(), articleId, title);
6189 }
6190
6191 JournalArticle urlTitleArticle = null;
6192
6193 try {
6194 urlTitleArticle = getArticleByUrlTitle(
6195 serviceContext.getScopeGroupId(), urlTitle);
6196 }
6197 catch (NoSuchArticleException nsae) {
6198 }
6199
6200 if ((urlTitleArticle != null) &&
6201 !Validator.equals(
6202 urlTitleArticle.getArticleId(), articleId)) {
6203
6204 urlTitle = getUniqueUrlTitle(
6205 id, serviceContext.getScopeGroupId(), articleId, urlTitle);
6206 }
6207
6208 return urlTitle;
6209 }
6210
6211 protected boolean hasModifiedLatestApprovedVersion(
6212 long groupId, String articleId, double version)
6213 throws PortalException, SystemException {
6214
6215 double latestApprovedVersion;
6216
6217 try {
6218 latestApprovedVersion = getLatestVersion(
6219 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6220
6221 if (version >= latestApprovedVersion) {
6222 return true;
6223 }
6224 else {
6225 return false;
6226 }
6227 }
6228 catch (NoSuchArticleException nsae) {
6229 return true;
6230 }
6231 }
6232
6233 protected void notifySubscribers(
6234 JournalArticle article, ServiceContext serviceContext)
6235 throws PortalException, SystemException {
6236
6237 if (!article.isApproved()) {
6238 return;
6239 }
6240
6241 String articleURL = PortalUtil.getControlPanelFullURL(
6242 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
6243
6244 if (Validator.isNull(articleURL)) {
6245 return;
6246 }
6247
6248 PortletPreferences preferences =
6249 ServiceContextUtil.getPortletPreferences(serviceContext);
6250
6251 if (preferences == null) {
6252 long ownerId = article.getGroupId();
6253 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
6254 long plid = PortletKeys.PREFS_PLID_SHARED;
6255 String portletId = PortletKeys.JOURNAL;
6256 String defaultPreferences = null;
6257
6258 preferences = portletPreferencesLocalService.getPreferences(
6259 article.getCompanyId(), ownerId, ownerType, plid, portletId,
6260 defaultPreferences);
6261 }
6262
6263 if ((article.getVersion() == 1.0) &&
6264 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
6265 }
6266 else if ((article.getVersion() != 1.0) &&
6267 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
6268 }
6269 else {
6270 return;
6271 }
6272
6273 String fromName = JournalUtil.getEmailFromName(
6274 preferences, article.getCompanyId());
6275 String fromAddress = JournalUtil.getEmailFromAddress(
6276 preferences, article.getCompanyId());
6277
6278 String subject = null;
6279 String body = null;
6280
6281 if (article.getVersion() == 1.0) {
6282 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
6283 body = JournalUtil.getEmailArticleAddedBody(preferences);
6284 }
6285 else {
6286 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
6287 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
6288 }
6289
6290 SubscriptionSender subscriptionSender = new SubscriptionSender();
6291
6292 subscriptionSender.setBody(body);
6293 subscriptionSender.setCompanyId(article.getCompanyId());
6294 subscriptionSender.setContextAttributes(
6295 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6296 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6297 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
6298 subscriptionSender.setContextUserPrefix("ARTICLE");
6299 subscriptionSender.setFrom(fromAddress, fromName);
6300 subscriptionSender.setHtmlFormat(true);
6301 subscriptionSender.setMailId("journal_article", article.getId());
6302 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6303 subscriptionSender.setReplyToAddress(fromAddress);
6304 subscriptionSender.setScopeGroupId(article.getGroupId());
6305 subscriptionSender.setServiceContext(serviceContext);
6306 subscriptionSender.setSubject(subject);
6307 subscriptionSender.setUserId(article.getUserId());
6308
6309 subscriptionSender.addPersistedSubscribers(
6310 JournalArticle.class.getName(), article.getResourcePrimKey());
6311
6312 JournalFolder folder = article.getFolder();
6313
6314 List<Long> folderIds = new ArrayList<Long>();
6315
6316 if (folder != null) {
6317 folderIds.add(folder.getFolderId());
6318
6319 folderIds.addAll(folder.getAncestorFolderIds());
6320 }
6321
6322 for (long curFolderId : folderIds) {
6323 subscriptionSender.addPersistedSubscribers(
6324 JournalFolder.class.getName(), curFolderId);
6325 }
6326
6327 subscriptionSender.addPersistedSubscribers(
6328 JournalArticle.class.getName(), article.getGroupId());
6329
6330 subscriptionSender.flushNotificationsAsync();
6331 }
6332
6333 protected void saveImages(
6334 boolean smallImage, long smallImageId, File smallImageFile,
6335 byte[] smallImageBytes)
6336 throws PortalException, SystemException {
6337
6338 if (smallImage) {
6339 if ((smallImageFile != null) && (smallImageBytes != null)) {
6340 imageLocalService.updateImage(smallImageId, smallImageBytes);
6341 }
6342 }
6343 else {
6344 imageLocalService.deleteImage(smallImageId);
6345 }
6346 }
6347
6348 protected void sendEmail(
6349 JournalArticle article, String articleURL,
6350 PortletPreferences preferences, String emailType,
6351 ServiceContext serviceContext)
6352 throws PortalException, SystemException {
6353
6354 if (preferences == null) {
6355 return;
6356 }
6357 else if (emailType.equals("denied") &&
6358 JournalUtil.getEmailArticleApprovalDeniedEnabled(
6359 preferences)) {
6360 }
6361 else if (emailType.equals("granted") &&
6362 JournalUtil.getEmailArticleApprovalGrantedEnabled(
6363 preferences)) {
6364 }
6365 else if (emailType.equals("requested") &&
6366 JournalUtil.getEmailArticleApprovalRequestedEnabled(
6367 preferences)) {
6368 }
6369 else if (emailType.equals("review") &&
6370 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
6371 }
6372 else {
6373 return;
6374 }
6375
6376 Company company = companyPersistence.findByPrimaryKey(
6377 article.getCompanyId());
6378
6379 User user = userPersistence.findByPrimaryKey(article.getUserId());
6380
6381 articleURL +=
6382 "&groupId=" + article.getGroupId() + "&articleId=" +
6383 article.getArticleId() + "&version=" + article.getVersion();
6384
6385 String fromName = JournalUtil.getEmailFromName(
6386 preferences, article.getCompanyId());
6387 String fromAddress = JournalUtil.getEmailFromAddress(
6388 preferences, article.getCompanyId());
6389
6390 String toName = user.getFullName();
6391 String toAddress = user.getEmailAddress();
6392
6393 if (emailType.equals("requested")) {
6394 String tempToName = fromName;
6395 String tempToAddress = fromAddress;
6396
6397 fromName = toName;
6398 fromAddress = toAddress;
6399
6400 toName = tempToName;
6401 toAddress = tempToAddress;
6402 }
6403
6404 String subject = null;
6405 String body = null;
6406
6407 if (emailType.equals("denied")) {
6408 subject = JournalUtil.getEmailArticleApprovalDeniedSubject(
6409 preferences);
6410 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
6411 }
6412 else if (emailType.equals("granted")) {
6413 subject = JournalUtil.getEmailArticleApprovalGrantedSubject(
6414 preferences);
6415 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
6416 }
6417 else if (emailType.equals("requested")) {
6418 subject = JournalUtil.getEmailArticleApprovalRequestedSubject(
6419 preferences);
6420 body = JournalUtil.getEmailArticleApprovalRequestedBody(
6421 preferences);
6422 }
6423 else if (emailType.equals("review")) {
6424 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
6425 body = JournalUtil.getEmailArticleReviewBody(preferences);
6426 }
6427
6428 SubscriptionSender subscriptionSender = new SubscriptionSender();
6429
6430 subscriptionSender.setBody(body);
6431 subscriptionSender.setCompanyId(company.getCompanyId());
6432 subscriptionSender.setContextAttributes(
6433 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6434 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6435 articleURL, "[$ARTICLE_USER_NAME$]", article.getUserName(),
6436 "[$ARTICLE_VERSION$]", article.getVersion());
6437 subscriptionSender.setContextUserPrefix("ARTICLE");
6438 subscriptionSender.setFrom(fromAddress, fromName);
6439 subscriptionSender.setHtmlFormat(true);
6440 subscriptionSender.setMailId("journal_article", article.getId());
6441 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6442 subscriptionSender.setScopeGroupId(article.getGroupId());
6443 subscriptionSender.setServiceContext(serviceContext);
6444 subscriptionSender.setSubject(subject);
6445 subscriptionSender.setUserId(article.getUserId());
6446
6447 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
6448
6449 subscriptionSender.flushNotificationsAsync();
6450 }
6451
6452 protected void updateDDMStructureXSD(
6453 long ddmStructureId, String content, ServiceContext serviceContext)
6454 throws PortalException, SystemException {
6455
6456 try {
6457 Document document = SAXReaderUtil.read(content);
6458
6459 Element rootElement = document.getRootElement();
6460
6461 List<Element> elements = rootElement.elements();
6462
6463 for (Element element : elements) {
6464 String fieldName = element.attributeValue(
6465 "name", StringPool.BLANK);
6466
6467 List<Element> dynamicContentElements = element.elements(
6468 "dynamic-content");
6469
6470 for (Element dynamicContentElement : dynamicContentElements) {
6471 String value = dynamicContentElement.getText();
6472
6473 ddmStructureLocalService.updateXSDFieldMetadata(
6474 ddmStructureId, fieldName,
6475 FieldConstants.PREDEFINED_VALUE, value, serviceContext);
6476 }
6477 }
6478 }
6479 catch (DocumentException de) {
6480 throw new SystemException(de);
6481 }
6482 }
6483
6484 protected void updatePreviousApprovedArticle(JournalArticle article)
6485 throws PortalException, SystemException {
6486
6487 List<JournalArticle> approvedArticles =
6488 journalArticlePersistence.findByG_A_ST(
6489 article.getGroupId(), article.getArticleId(),
6490 WorkflowConstants.STATUS_APPROVED, 0, 2);
6491
6492 if (approvedArticles.isEmpty() ||
6493 ((approvedArticles.size() == 1) &&
6494 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
6495
6496 assetEntryLocalService.updateVisible(
6497 JournalArticle.class.getName(), article.getResourcePrimKey(),
6498 false);
6499 }
6500 else {
6501 JournalArticle previousApprovedArticle = approvedArticles.get(0);
6502
6503 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
6504 previousApprovedArticle = approvedArticles.get(1);
6505 }
6506
6507 Date[] dateInterval = getDateInterval(
6508 previousApprovedArticle.getGroupId(),
6509 previousApprovedArticle.getArticleId(),
6510 previousApprovedArticle.getDisplayDate(),
6511 previousApprovedArticle.getExpirationDate());
6512
6513 Date displayDate = dateInterval[0];
6514 Date expirationDate = dateInterval[1];
6515
6516 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
6517 JournalArticle.class.getName(), article.getResourcePrimKey(),
6518 displayDate, expirationDate, true);
6519
6520 assetEntry.setModifiedDate(
6521 previousApprovedArticle.getModifiedDate());
6522 assetEntry.setTitle(previousApprovedArticle.getTitle());
6523
6524 assetEntryPersistence.update(assetEntry);
6525 }
6526 }
6527
6528 protected void updateUrlTitles(
6529 long groupId, String articleId, String urlTitle)
6530 throws SystemException {
6531
6532 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
6533 groupId, articleId);
6534
6535 for (JournalArticle article : articles) {
6536 if (!article.getUrlTitle().equals(urlTitle)) {
6537 article.setUrlTitle(urlTitle);
6538
6539 journalArticlePersistence.update(article);
6540 }
6541 }
6542 }
6543
6544 protected void validate(
6545 long companyId, long groupId, long classNameId,
6546 Map<Locale, String> titleMap, String content, String type,
6547 String ddmStructureKey, String ddmTemplateKey, Date expirationDate,
6548 boolean smallImage, String smallImageURL, File smallImageFile,
6549 byte[] smallImageBytes)
6550 throws PortalException, SystemException {
6551
6552 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
6553 LocalizationUtil.getDefaultLanguageId(content));
6554
6555 Locale[] availableLocales = LanguageUtil.getAvailableLocales(groupId);
6556
6557 if (!ArrayUtil.contains(availableLocales, articleDefaultLocale)) {
6558 LocaleException le = new LocaleException(
6559 LocaleException.TYPE_CONTENT,
6560 "The locale " + articleDefaultLocale +
6561 " is not available in site with groupId" + groupId);
6562
6563 Locale[] sourceAvailableLocales = {articleDefaultLocale};
6564
6565 le.setSourceAvailableLocales(sourceAvailableLocales);
6566 le.setTargetAvailableLocales(availableLocales);
6567
6568 throw le;
6569 }
6570
6571 if ((classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
6572 (titleMap.isEmpty() ||
6573 Validator.isNull(titleMap.get(articleDefaultLocale)))) {
6574
6575 throw new ArticleTitleException();
6576 }
6577 else if (Validator.isNull(type)) {
6578 throw new ArticleTypeException();
6579 }
6580
6581 validateContent(content);
6582
6583 if (Validator.isNotNull(ddmStructureKey)) {
6584 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
6585 PortalUtil.getSiteGroupId(groupId),
6586 PortalUtil.getClassNameId(JournalArticle.class),
6587 ddmStructureKey, true);
6588
6589 if (Validator.isNotNull(ddmTemplateKey)) {
6590 DDMTemplate ddmTemplate = ddmTemplateLocalService.getTemplate(
6591 PortalUtil.getSiteGroupId(groupId),
6592 PortalUtil.getClassNameId(DDMStructure.class),
6593 ddmTemplateKey, true);
6594
6595 if (ddmTemplate.getClassPK() != ddmStructure.getStructureId()) {
6596 throw new NoSuchTemplateException();
6597 }
6598 }
6599 else if (classNameId ==
6600 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
6601
6602 throw new NoSuchTemplateException();
6603 }
6604 }
6605
6606 if ((expirationDate != null) && expirationDate.before(new Date()) &&
6607 !ExportImportThreadLocal.isImportInProcess()) {
6608
6609 throw new ArticleExpirationDateException();
6610 }
6611
6612 String[] imageExtensions = PrefsPropsUtil.getStringArray(
6613 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
6614
6615 if (!smallImage || Validator.isNotNull(smallImageURL) ||
6616 (smallImageFile == null) || (smallImageBytes == null)) {
6617
6618 return;
6619 }
6620
6621 String smallImageName = smallImageFile.getName();
6622
6623 if (smallImageName != null) {
6624 boolean validSmallImageExtension = false;
6625
6626 for (String _imageExtension : imageExtensions) {
6627 if (StringPool.STAR.equals(_imageExtension) ||
6628 StringUtil.endsWith(smallImageName, _imageExtension)) {
6629
6630 validSmallImageExtension = true;
6631
6632 break;
6633 }
6634 }
6635
6636 if (!validSmallImageExtension) {
6637 throw new ArticleSmallImageNameException(smallImageName);
6638 }
6639 }
6640
6641 long smallImageMaxSize = PrefsPropsUtil.getLong(
6642 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
6643
6644 if ((smallImageMaxSize > 0) &&
6645 ((smallImageBytes == null) ||
6646 (smallImageBytes.length > smallImageMaxSize))) {
6647
6648 throw new ArticleSmallImageSizeException();
6649 }
6650 }
6651
6652 protected void validate(
6653 long companyId, long groupId, long classNameId, String articleId,
6654 boolean autoArticleId, double version, Map<Locale, String> titleMap,
6655 String content, String type, String ddmStructureKey,
6656 String ddmTemplateKey, Date expirationDate, boolean smallImage,
6657 String smallImageURL, File smallImageFile, byte[] smallImageBytes)
6658 throws PortalException, SystemException {
6659
6660 if (!autoArticleId) {
6661 validate(articleId);
6662 }
6663
6664 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
6665 groupId, articleId, version);
6666
6667 if (article != null) {
6668 throw new DuplicateArticleIdException();
6669 }
6670
6671 validate(
6672 companyId, groupId, classNameId, titleMap, content, type,
6673 ddmStructureKey, ddmTemplateKey, expirationDate, smallImage,
6674 smallImageURL, smallImageFile, smallImageBytes);
6675 }
6676
6677 protected void validate(String articleId) throws PortalException {
6678 if (Validator.isNull(articleId) ||
6679 (articleId.indexOf(CharPool.COMMA) != -1) ||
6680 (articleId.indexOf(CharPool.SPACE) != -1)) {
6681
6682 throw new ArticleIdException();
6683 }
6684 }
6685
6686 protected void validateContent(String content) throws PortalException {
6687 if (Validator.isNull(content)) {
6688 throw new ArticleContentException("Content is null");
6689 }
6690
6691 try {
6692 SAXReaderUtil.read(content);
6693 }
6694 catch (DocumentException de) {
6695 if (_log.isDebugEnabled()) {
6696 _log.debug("Invalid content:\n" + content);
6697 }
6698
6699 throw new ArticleContentException(
6700 "Unable to read content with an XML parser", de);
6701 }
6702 }
6703
6704 private static final long _JOURNAL_ARTICLE_CHECK_INTERVAL =
6705 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
6706
6707 private static Log _log = LogFactoryUtil.getLog(
6708 JournalArticleLocalServiceImpl.class);
6709
6710 private Date _previousCheckDate;
6711
6712 }