001
014
015 package com.liferay.portlet.journal.service.impl;
016
017 import com.liferay.portal.LocaleException;
018 import com.liferay.portal.kernel.comment.CommentManagerUtil;
019 import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
020 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
021 import com.liferay.portal.kernel.dao.orm.Property;
022 import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
023 import com.liferay.portal.kernel.dao.orm.QueryDefinition;
024 import com.liferay.portal.kernel.dao.orm.QueryUtil;
025 import com.liferay.portal.kernel.diff.DiffHtmlUtil;
026 import com.liferay.portal.kernel.exception.PortalException;
027 import com.liferay.portal.kernel.exception.SystemException;
028 import com.liferay.portal.kernel.json.JSONFactoryUtil;
029 import com.liferay.portal.kernel.json.JSONObject;
030 import com.liferay.portal.kernel.language.LanguageUtil;
031 import com.liferay.portal.kernel.log.Log;
032 import com.liferay.portal.kernel.log.LogFactoryUtil;
033 import com.liferay.portal.kernel.notifications.UserNotificationDefinition;
034 import com.liferay.portal.kernel.portlet.PortletProvider;
035 import com.liferay.portal.kernel.portlet.PortletProviderUtil;
036 import com.liferay.portal.kernel.portlet.PortletRequestModel;
037 import com.liferay.portal.kernel.repository.model.FileEntry;
038 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
039 import com.liferay.portal.kernel.search.BaseModelSearchResult;
040 import com.liferay.portal.kernel.search.Field;
041 import com.liferay.portal.kernel.search.Hits;
042 import com.liferay.portal.kernel.search.Indexable;
043 import com.liferay.portal.kernel.search.IndexableType;
044 import com.liferay.portal.kernel.search.Indexer;
045 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
046 import com.liferay.portal.kernel.search.QueryConfig;
047 import com.liferay.portal.kernel.search.SearchContext;
048 import com.liferay.portal.kernel.search.SearchException;
049 import com.liferay.portal.kernel.search.Sort;
050 import com.liferay.portal.kernel.systemevent.SystemEvent;
051 import com.liferay.portal.kernel.systemevent.SystemEventHierarchyEntryThreadLocal;
052 import com.liferay.portal.kernel.template.TemplateConstants;
053 import com.liferay.portal.kernel.util.ArrayUtil;
054 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
055 import com.liferay.portal.kernel.util.CharPool;
056 import com.liferay.portal.kernel.util.Constants;
057 import com.liferay.portal.kernel.util.ContentTypes;
058 import com.liferay.portal.kernel.util.FileUtil;
059 import com.liferay.portal.kernel.util.GetterUtil;
060 import com.liferay.portal.kernel.util.HtmlUtil;
061 import com.liferay.portal.kernel.util.HttpUtil;
062 import com.liferay.portal.kernel.util.ListUtil;
063 import com.liferay.portal.kernel.util.LocaleUtil;
064 import com.liferay.portal.kernel.util.LocalizationUtil;
065 import com.liferay.portal.kernel.util.MathUtil;
066 import com.liferay.portal.kernel.util.ObjectValuePair;
067 import com.liferay.portal.kernel.util.OrderByComparator;
068 import com.liferay.portal.kernel.util.ParamUtil;
069 import com.liferay.portal.kernel.util.PropsKeys;
070 import com.liferay.portal.kernel.util.StringBundler;
071 import com.liferay.portal.kernel.util.StringPool;
072 import com.liferay.portal.kernel.util.StringUtil;
073 import com.liferay.portal.kernel.util.Time;
074 import com.liferay.portal.kernel.util.UnicodeProperties;
075 import com.liferay.portal.kernel.util.Validator;
076 import com.liferay.portal.kernel.workflow.WorkflowConstants;
077 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
078 import com.liferay.portal.kernel.xml.Document;
079 import com.liferay.portal.kernel.xml.DocumentException;
080 import com.liferay.portal.kernel.xml.Element;
081 import com.liferay.portal.kernel.xml.Node;
082 import com.liferay.portal.kernel.xml.SAXReaderUtil;
083 import com.liferay.portal.kernel.xml.XPath;
084 import com.liferay.portal.model.Company;
085 import com.liferay.portal.model.Group;
086 import com.liferay.portal.model.Image;
087 import com.liferay.portal.model.ResourceConstants;
088 import com.liferay.portal.model.SystemEventConstants;
089 import com.liferay.portal.model.User;
090 import com.liferay.portal.service.ServiceContext;
091 import com.liferay.portal.service.ServiceContextUtil;
092 import com.liferay.portal.servlet.filters.cache.CacheUtil;
093 import com.liferay.portal.theme.ThemeDisplay;
094 import com.liferay.portal.util.GroupSubscriptionCheckSubscriptionSender;
095 import com.liferay.portal.util.PortalUtil;
096 import com.liferay.portal.util.PortletKeys;
097 import com.liferay.portal.util.PrefsPropsUtil;
098 import com.liferay.portal.util.PropsValues;
099 import com.liferay.portal.util.SubscriptionSender;
100 import com.liferay.portal.webserver.WebServerServletTokenUtil;
101 import com.liferay.portlet.asset.model.AssetEntry;
102 import com.liferay.portlet.asset.model.AssetLink;
103 import com.liferay.portlet.asset.model.AssetLinkConstants;
104 import com.liferay.portlet.documentlibrary.util.DLUtil;
105 import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
106 import com.liferay.portlet.dynamicdatamapping.StorageFieldNameException;
107 import com.liferay.portlet.dynamicdatamapping.StorageFieldRequiredException;
108 import com.liferay.portlet.dynamicdatamapping.StructureDefinitionException;
109 import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
110 import com.liferay.portlet.dynamicdatamapping.model.DDMFormField;
111 import com.liferay.portlet.dynamicdatamapping.model.DDMStorageLink;
112 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
113 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
114 import com.liferay.portlet.dynamicdatamapping.model.LocalizedValue;
115 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
116 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
117 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
118 import com.liferay.portlet.expando.util.ExpandoBridgeUtil;
119 import com.liferay.portlet.exportimport.lar.ExportImportThreadLocal;
120 import com.liferay.portlet.journal.ArticleContentException;
121 import com.liferay.portlet.journal.ArticleDisplayDateException;
122 import com.liferay.portlet.journal.ArticleExpirationDateException;
123 import com.liferay.portlet.journal.ArticleIdException;
124 import com.liferay.portlet.journal.ArticleReviewDateException;
125 import com.liferay.portlet.journal.ArticleSmallImageNameException;
126 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
127 import com.liferay.portlet.journal.ArticleTitleException;
128 import com.liferay.portlet.journal.ArticleVersionException;
129 import com.liferay.portlet.journal.DuplicateArticleIdException;
130 import com.liferay.portlet.journal.InvalidDDMStructureException;
131 import com.liferay.portlet.journal.NoSuchArticleException;
132 import com.liferay.portlet.journal.model.JournalArticle;
133 import com.liferay.portlet.journal.model.JournalArticleConstants;
134 import com.liferay.portlet.journal.model.JournalArticleDisplay;
135 import com.liferay.portlet.journal.model.JournalArticleResource;
136 import com.liferay.portlet.journal.model.JournalFolder;
137 import com.liferay.portlet.journal.model.impl.JournalArticleDisplayImpl;
138 import com.liferay.portlet.journal.service.base.JournalArticleLocalServiceBaseImpl;
139 import com.liferay.portlet.journal.service.permission.JournalPermission;
140 import com.liferay.portlet.journal.social.JournalActivityKeys;
141 import com.liferay.portlet.journal.util.JournalContentUtil;
142 import com.liferay.portlet.journal.util.JournalUtil;
143 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
144 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
145 import com.liferay.portlet.social.model.SocialActivityConstants;
146 import com.liferay.portlet.trash.model.TrashEntry;
147 import com.liferay.portlet.trash.model.TrashVersion;
148 import com.liferay.portlet.trash.util.TrashUtil;
149
150 import java.io.File;
151 import java.io.IOException;
152 import java.io.Serializable;
153
154 import java.util.ArrayList;
155 import java.util.Calendar;
156 import java.util.Collections;
157 import java.util.Date;
158 import java.util.HashMap;
159 import java.util.HashSet;
160 import java.util.LinkedHashMap;
161 import java.util.List;
162 import java.util.Locale;
163 import java.util.Map;
164 import java.util.Set;
165
166 import javax.portlet.PortletPreferences;
167
168
178 public class JournalArticleLocalServiceImpl
179 extends JournalArticleLocalServiceBaseImpl {
180
181
275 @Indexable(type = IndexableType.REINDEX)
276 @Override
277 public JournalArticle addArticle(
278 long userId, long groupId, long folderId, long classNameId,
279 long classPK, String articleId, boolean autoArticleId,
280 double version, Map<Locale, String> titleMap,
281 Map<Locale, String> descriptionMap, String content,
282 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
283 int displayDateMonth, int displayDateDay, int displayDateYear,
284 int displayDateHour, int displayDateMinute, int expirationDateMonth,
285 int expirationDateDay, int expirationDateYear,
286 int expirationDateHour, int expirationDateMinute,
287 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
288 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
289 boolean neverReview, boolean indexable, boolean smallImage,
290 String smallImageURL, File smallImageFile,
291 Map<String, byte[]> images, String articleURL,
292 ServiceContext serviceContext)
293 throws PortalException {
294
295
296
297 User user = userPersistence.findByPrimaryKey(userId);
298 articleId = StringUtil.toUpperCase(articleId.trim());
299
300 Date displayDate = null;
301 Date expirationDate = null;
302 Date reviewDate = null;
303
304 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
305 displayDate = PortalUtil.getDate(
306 displayDateMonth, displayDateDay, displayDateYear,
307 displayDateHour, displayDateMinute, user.getTimeZone(),
308 ArticleDisplayDateException.class);
309
310 if (!neverExpire) {
311 expirationDate = PortalUtil.getDate(
312 expirationDateMonth, expirationDateDay, expirationDateYear,
313 expirationDateHour, expirationDateMinute,
314 user.getTimeZone(), ArticleExpirationDateException.class);
315 }
316
317 if (!neverReview) {
318 reviewDate = PortalUtil.getDate(
319 reviewDateMonth, reviewDateDay, reviewDateYear,
320 reviewDateHour, reviewDateMinute, user.getTimeZone(),
321 ArticleReviewDateException.class);
322 }
323 }
324
325 byte[] smallImageBytes = null;
326
327 try {
328 smallImageBytes = FileUtil.getBytes(smallImageFile);
329 }
330 catch (IOException ioe) {
331 }
332
333 Date now = new Date();
334
335 validateDDMStructureId(groupId, folderId, ddmStructureKey);
336
337 if (autoArticleId) {
338 articleId = String.valueOf(counterLocalService.increment());
339 }
340
341 validate(
342 user.getCompanyId(), groupId, classNameId, articleId, autoArticleId,
343 version, titleMap, content, ddmStructureKey, ddmTemplateKey,
344 expirationDate, smallImage, smallImageURL, smallImageFile,
345 smallImageBytes, serviceContext);
346
347 serviceContext.setAttribute("articleId", articleId);
348
349 long id = counterLocalService.increment();
350
351 String articleResourceUuid = GetterUtil.getString(
352 serviceContext.getAttribute("articleResourceUuid"));
353
354 long resourcePrimKey =
355 journalArticleResourceLocalService.getArticleResourcePrimKey(
356 articleResourceUuid, groupId, articleId);
357
358 JournalArticle article = journalArticlePersistence.create(id);
359
360 Locale locale = getArticleDefaultLocale(content);
361
362 String title = titleMap.get(locale);
363
364 content = format(
365 user, groupId, articleId, version, false, content, images);
366
367 article.setUuid(serviceContext.getUuid());
368 article.setResourcePrimKey(resourcePrimKey);
369 article.setGroupId(groupId);
370 article.setCompanyId(user.getCompanyId());
371 article.setUserId(user.getUserId());
372 article.setUserName(user.getFullName());
373 article.setFolderId(folderId);
374 article.setClassNameId(classNameId);
375 article.setClassPK(classPK);
376 article.setTreePath(article.buildTreePath());
377 article.setArticleId(articleId);
378 article.setVersion(version);
379 article.setTitleMap(titleMap, locale);
380 article.setUrlTitle(
381 getUniqueUrlTitle(
382 id, groupId, articleId, title, null, serviceContext));
383 article.setDescriptionMap(descriptionMap, locale);
384 article.setContent(content);
385 article.setDDMStructureKey(ddmStructureKey);
386 article.setDDMTemplateKey(ddmTemplateKey);
387 article.setLayoutUuid(layoutUuid);
388 article.setDisplayDate(displayDate);
389 article.setExpirationDate(expirationDate);
390 article.setReviewDate(reviewDate);
391 article.setIndexable(indexable);
392 article.setSmallImage(smallImage);
393 article.setSmallImageId(counterLocalService.increment());
394 article.setSmallImageURL(smallImageURL);
395
396 if ((expirationDate == null) || expirationDate.after(now)) {
397 article.setStatus(WorkflowConstants.STATUS_DRAFT);
398 }
399 else {
400 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
401 }
402
403 article.setStatusByUserId(userId);
404 article.setStatusDate(serviceContext.getModifiedDate(now));
405 article.setExpandoBridgeAttributes(serviceContext);
406
407 journalArticlePersistence.update(article);
408
409
410
411 if (serviceContext.isAddGroupPermissions() ||
412 serviceContext.isAddGuestPermissions()) {
413
414 addArticleResources(
415 article, serviceContext.isAddGroupPermissions(),
416 serviceContext.isAddGuestPermissions());
417 }
418 else {
419 addArticleResources(
420 article, serviceContext.getGroupPermissions(),
421 serviceContext.getGuestPermissions());
422 }
423
424
425
426 saveImages(
427 smallImage, article.getSmallImageId(), smallImageFile,
428 smallImageBytes);
429
430
431
432 updateAsset(
433 userId, article, serviceContext.getAssetCategoryIds(),
434 serviceContext.getAssetTagNames(),
435 serviceContext.getAssetLinkEntryIds());
436
437
438
439 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
440 CommentManagerUtil.addDiscussion(
441 userId, groupId, JournalArticle.class.getName(),
442 resourcePrimKey, article.getUserName());
443 }
444
445
446
447 if (classNameLocalService.getClassNameId(DDMStructure.class) ==
448 classNameId) {
449
450 updateDDMStructurePredefinedValues(
451 classPK, content, serviceContext);
452 }
453 else {
454 updateDDMLinks(id, groupId, ddmStructureKey, ddmTemplateKey, true);
455 }
456
457
458
459 PortletPreferences preferences =
460 ServiceContextUtil.getPortletPreferences(serviceContext);
461
462 articleURL = buildArticleURL(articleURL, groupId, folderId, articleId);
463
464 serviceContext.setAttribute("articleURL", articleURL);
465
466 sendEmail(
467 article, articleURL, preferences, "requested", serviceContext);
468
469
470
471 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
472 startWorkflowInstance(userId, article, serviceContext);
473 }
474 else {
475 updateStatus(
476 userId, article, WorkflowConstants.STATUS_APPROVED, null,
477 serviceContext, new HashMap<String, Serializable>());
478 }
479
480 return journalArticlePersistence.findByPrimaryKey(article.getId());
481 }
482
483
512 @Override
513 public JournalArticle addArticle(
514 long userId, long groupId, long folderId,
515 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
516 String content, String ddmStructureKey, String ddmTemplateKey,
517 ServiceContext serviceContext)
518 throws PortalException {
519
520 User user = userPersistence.findByPrimaryKey(userId);
521
522 Calendar calendar = CalendarFactoryUtil.getCalendar(user.getTimeZone());
523
524 int displayDateMonth = calendar.get(Calendar.MONTH);
525 int displayDateDay = calendar.get(Calendar.DAY_OF_MONTH);
526 int displayDateYear = calendar.get(Calendar.YEAR);
527 int displayDateHour = calendar.get(Calendar.HOUR_OF_DAY);
528 int displayDateMinute = calendar.get(Calendar.MINUTE);
529
530 return journalArticleLocalService.addArticle(
531 userId, groupId, folderId,
532 JournalArticleConstants.CLASSNAME_ID_DEFAULT, 0, StringPool.BLANK,
533 true, 1, titleMap, descriptionMap, content, ddmStructureKey,
534 ddmTemplateKey, null, displayDateMonth, displayDateDay,
535 displayDateYear, displayDateHour, displayDateMinute, 0, 0, 0, 0, 0,
536 true, 0, 0, 0, 0, 0, true, true, false, null, null, null, null,
537 serviceContext);
538 }
539
540
549 @Override
550 public void addArticleResources(
551 JournalArticle article, boolean addGroupPermissions,
552 boolean addGuestPermissions)
553 throws PortalException {
554
555 resourceLocalService.addResources(
556 article.getCompanyId(), article.getGroupId(), article.getUserId(),
557 JournalArticle.class.getName(), article.getResourcePrimKey(), false,
558 addGroupPermissions, addGuestPermissions);
559 }
560
561
569 @Override
570 public void addArticleResources(
571 JournalArticle article, String[] groupPermissions,
572 String[] guestPermissions)
573 throws PortalException {
574
575 resourceLocalService.addModelResources(
576 article.getCompanyId(), article.getGroupId(), article.getUserId(),
577 JournalArticle.class.getName(), article.getResourcePrimKey(),
578 groupPermissions, guestPermissions);
579 }
580
581
590 @Override
591 public void addArticleResources(
592 long groupId, String articleId, boolean addGroupPermissions,
593 boolean addGuestPermissions)
594 throws PortalException {
595
596 JournalArticle article = getLatestArticle(groupId, articleId);
597
598 addArticleResources(article, addGroupPermissions, addGuestPermissions);
599 }
600
601
611 @Override
612 public void addArticleResources(
613 long groupId, String articleId, String[] groupPermissions,
614 String[] guestPermissions)
615 throws PortalException {
616
617 JournalArticle article = getLatestArticle(groupId, articleId);
618
619 addArticleResources(article, groupPermissions, guestPermissions);
620 }
621
622
634 @Override
635 public JournalArticle checkArticleResourcePrimKey(
636 long groupId, String articleId, double version)
637 throws PortalException {
638
639 JournalArticle article = journalArticlePersistence.findByG_A_V(
640 groupId, articleId, version);
641
642 if (article.getResourcePrimKey() > 0) {
643 return article;
644 }
645
646 long resourcePrimKey =
647 journalArticleResourceLocalService.getArticleResourcePrimKey(
648 groupId, articleId);
649
650 article.setResourcePrimKey(resourcePrimKey);
651
652 journalArticlePersistence.update(article);
653
654 return article;
655 }
656
657
663 @Override
664 public void checkArticles() throws PortalException {
665 Date now = new Date();
666
667 checkArticlesByExpirationDate(now);
668
669 checkArticlesByReviewDate(now);
670
671 checkArticlesByDisplayDate(now);
672
673 _previousCheckDate = now;
674 }
675
676
687 @Override
688 public void checkNewLine(long groupId, String articleId, double version)
689 throws PortalException {
690
691 JournalArticle article = journalArticlePersistence.findByG_A_V(
692 groupId, articleId, version);
693
694 String content = GetterUtil.getString(article.getContent());
695
696 if (content.contains("\\n")) {
697 content = StringUtil.replace(
698 content, new String[] {"\\n", "\\r"},
699 new String[] {"\n", "\r"});
700
701 article.setContent(content);
702
703 journalArticlePersistence.update(article);
704 }
705 }
706
707
719 @Override
720 public void checkStructure(long groupId, String articleId, double version)
721 throws PortalException {
722
723 JournalArticle article = journalArticlePersistence.findByG_A_V(
724 groupId, articleId, version);
725
726 checkStructure(article);
727 }
728
729
744 @Indexable(type = IndexableType.REINDEX)
745 @Override
746 public JournalArticle copyArticle(
747 long userId, long groupId, String oldArticleId, String newArticleId,
748 boolean autoArticleId, double version)
749 throws PortalException {
750
751
752
753 User user = userPersistence.findByPrimaryKey(userId);
754 oldArticleId = StringUtil.toUpperCase(oldArticleId.trim());
755 newArticleId = StringUtil.toUpperCase(newArticleId.trim());
756
757 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
758 groupId, oldArticleId, version);
759
760 if (autoArticleId) {
761 newArticleId = String.valueOf(counterLocalService.increment());
762 }
763 else {
764 validate(newArticleId);
765
766 if (journalArticlePersistence.countByG_A(
767 groupId, newArticleId) > 0) {
768
769 StringBundler sb = new StringBundler(5);
770
771 sb.append("{groupId=");
772 sb.append(groupId);
773 sb.append(", articleId=");
774 sb.append(newArticleId);
775 sb.append("}");
776
777 throw new DuplicateArticleIdException(sb.toString());
778 }
779 }
780
781 long id = counterLocalService.increment();
782
783 long resourcePrimKey =
784 journalArticleResourceLocalService.getArticleResourcePrimKey(
785 groupId, newArticleId);
786
787 JournalArticle newArticle = journalArticlePersistence.create(id);
788
789 newArticle.setResourcePrimKey(resourcePrimKey);
790 newArticle.setGroupId(groupId);
791 newArticle.setCompanyId(user.getCompanyId());
792 newArticle.setUserId(user.getUserId());
793 newArticle.setUserName(user.getFullName());
794 newArticle.setFolderId(oldArticle.getFolderId());
795 newArticle.setTreePath(oldArticle.getTreePath());
796 newArticle.setArticleId(newArticleId);
797 newArticle.setVersion(JournalArticleConstants.VERSION_DEFAULT);
798 newArticle.setTitle(oldArticle.getTitle());
799 newArticle.setUrlTitle(
800 getUniqueUrlTitle(
801 id, groupId, newArticleId, oldArticle.getTitleCurrentValue()));
802 newArticle.setDescription(oldArticle.getDescription());
803
804 try {
805 copyArticleImages(oldArticle, newArticle);
806 }
807 catch (Exception e) {
808 newArticle.setContent(oldArticle.getContent());
809 }
810
811 newArticle.setDDMStructureKey(oldArticle.getDDMStructureKey());
812 newArticle.setDDMTemplateKey(oldArticle.getDDMTemplateKey());
813 newArticle.setLayoutUuid(oldArticle.getLayoutUuid());
814 newArticle.setDisplayDate(oldArticle.getDisplayDate());
815 newArticle.setExpirationDate(oldArticle.getExpirationDate());
816 newArticle.setReviewDate(oldArticle.getReviewDate());
817 newArticle.setIndexable(oldArticle.isIndexable());
818 newArticle.setSmallImage(oldArticle.isSmallImage());
819 newArticle.setSmallImageId(counterLocalService.increment());
820 newArticle.setSmallImageURL(oldArticle.getSmallImageURL());
821
822 if (oldArticle.isPending() ||
823 workflowDefinitionLinkLocalService.hasWorkflowDefinitionLink(
824 user.getCompanyId(), groupId, JournalArticle.class.getName())) {
825
826 newArticle.setStatus(WorkflowConstants.STATUS_DRAFT);
827 }
828 else {
829 newArticle.setStatus(oldArticle.getStatus());
830 }
831
832 ExpandoBridgeUtil.copyExpandoBridgeAttributes(
833 oldArticle.getExpandoBridge(), newArticle.getExpandoBridge());
834
835 journalArticlePersistence.update(newArticle);
836
837
838
839 addArticleResources(newArticle, true, true);
840
841
842
843 if (oldArticle.isSmallImage()) {
844 Image image = imageLocalService.fetchImage(
845 oldArticle.getSmallImageId());
846
847 if (image != null) {
848 byte[] smallImageBytes = image.getTextObj();
849
850 imageLocalService.updateImage(
851 newArticle.getSmallImageId(), smallImageBytes);
852 }
853 }
854
855
856
857 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
858 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
859 String[] assetTagNames = assetTagLocalService.getTagNames(
860 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
861
862 AssetEntry oldAssetEntry = assetEntryLocalService.getEntry(
863 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
864
865 List<AssetLink> assetLinks = assetLinkLocalService.getDirectLinks(
866 oldAssetEntry.getEntryId());
867
868 long[] assetLinkEntryIds = ListUtil.toLongArray(
869 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR);
870
871 updateAsset(
872 userId, newArticle, assetCategoryIds, assetTagNames,
873 assetLinkEntryIds);
874
875
876
877 updateDDMLinks(
878 id, groupId, oldArticle.getDDMStructureKey(),
879 oldArticle.getDDMTemplateKey(), true);
880
881 return newArticle;
882 }
883
884
891 @Override
892 @SystemEvent(
893 action = SystemEventConstants.ACTION_SKIP, send = false,
894 type = SystemEventConstants.TYPE_DELETE
895 )
896 public JournalArticle deleteArticle(JournalArticle article)
897 throws PortalException {
898
899 return journalArticleLocalService.deleteArticle(
900 article, StringPool.BLANK, null);
901 }
902
903
917 @Indexable(type = IndexableType.DELETE)
918 @Override
919 @SystemEvent(
920 action = SystemEventConstants.ACTION_SKIP, send = false,
921 type = SystemEventConstants.TYPE_DELETE
922 )
923 public JournalArticle deleteArticle(
924 JournalArticle article, String articleURL,
925 ServiceContext serviceContext)
926 throws PortalException {
927
928 JournalArticleResource articleResource =
929 journalArticleResourceLocalService.fetchArticleResource(
930 article.getGroupId(), article.getArticleId());
931
932 if (article.isApproved() &&
933 isLatestVersion(
934 article.getGroupId(), article.getArticleId(),
935 article.getVersion(), WorkflowConstants.STATUS_APPROVED)) {
936
937 updatePreviousApprovedArticle(article);
938 }
939
940
941
942 if ((serviceContext != null) && Validator.isNotNull(articleURL)) {
943 PortletPreferences preferences =
944 ServiceContextUtil.getPortletPreferences(serviceContext);
945
946 if ((preferences != null) && !article.isApproved() &&
947 isLatestVersion(
948 article.getGroupId(), article.getArticleId(),
949 article.getVersion())) {
950
951 articleURL = buildArticleURL(
952 articleURL, article.getGroupId(), article.getFolderId(),
953 article.getArticleId());
954
955 sendEmail(
956 article, articleURL, preferences, "denied", serviceContext);
957 }
958 }
959
960
961
962 String articleId = article.getArticleId();
963
964 if (article.isInTrash()) {
965 articleId = TrashUtil.getOriginalTitle(article.getArticleId());
966 }
967
968 journalArticleImageLocalService.deleteImages(
969 article.getGroupId(), articleId, article.getVersion());
970
971
972
973 if (article.getClassNameId() !=
974 classNameLocalService.getClassNameId(DDMStructure.class)) {
975
976 ddmStorageLinkLocalService.deleteClassStorageLink(article.getId());
977
978 ddmTemplateLinkLocalService.deleteTemplateLink(
979 classNameLocalService.getClassNameId(JournalArticle.class),
980 article.getId());
981 }
982
983
984
985 expandoRowLocalService.deleteRows(article.getId());
986
987
988
989 if (article.isInTrash()) {
990 TrashEntry trashEntry = article.getTrashEntry();
991
992 if (trashEntry != null) {
993 trashVersionLocalService.deleteTrashVersion(
994 JournalArticle.class.getName(), article.getId());
995 }
996 }
997
998
999
1000 if (!article.isDraft()) {
1001 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
1002 article.getCompanyId(), article.getGroupId(),
1003 JournalArticle.class.getName(), article.getId());
1004 }
1005
1006 int articlesCount = journalArticlePersistence.countByG_A(
1007 article.getGroupId(), article.getArticleId());
1008
1009 if (articlesCount == 1) {
1010
1011
1012
1013 assetEntryLocalService.deleteEntry(
1014 JournalArticle.class.getName(), article.getResourcePrimKey());
1015
1016
1017
1018 CommentManagerUtil.deleteDiscussion(
1019 JournalArticle.class.getName(), article.getResourcePrimKey());
1020
1021
1022
1023 journalContentSearchLocalService.deleteArticleContentSearches(
1024 article.getGroupId(), article.getArticleId());
1025
1026
1027
1028 ratingsStatsLocalService.deleteStats(
1029 JournalArticle.class.getName(), article.getResourcePrimKey());
1030
1031
1032
1033 imageLocalService.deleteImage(article.getSmallImageId());
1034
1035
1036
1037 trashEntryLocalService.deleteEntry(
1038 JournalArticle.class.getName(), article.getResourcePrimKey());
1039
1040
1041
1042 resourceLocalService.deleteResource(
1043 article.getCompanyId(), JournalArticle.class.getName(),
1044 ResourceConstants.SCOPE_INDIVIDUAL,
1045 article.getResourcePrimKey());
1046
1047
1048
1049 if (articleResource != null) {
1050 journalArticleResourceLocalService.deleteJournalArticleResource(
1051 articleResource);
1052 }
1053 }
1054
1055
1056
1057 journalArticlePersistence.remove(article);
1058
1059
1060
1061 if (articleResource != null) {
1062 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1063
1064 extraDataJSONObject.put("uuid", article.getUuid());
1065 extraDataJSONObject.put("version", article.getVersion());
1066
1067 systemEventLocalService.addSystemEvent(
1068 0, article.getGroupId(), article.getModelClassName(),
1069 article.getPrimaryKey(), articleResource.getUuid(), null,
1070 SystemEventConstants.TYPE_DELETE,
1071 extraDataJSONObject.toString());
1072 }
1073
1074 return article;
1075 }
1076
1077
1093 @Override
1094 public JournalArticle deleteArticle(
1095 long groupId, String articleId, double version, String articleURL,
1096 ServiceContext serviceContext)
1097 throws PortalException {
1098
1099 JournalArticle article = journalArticlePersistence.findByG_A_V(
1100 groupId, articleId, version);
1101
1102 return journalArticleLocalService.deleteArticle(
1103 article, articleURL, serviceContext);
1104 }
1105
1106
1118 @Override
1119 public void deleteArticle(
1120 long groupId, String articleId, ServiceContext serviceContext)
1121 throws PortalException {
1122
1123 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1124
1125 JournalArticleResource articleResource =
1126 journalArticleResourceLocalService.fetchArticleResource(
1127 groupId, articleId);
1128
1129 try {
1130 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1131 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1132 new ArticleVersionComparator(true));
1133
1134 for (JournalArticle article : articles) {
1135 journalArticleLocalService.deleteArticle(
1136 article, null, serviceContext);
1137 }
1138 }
1139 finally {
1140 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1141 }
1142
1143 if (articleResource != null) {
1144 systemEventLocalService.addSystemEvent(
1145 0, groupId, JournalArticle.class.getName(),
1146 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1147 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1148 }
1149 }
1150
1151
1157 @Override
1158 public void deleteArticles(long groupId) throws PortalException {
1159 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1160
1161 List<JournalArticleResource> articleResources = new ArrayList<>();
1162
1163 try {
1164 JournalArticleResource articleResource = null;
1165
1166 for (JournalArticle article :
1167 journalArticlePersistence.findByGroupId(groupId)) {
1168
1169 if ((articleResource == null) ||
1170 (articleResource.getPrimaryKey() !=
1171 article.getResourcePrimKey())) {
1172
1173 articleResource =
1174 journalArticleResourceLocalService.getArticleResource(
1175 article.getResourcePrimKey());
1176
1177 articleResources.add(articleResource);
1178 }
1179
1180 journalArticleLocalService.deleteArticle(article, null, null);
1181 }
1182 }
1183 finally {
1184 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1185 }
1186
1187 for (JournalArticleResource articleResource : articleResources) {
1188 systemEventLocalService.addSystemEvent(
1189 0, groupId, JournalArticle.class.getName(),
1190 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1191 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1192 }
1193 }
1194
1195
1203 @Override
1204 public void deleteArticles(long groupId, long folderId)
1205 throws PortalException {
1206
1207 deleteArticles(groupId, folderId, true);
1208 }
1209
1210
1220 @Override
1221 public void deleteArticles(
1222 long groupId, long folderId, boolean includeTrashedEntries)
1223 throws PortalException {
1224
1225 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1226
1227 List<JournalArticleResource> articleResources = new ArrayList<>();
1228
1229 try {
1230 JournalArticleResource articleResource = null;
1231
1232 for (JournalArticle article :
1233 journalArticlePersistence.findByG_F(groupId, folderId)) {
1234
1235 if ((articleResource == null) ||
1236 (articleResource.getPrimaryKey() !=
1237 article.getResourcePrimKey())) {
1238
1239 articleResource =
1240 journalArticleResourceLocalService.getArticleResource(
1241 article.getResourcePrimKey());
1242
1243 articleResources.add(articleResource);
1244 }
1245
1246 if (includeTrashedEntries || !article.isInTrashExplicitly()) {
1247 journalArticleLocalService.deleteArticle(
1248 article, null, null);
1249 }
1250 else {
1251 articleResources.remove(articleResource);
1252 }
1253 }
1254 }
1255 finally {
1256 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1257 }
1258
1259 for (JournalArticleResource articleResource : articleResources) {
1260 systemEventLocalService.addSystemEvent(
1261 0, groupId, JournalArticle.class.getName(),
1262 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1263 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1264 }
1265 }
1266
1267
1275 @Override
1276 public void deleteLayoutArticleReferences(long groupId, String layoutUuid) {
1277 List<JournalArticle> articles = journalArticlePersistence.findByG_L(
1278 groupId, layoutUuid);
1279
1280 for (JournalArticle article : articles) {
1281 article.setLayoutUuid(StringPool.BLANK);
1282
1283 journalArticlePersistence.update(article);
1284 }
1285 }
1286
1287
1309 @Indexable(type = IndexableType.REINDEX)
1310 @Override
1311 public JournalArticle expireArticle(
1312 long userId, long groupId, String articleId, double version,
1313 String articleURL, ServiceContext serviceContext)
1314 throws PortalException {
1315
1316 return updateStatus(
1317 userId, groupId, articleId, version,
1318 WorkflowConstants.STATUS_EXPIRED, articleURL,
1319 new HashMap<String, Serializable>(), serviceContext);
1320 }
1321
1322
1344 @Override
1345 public void expireArticle(
1346 long userId, long groupId, String articleId, String articleURL,
1347 ServiceContext serviceContext)
1348 throws PortalException {
1349
1350 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
1351 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1352 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1353 new ArticleVersionComparator(true));
1354
1355 for (JournalArticle article : articles) {
1356 journalArticleLocalService.expireArticle(
1357 userId, groupId, article.getArticleId(),
1358 article.getVersion(), articleURL, serviceContext);
1359 }
1360 }
1361 else {
1362 JournalArticle article = getLatestArticle(
1363 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1364
1365 journalArticleLocalService.expireArticle(
1366 userId, groupId, article.getArticleId(), article.getVersion(),
1367 articleURL, serviceContext);
1368 }
1369 }
1370
1371 @Override
1372 public JournalArticle fetchArticle(long groupId, String articleId) {
1373
1374
1375
1376
1377 JournalArticle article = fetchLatestArticle(
1378 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1379
1380 if (article != null) {
1381 return article;
1382 }
1383
1384 return fetchLatestArticle(
1385 groupId, articleId, WorkflowConstants.STATUS_ANY);
1386 }
1387
1388
1399 @Override
1400 public JournalArticle fetchArticle(
1401 long groupId, String articleId, double version) {
1402
1403 return journalArticlePersistence.fetchByG_A_V(
1404 groupId, articleId, version);
1405 }
1406
1407 @Override
1408 public JournalArticle fetchArticleByUrlTitle(
1409 long groupId, String urlTitle) {
1410
1411 JournalArticle article = fetchLatestArticleByUrlTitle(
1412 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
1413
1414 if (article != null) {
1415 return article;
1416 }
1417
1418 return fetchLatestArticleByUrlTitle(
1419 groupId, urlTitle, WorkflowConstants.STATUS_PENDING);
1420 }
1421
1422 @Override
1423 public JournalArticle fetchDisplayArticle(long groupId, String articleId) {
1424 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
1425 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1426
1427 if (articles.isEmpty()) {
1428 return null;
1429 }
1430
1431 Date now = new Date();
1432
1433 for (JournalArticle article : articles) {
1434 Date displayDate = article.getDisplayDate();
1435 Date expirationDate = article.getExpirationDate();
1436
1437 if (((displayDate == null) || displayDate.before(now)) &&
1438 ((expirationDate == null) || expirationDate.after(now))) {
1439
1440 return article;
1441 }
1442 }
1443
1444 return articles.get(0);
1445 }
1446
1447 @Override
1448 public JournalArticle fetchLatestArticle(long resourcePrimKey) {
1449 return fetchLatestArticle(
1450 resourcePrimKey, WorkflowConstants.STATUS_ANY);
1451 }
1452
1453 @Override
1454 public JournalArticle fetchLatestArticle(long resourcePrimKey, int status) {
1455 return fetchLatestArticle(resourcePrimKey, status, true);
1456 }
1457
1458
1476 @Override
1477 public JournalArticle fetchLatestArticle(
1478 long resourcePrimKey, int status, boolean preferApproved) {
1479
1480 JournalArticle article = null;
1481
1482 OrderByComparator<JournalArticle> orderByComparator =
1483 new ArticleVersionComparator();
1484
1485 if (status == WorkflowConstants.STATUS_ANY) {
1486 if (preferApproved) {
1487 article = journalArticlePersistence.fetchByR_ST_First(
1488 resourcePrimKey, WorkflowConstants.STATUS_APPROVED,
1489 orderByComparator);
1490 }
1491
1492 if (article == null) {
1493 article =
1494 journalArticlePersistence.fetchByResourcePrimKey_First(
1495 resourcePrimKey, orderByComparator);
1496 }
1497 }
1498 else {
1499 article = journalArticlePersistence.fetchByR_ST_First(
1500 resourcePrimKey, status, orderByComparator);
1501 }
1502
1503 return article;
1504 }
1505
1506 @Override
1507 public JournalArticle fetchLatestArticle(
1508 long resourcePrimKey, int[] statuses) {
1509
1510 OrderByComparator<JournalArticle> orderByComparator =
1511 new ArticleVersionComparator();
1512
1513 List<JournalArticle> articles = journalArticlePersistence.findByR_ST(
1514 resourcePrimKey, statuses, 0, 1, orderByComparator);
1515
1516 if (!articles.isEmpty()) {
1517 return articles.get(0);
1518 }
1519
1520 return null;
1521 }
1522
1523
1535 @Override
1536 public JournalArticle fetchLatestArticle(
1537 long groupId, String articleId, int status) {
1538
1539 OrderByComparator<JournalArticle> orderByComparator =
1540 new ArticleVersionComparator();
1541
1542 if (status == WorkflowConstants.STATUS_ANY) {
1543 return journalArticlePersistence.fetchByG_A_NotST_First(
1544 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH,
1545 orderByComparator);
1546 }
1547
1548 return journalArticlePersistence.fetchByG_A_ST_First(
1549 groupId, articleId, status, orderByComparator);
1550 }
1551
1552 @Override
1553 public JournalArticle fetchLatestArticleByUrlTitle(
1554 long groupId, String urlTitle, int status) {
1555
1556 List<JournalArticle> articles = null;
1557
1558 OrderByComparator<JournalArticle> orderByComparator =
1559 new ArticleVersionComparator();
1560
1561 if (status == WorkflowConstants.STATUS_ANY) {
1562 articles = journalArticlePersistence.findByG_UT(
1563 groupId, urlTitle, 0, 1, orderByComparator);
1564 }
1565 else {
1566 articles = journalArticlePersistence.findByG_UT_ST(
1567 groupId, urlTitle, status, 0, 1, orderByComparator);
1568 }
1569
1570 if (articles.isEmpty()) {
1571 return null;
1572 }
1573
1574 return articles.get(0);
1575 }
1576
1577
1586 @Override
1587 public JournalArticle fetchLatestIndexableArticle(long resourcePrimKey) {
1588 OrderByComparator<JournalArticle> orderByComparator =
1589 new ArticleVersionComparator();
1590
1591 int[] statuses = new int[] {
1592 WorkflowConstants.STATUS_APPROVED, WorkflowConstants.STATUS_IN_TRASH
1593 };
1594
1595 List<JournalArticle> articles = journalArticlePersistence.findByR_I_S(
1596 resourcePrimKey, true, statuses, 0, 1, orderByComparator);
1597
1598 if (articles.isEmpty()) {
1599 return null;
1600 }
1601
1602 return articles.get(0);
1603 }
1604
1605
1613 @Override
1614 public JournalArticle getArticle(long id) throws PortalException {
1615 return journalArticlePersistence.findByPrimaryKey(id);
1616 }
1617
1618
1629 @Override
1630 public JournalArticle getArticle(long groupId, String articleId)
1631 throws PortalException {
1632
1633
1634
1635
1636 JournalArticle article = fetchLatestArticle(
1637 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1638
1639 if (article != null) {
1640 return article;
1641 }
1642
1643 return getLatestArticle(
1644 groupId, articleId, WorkflowConstants.STATUS_ANY);
1645 }
1646
1647
1658 @Override
1659 public JournalArticle getArticle(
1660 long groupId, String articleId, double version)
1661 throws PortalException {
1662
1663 return journalArticlePersistence.findByG_A_V(
1664 groupId, articleId, version);
1665 }
1666
1667
1684 @Override
1685 public JournalArticle getArticle(
1686 long groupId, String className, long classPK)
1687 throws PortalException {
1688
1689 long classNameId = classNameLocalService.getClassNameId(className);
1690
1691 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1692 groupId, classNameId, classPK);
1693
1694 if (articles.isEmpty()) {
1695 throw new NoSuchArticleException(
1696 "No approved JournalArticle exists with the key {groupId=" +
1697 groupId + ", className=" + className + ", classPK=" +
1698 classPK + "}");
1699 }
1700
1701 return articles.get(0);
1702 }
1703
1704
1714 @Override
1715 public JournalArticle getArticleByUrlTitle(long groupId, String urlTitle)
1716 throws PortalException {
1717
1718
1719
1720
1721 JournalArticle article = fetchLatestArticleByUrlTitle(
1722 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
1723
1724 if (article != null) {
1725 return article;
1726 }
1727
1728 return getLatestArticleByUrlTitle(
1729 groupId, urlTitle, WorkflowConstants.STATUS_PENDING);
1730 }
1731
1732
1748 @Override
1749 public String getArticleContent(
1750 JournalArticle article, String ddmTemplateKey, String viewMode,
1751 String languageId, PortletRequestModel portletRequestModel,
1752 ThemeDisplay themeDisplay)
1753 throws PortalException {
1754
1755 JournalArticleDisplay articleDisplay = getArticleDisplay(
1756 article, ddmTemplateKey, viewMode, languageId, 1,
1757 portletRequestModel, themeDisplay);
1758
1759 if (articleDisplay == null) {
1760 return StringPool.BLANK;
1761 }
1762 else {
1763 return articleDisplay.getContent();
1764 }
1765 }
1766
1767
1784 @Deprecated
1785 @Override
1786 public String getArticleContent(
1787 JournalArticle article, String ddmTemplateKey, String viewMode,
1788 String languageId, ThemeDisplay themeDisplay)
1789 throws PortalException {
1790
1791 return getArticleContent(
1792 article, ddmTemplateKey, viewMode, languageId, null, themeDisplay);
1793 }
1794
1795
1813 @Override
1814 public String getArticleContent(
1815 long groupId, String articleId, double version, String viewMode,
1816 String ddmTemplateKey, String languageId,
1817 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay)
1818 throws PortalException {
1819
1820 JournalArticleDisplay articleDisplay = getArticleDisplay(
1821 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
1822 1, portletRequestModel, themeDisplay);
1823
1824 if (articleDisplay == null) {
1825 return StringPool.BLANK;
1826 }
1827 else {
1828 return articleDisplay.getContent();
1829 }
1830 }
1831
1832
1854 @Deprecated
1855 @Override
1856 public String getArticleContent(
1857 long groupId, String articleId, double version, String viewMode,
1858 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1859 throws PortalException {
1860
1861 return getArticleContent(
1862 groupId, articleId, version, viewMode, ddmTemplateKey, languageId,
1863 null, themeDisplay);
1864 }
1865
1866
1884 @Deprecated
1885 @Override
1886 public String getArticleContent(
1887 long groupId, String articleId, double version, String viewMode,
1888 String languageId, ThemeDisplay themeDisplay)
1889 throws PortalException {
1890
1891 return getArticleContent(
1892 groupId, articleId, version, viewMode, null, languageId, null,
1893 themeDisplay);
1894 }
1895
1896
1913 @Override
1914 public String getArticleContent(
1915 long groupId, String articleId, String viewMode,
1916 String ddmTemplateKey, String languageId,
1917 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay)
1918 throws PortalException {
1919
1920 JournalArticleDisplay articleDisplay = getArticleDisplay(
1921 groupId, articleId, ddmTemplateKey, viewMode, languageId, 1,
1922 portletRequestModel, themeDisplay);
1923
1924 return articleDisplay.getContent();
1925 }
1926
1927
1946 @Deprecated
1947 @Override
1948 public String getArticleContent(
1949 long groupId, String articleId, String viewMode,
1950 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1951 throws PortalException {
1952
1953 return getArticleContent(
1954 groupId, articleId, viewMode, ddmTemplateKey, languageId, null,
1955 themeDisplay);
1956 }
1957
1958
1975 @Deprecated
1976 @Override
1977 public String getArticleContent(
1978 long groupId, String articleId, String viewMode, String languageId,
1979 ThemeDisplay themeDisplay)
1980 throws PortalException {
1981
1982 return getArticleContent(
1983 groupId, articleId, viewMode, null, languageId, null, themeDisplay);
1984 }
1985
1986
2005 @Override
2006 public JournalArticleDisplay getArticleDisplay(
2007 JournalArticle article, String ddmTemplateKey, String viewMode,
2008 String languageId, int page,
2009 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay)
2010 throws PortalException {
2011
2012 return getArticleDisplay(
2013 article, ddmTemplateKey, viewMode, languageId, page,
2014 portletRequestModel, themeDisplay, false);
2015 }
2016
2017
2038 @Override
2039 public JournalArticleDisplay getArticleDisplay(
2040 long groupId, String articleId, double version,
2041 String ddmTemplateKey, String viewMode, String languageId, int page,
2042 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay)
2043 throws PortalException {
2044
2045 Date now = new Date();
2046
2047 JournalArticle article = journalArticlePersistence.findByG_A_V(
2048 groupId, articleId, version);
2049
2050 if (article.isExpired()) {
2051 Date expirationDate = article.getExpirationDate();
2052
2053 if ((expirationDate != null) && expirationDate.before(now)) {
2054 return null;
2055 }
2056 }
2057
2058 Date displayDate = article.getDisplayDate();
2059
2060 if (displayDate.after(now)) {
2061 return null;
2062 }
2063
2064 return getArticleDisplay(
2065 article, ddmTemplateKey, viewMode, languageId, page,
2066 portletRequestModel, themeDisplay);
2067 }
2068
2069
2089 @Override
2090 public JournalArticleDisplay getArticleDisplay(
2091 long groupId, String articleId, double version,
2092 String ddmTemplateKey, String viewMode, String languageId,
2093 ThemeDisplay themeDisplay)
2094 throws PortalException {
2095
2096 return getArticleDisplay(
2097 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
2098 1, null, themeDisplay);
2099 }
2100
2101
2119 @Override
2120 public JournalArticleDisplay getArticleDisplay(
2121 long groupId, String articleId, String viewMode, String languageId,
2122 int page, PortletRequestModel portletRequestModel,
2123 ThemeDisplay themeDisplay)
2124 throws PortalException {
2125
2126 return getArticleDisplay(
2127 groupId, articleId, null, viewMode, languageId, page,
2128 portletRequestModel, themeDisplay);
2129 }
2130
2131
2151 @Override
2152 public JournalArticleDisplay getArticleDisplay(
2153 long groupId, String articleId, String ddmTemplateKey,
2154 String viewMode, String languageId, int page,
2155 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay)
2156 throws PortalException {
2157
2158 JournalArticle article = getDisplayArticle(groupId, articleId);
2159
2160 return getArticleDisplay(
2161 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2162 languageId, page, portletRequestModel, themeDisplay);
2163 }
2164
2165
2184 @Override
2185 public JournalArticleDisplay getArticleDisplay(
2186 long groupId, String articleId, String ddmTemplateKey,
2187 String viewMode, String languageId, ThemeDisplay themeDisplay)
2188 throws PortalException {
2189
2190 JournalArticle article = getDisplayArticle(groupId, articleId);
2191
2192 return getArticleDisplay(
2193 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2194 languageId, themeDisplay);
2195 }
2196
2197
2214 @Override
2215 public JournalArticleDisplay getArticleDisplay(
2216 long groupId, String articleId, String viewMode, String languageId,
2217 ThemeDisplay themeDisplay)
2218 throws PortalException {
2219
2220 return getArticleDisplay(
2221 groupId, articleId, null, viewMode, languageId, themeDisplay);
2222 }
2223
2224
2229 @Override
2230 public List<JournalArticle> getArticles() {
2231 return journalArticlePersistence.findAll();
2232 }
2233
2234
2240 @Override
2241 public List<JournalArticle> getArticles(long groupId) {
2242 return journalArticlePersistence.findByGroupId(groupId);
2243 }
2244
2245
2264 @Override
2265 public List<JournalArticle> getArticles(long groupId, int start, int end) {
2266 return journalArticlePersistence.findByGroupId(groupId, start, end);
2267 }
2268
2269
2291 @Override
2292 public List<JournalArticle> getArticles(
2293 long groupId, int start, int end,
2294 OrderByComparator<JournalArticle> obc) {
2295
2296 return journalArticlePersistence.findByGroupId(
2297 groupId, start, end, obc);
2298 }
2299
2300
2307 @Override
2308 public List<JournalArticle> getArticles(long groupId, long folderId) {
2309 return journalArticlePersistence.findByG_F(groupId, folderId);
2310 }
2311
2312
2333 @Override
2334 public List<JournalArticle> getArticles(
2335 long groupId, long folderId, int start, int end) {
2336
2337 return journalArticlePersistence.findByG_F(
2338 groupId, folderId, start, end);
2339 }
2340
2341
2365 @Override
2366 public List<JournalArticle> getArticles(
2367 long groupId, long folderId, int status, int start, int end) {
2368
2369 return journalArticlePersistence.findByG_F_ST(
2370 groupId, folderId, status, start, end);
2371 }
2372
2373
2397 @Override
2398 public List<JournalArticle> getArticles(
2399 long groupId, long folderId, int start, int end,
2400 OrderByComparator<JournalArticle> orderByComparator) {
2401
2402 return journalArticlePersistence.findByG_F(
2403 groupId, folderId, start, end, orderByComparator);
2404 }
2405
2406
2413 @Override
2414 public List<JournalArticle> getArticles(long groupId, String articleId) {
2415 return journalArticlePersistence.findByG_A(groupId, articleId);
2416 }
2417
2418 @Override
2419 public List<JournalArticle> getArticles(
2420 long groupId, String articleId, int start, int end,
2421 OrderByComparator<JournalArticle> orderByComparator) {
2422
2423 return journalArticlePersistence.findByG_A(
2424 groupId, articleId, start, end, orderByComparator);
2425 }
2426
2427
2433 @Override
2434 public List<JournalArticle> getArticlesByResourcePrimKey(
2435 long resourcePrimKey) {
2436
2437 return journalArticlePersistence.findByResourcePrimKey(resourcePrimKey);
2438 }
2439
2440
2447 @Override
2448 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId) {
2449 return journalArticlePersistence.findBySmallImageId(smallImageId);
2450 }
2451
2452
2458 @Override
2459 public int getArticlesCount(long groupId) {
2460 return journalArticlePersistence.countByGroupId(groupId);
2461 }
2462
2463
2470 @Override
2471 public int getArticlesCount(long groupId, long folderId) {
2472 return journalArticlePersistence.countByG_F(groupId, folderId);
2473 }
2474
2475
2486 @Override
2487 public int getArticlesCount(long groupId, long folderId, int status) {
2488 return journalArticlePersistence.countByG_F_ST(
2489 groupId, folderId, status);
2490 }
2491
2492 @Override
2493 public int getArticlesCount(long groupId, String articleId) {
2494 return journalArticlePersistence.countByG_A(groupId, articleId);
2495 }
2496
2497
2521 @Override
2522 public List<JournalArticle> getCompanyArticles(
2523 long companyId, double version, int status, int start, int end) {
2524
2525 if (status == WorkflowConstants.STATUS_ANY) {
2526 return journalArticlePersistence.findByC_V(
2527 companyId, version, start, end, new ArticleIDComparator(true));
2528 }
2529 else {
2530 return journalArticlePersistence.findByC_V_ST(
2531 companyId, version, status, start, end,
2532 new ArticleIDComparator(true));
2533 }
2534 }
2535
2536
2559 @Override
2560 public List<JournalArticle> getCompanyArticles(
2561 long companyId, int status, int start, int end) {
2562
2563 if (status == WorkflowConstants.STATUS_ANY) {
2564 return journalArticlePersistence.findByCompanyId(
2565 companyId, start, end, new ArticleIDComparator(true));
2566 }
2567 else {
2568 return journalArticlePersistence.findByC_ST(
2569 companyId, status, start, end, new ArticleIDComparator(true));
2570 }
2571 }
2572
2573
2597 @Override
2598 public int getCompanyArticlesCount(
2599 long companyId, double version, int status, int start, int end) {
2600
2601 if (status == WorkflowConstants.STATUS_ANY) {
2602 return journalArticlePersistence.countByC_V(companyId, version);
2603 }
2604 else {
2605 return journalArticlePersistence.countByC_V_ST(
2606 companyId, version, status);
2607 }
2608 }
2609
2610
2620 @Override
2621 public int getCompanyArticlesCount(long companyId, int status) {
2622 if (status == WorkflowConstants.STATUS_ANY) {
2623 return journalArticlePersistence.countByCompanyId(companyId);
2624 }
2625 else {
2626 return journalArticlePersistence.countByC_ST(companyId, status);
2627 }
2628 }
2629
2630
2642 @Override
2643 public JournalArticle getDisplayArticle(long groupId, String articleId)
2644 throws PortalException {
2645
2646 JournalArticle article = fetchDisplayArticle(groupId, articleId);
2647
2648 if (article == null) {
2649 throw new NoSuchArticleException(
2650 "No approved JournalArticle exists with the key {groupId=" +
2651 groupId + ", " + "articleId=" + articleId + "}");
2652 }
2653
2654 return article;
2655 }
2656
2657
2669 @Override
2670 public JournalArticle getDisplayArticleByUrlTitle(
2671 long groupId, String urlTitle)
2672 throws PortalException {
2673
2674 List<JournalArticle> articles = null;
2675
2676 OrderByComparator<JournalArticle> orderByComparator =
2677 new ArticleVersionComparator();
2678
2679 articles = journalArticlePersistence.findByG_UT_ST(
2680 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED,
2681 QueryUtil.ALL_POS, QueryUtil.ALL_POS, orderByComparator);
2682
2683 if (articles.isEmpty()) {
2684 throw new NoSuchArticleException(
2685 "No JournalArticle exists with the key {groupId=" + groupId +
2686 ", urlTitle=" + urlTitle + "}");
2687 }
2688
2689 Date now = new Date();
2690
2691 for (JournalArticle article : articles) {
2692 Date displayDate = article.getDisplayDate();
2693 Date expirationDate = article.getExpirationDate();
2694
2695 if ((displayDate != null) && displayDate.before(now) &&
2696 ((expirationDate == null) || expirationDate.after(now)) ) {
2697
2698 return article;
2699 }
2700 }
2701
2702 return articles.get(0);
2703 }
2704
2705 @Override
2706 public List<JournalArticle> getIndexableArticlesByDDMStructureKey(
2707 String[] ddmStructureKeys) {
2708
2709 if (PropsValues.JOURNAL_ARTICLE_INDEX_ALL_VERSIONS) {
2710 return getStructureArticles(ddmStructureKeys);
2711 }
2712
2713 QueryDefinition<JournalArticle> approvedQueryDefinition =
2714 new QueryDefinition<JournalArticle>(
2715 WorkflowConstants.STATUS_APPROVED, QueryUtil.ALL_POS,
2716 QueryUtil.ALL_POS, new ArticleVersionComparator());
2717
2718 List<JournalArticle> articles = new ArrayList<>();
2719
2720 articles.addAll(
2721 journalArticleFinder.findByG_C_S(
2722 0, JournalArticleConstants.CLASSNAME_ID_DEFAULT,
2723 ddmStructureKeys, approvedQueryDefinition));
2724
2725 QueryDefinition<JournalArticle> trashQueryDefinition =
2726 new QueryDefinition<JournalArticle>(
2727 WorkflowConstants.STATUS_IN_TRASH, QueryUtil.ALL_POS,
2728 QueryUtil.ALL_POS, new ArticleVersionComparator());
2729
2730 articles.addAll(
2731 journalArticleFinder.findByG_C_S(
2732 0, JournalArticleConstants.CLASSNAME_ID_DEFAULT,
2733 ddmStructureKeys, trashQueryDefinition));
2734
2735 return articles;
2736 }
2737
2738
2746 @Override
2747 public List<JournalArticle> getIndexableArticlesByResourcePrimKey(
2748 long resourcePrimKey) {
2749
2750 return journalArticlePersistence.findByR_I(resourcePrimKey, true);
2751 }
2752
2753
2763 @Override
2764 public JournalArticle getLatestArticle(long resourcePrimKey)
2765 throws PortalException {
2766
2767 return getLatestArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);
2768 }
2769
2770
2784 @Override
2785 public JournalArticle getLatestArticle(long resourcePrimKey, int status)
2786 throws PortalException {
2787
2788 return getLatestArticle(resourcePrimKey, status, true);
2789 }
2790
2791
2810 @Override
2811 public JournalArticle getLatestArticle(
2812 long resourcePrimKey, int status, boolean preferApproved)
2813 throws PortalException {
2814
2815 List<JournalArticle> articles = null;
2816
2817 OrderByComparator<JournalArticle> orderByComparator =
2818 new ArticleVersionComparator();
2819
2820 if (status == WorkflowConstants.STATUS_ANY) {
2821 if (preferApproved) {
2822 articles = journalArticlePersistence.findByR_ST(
2823 resourcePrimKey, WorkflowConstants.STATUS_APPROVED, 0, 1,
2824 orderByComparator);
2825 }
2826
2827 if (ListUtil.isEmpty(articles)) {
2828 articles = journalArticlePersistence.findByResourcePrimKey(
2829 resourcePrimKey, 0, 1, orderByComparator);
2830 }
2831 }
2832 else {
2833 articles = journalArticlePersistence.findByR_ST(
2834 resourcePrimKey, status, 0, 1, orderByComparator);
2835 }
2836
2837 if (articles.isEmpty()) {
2838 throw new NoSuchArticleException(
2839 "No JournalArticle exists with the key {resourcePrimKey=" +
2840 resourcePrimKey + "}");
2841 }
2842
2843 return articles.get(0);
2844 }
2845
2846
2855 @Override
2856 public JournalArticle getLatestArticle(long groupId, String articleId)
2857 throws PortalException {
2858
2859 return getLatestArticle(
2860 groupId, articleId, WorkflowConstants.STATUS_ANY);
2861 }
2862
2863
2876 @Override
2877 public JournalArticle getLatestArticle(
2878 long groupId, String articleId, int status)
2879 throws PortalException {
2880
2881 return getFirstArticle(
2882 groupId, articleId, status, new ArticleVersionComparator());
2883 }
2884
2885
2902 @Override
2903 public JournalArticle getLatestArticle(
2904 long groupId, String className, long classPK)
2905 throws PortalException {
2906
2907 long classNameId = classNameLocalService.getClassNameId(className);
2908
2909 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
2910 groupId, classNameId, classPK, 0, 1,
2911 new ArticleVersionComparator());
2912
2913 if (articles.isEmpty()) {
2914 throw new NoSuchArticleException(
2915 "No JournalArticle exists with the key {groupId=" + groupId +
2916 ", className=" + className + ", classPK =" + classPK + "}");
2917 }
2918
2919 return articles.get(0);
2920 }
2921
2922
2935 @Override
2936 public JournalArticle getLatestArticleByUrlTitle(
2937 long groupId, String urlTitle, int status)
2938 throws PortalException {
2939
2940 JournalArticle article = fetchLatestArticleByUrlTitle(
2941 groupId, urlTitle, status);
2942
2943 if (article == null) {
2944 throw new NoSuchArticleException(
2945 "No JournalArticle exists with the key {groupId=" + groupId +
2946 ", urlTitle=" + urlTitle + ", status=" + status + "}");
2947 }
2948
2949 return article;
2950 }
2951
2952
2962 @Override
2963 public double getLatestVersion(long groupId, String articleId)
2964 throws PortalException {
2965
2966 JournalArticle article = getLatestArticle(groupId, articleId);
2967
2968 return article.getVersion();
2969 }
2970
2971
2984 @Override
2985 public double getLatestVersion(long groupId, String articleId, int status)
2986 throws PortalException {
2987
2988 JournalArticle article = getLatestArticle(groupId, articleId, status);
2989
2990 return article.getVersion();
2991 }
2992
2993 @Override
2994 public List<JournalArticle> getNoAssetArticles() {
2995 return journalArticleFinder.findByNoAssets();
2996 }
2997
2998 @Override
2999 public List<JournalArticle> getNoPermissionArticles() {
3000 return journalArticleFinder.findByNoPermissions();
3001 }
3002
3003
3010 @Override
3011 public int getNotInTrashArticlesCount(long groupId, long folderId) {
3012 QueryDefinition<JournalArticle> queryDefinition = new QueryDefinition<>(
3013 WorkflowConstants.STATUS_ANY);
3014
3015 List<Long> folderIds = new ArrayList<>();
3016
3017 folderIds.add(folderId);
3018
3019 return journalArticleFinder.countByG_F(
3020 groupId, folderIds, queryDefinition);
3021 }
3022
3023
3032 @Override
3033 public JournalArticle getOldestArticle(long groupId, String articleId)
3034 throws PortalException {
3035
3036 return getOldestArticle(
3037 groupId, articleId, WorkflowConstants.STATUS_ANY);
3038 }
3039
3040
3053 @Override
3054 public JournalArticle getOldestArticle(
3055 long groupId, String articleId, int status)
3056 throws PortalException {
3057
3058 return getFirstArticle(
3059 groupId, articleId, status, new ArticleVersionComparator(false));
3060 }
3061
3062
3072 @Override
3073 public JournalArticle getPreviousApprovedArticle(JournalArticle article) {
3074 List<JournalArticle> approvedArticles =
3075 journalArticlePersistence.findByG_A_ST(
3076 article.getGroupId(), article.getArticleId(),
3077 WorkflowConstants.STATUS_APPROVED, 0, 2);
3078
3079 if (approvedArticles.isEmpty() ||
3080 ((approvedArticles.size() == 1) &&
3081 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
3082
3083 return article;
3084 }
3085
3086 JournalArticle previousApprovedArticle = approvedArticles.get(0);
3087
3088 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
3089 previousApprovedArticle = approvedArticles.get(1);
3090 }
3091
3092 return previousApprovedArticle;
3093 }
3094
3095
3104 @Override
3105 public List<JournalArticle> getStructureArticles(
3106 long groupId, String ddmStructureKey) {
3107
3108 return journalArticlePersistence.findByG_DDMSK(
3109 groupId, ddmStructureKey);
3110 }
3111
3112
3136 @Override
3137 public List<JournalArticle> getStructureArticles(
3138 long groupId, String ddmStructureKey, int start, int end,
3139 OrderByComparator<JournalArticle> obc) {
3140
3141 return journalArticlePersistence.findByG_DDMSK(
3142 groupId, ddmStructureKey, start, end, obc);
3143 }
3144
3145
3152 @Override
3153 public List<JournalArticle> getStructureArticles(
3154 String[] ddmStructureKeys) {
3155
3156 return journalArticlePersistence.findByDDMStructureKey(
3157 ddmStructureKeys);
3158 }
3159
3160
3169 @Override
3170 public int getStructureArticlesCount(long groupId, String ddmStructureKey) {
3171 return journalArticlePersistence.countByG_DDMSK(
3172 groupId, ddmStructureKey);
3173 }
3174
3175
3183 @Override
3184 public List<JournalArticle> getTemplateArticles(
3185 long groupId, String ddmTemplateKey) {
3186
3187 return journalArticlePersistence.findByG_DDMTK(groupId, ddmTemplateKey);
3188 }
3189
3190
3214 @Override
3215 public List<JournalArticle> getTemplateArticles(
3216 long groupId, String ddmTemplateKey, int start, int end,
3217 OrderByComparator<JournalArticle> obc) {
3218
3219 return journalArticlePersistence.findByG_DDMTK(
3220 groupId, ddmTemplateKey, start, end, obc);
3221 }
3222
3223
3232 @Override
3233 public int getTemplateArticlesCount(long groupId, String ddmTemplateKey) {
3234 return journalArticlePersistence.countByG_DDMTK(
3235 groupId, ddmTemplateKey);
3236 }
3237
3238
3247 @Override
3248 public String getUniqueUrlTitle(
3249 long groupId, String articleId, String urlTitle)
3250 throws PortalException {
3251
3252 for (int i = 1;; i++) {
3253 JournalArticle article = fetchArticleByUrlTitle(groupId, urlTitle);
3254
3255 if ((article == null) || articleId.equals(article.getArticleId())) {
3256 break;
3257 }
3258 else {
3259 String suffix = StringPool.DASH + i;
3260
3261 String prefix = urlTitle;
3262
3263 if (urlTitle.length() > suffix.length()) {
3264 prefix = urlTitle.substring(
3265 0, urlTitle.length() - suffix.length());
3266 }
3267
3268 urlTitle = prefix + suffix;
3269 }
3270 }
3271
3272 return urlTitle;
3273 }
3274
3275
3283 @Override
3284 public boolean hasArticle(long groupId, String articleId) {
3285 JournalArticle article = fetchArticle(groupId, articleId);
3286
3287 if (article != null) {
3288 return true;
3289 }
3290
3291 return false;
3292 }
3293
3294
3306 @Override
3307 public boolean isLatestVersion(
3308 long groupId, String articleId, double version)
3309 throws PortalException {
3310
3311 if (getLatestVersion(groupId, articleId) == version) {
3312 return true;
3313 }
3314 else {
3315 return false;
3316 }
3317 }
3318
3319
3334 @Override
3335 public boolean isLatestVersion(
3336 long groupId, String articleId, double version, int status)
3337 throws PortalException {
3338
3339 if (getLatestVersion(groupId, articleId, status) == version) {
3340 return true;
3341 }
3342 else {
3343 return false;
3344 }
3345 }
3346
3347 @Override
3348 public boolean isRenderable(
3349 JournalArticle article, PortletRequestModel portletRequestModel,
3350 ThemeDisplay themeDisplay) {
3351
3352 try {
3353 getArticleDisplay(
3354 article, null, Constants.VIEW, article.getDefaultLanguageId(),
3355 0, portletRequestModel, themeDisplay, true);
3356 }
3357 catch (Exception e) {
3358 return false;
3359 }
3360
3361 return true;
3362 }
3363
3364
3379 @Deprecated
3380 @Indexable(type = IndexableType.REINDEX)
3381 @Override
3382 public JournalArticle moveArticle(
3383 long groupId, String articleId, long newFolderId)
3384 throws PortalException {
3385
3386 return moveArticle(groupId, articleId, newFolderId, null);
3387 }
3388
3389
3409 @Indexable(type = IndexableType.REINDEX)
3410 @Override
3411 public JournalArticle moveArticle(
3412 long groupId, String articleId, long newFolderId,
3413 ServiceContext serviceContext)
3414 throws PortalException {
3415
3416 JournalArticle latestArticle = getLatestArticle(groupId, articleId);
3417
3418 validateDDMStructureId(
3419 groupId, newFolderId, latestArticle.getDDMStructureKey());
3420
3421 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3422 groupId, articleId);
3423
3424 for (JournalArticle article : articles) {
3425 if (serviceContext != null) {
3426 notifySubscribers(
3427 serviceContext.getUserId(), article, article.getUrlTitle(),
3428 "move_from", serviceContext);
3429 }
3430
3431 article.setFolderId(newFolderId);
3432 article.setTreePath(article.buildTreePath());
3433
3434 journalArticlePersistence.update(article);
3435
3436 if (serviceContext != null) {
3437 notifySubscribers(
3438 serviceContext.getUserId(), article, article.getUrlTitle(),
3439 "move_to", serviceContext);
3440 }
3441 }
3442
3443 return getArticle(groupId, articleId);
3444 }
3445
3446
3468 @Indexable(type = IndexableType.REINDEX)
3469 @Override
3470 public JournalArticle moveArticleFromTrash(
3471 long userId, long groupId, JournalArticle article, long newFolderId,
3472 ServiceContext serviceContext)
3473 throws PortalException {
3474
3475 if (article.isInTrashExplicitly()) {
3476 restoreArticleFromTrash(userId, article);
3477 }
3478 else {
3479
3480
3481
3482 TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
3483 JournalArticle.class.getName(), article.getResourcePrimKey());
3484
3485 int status = WorkflowConstants.STATUS_APPROVED;
3486
3487 if (trashVersion != null) {
3488 status = trashVersion.getStatus();
3489 }
3490
3491 updateStatus(
3492 userId, article, status, null, serviceContext,
3493 new HashMap<String, Serializable>());
3494
3495
3496
3497 if (trashVersion != null) {
3498 trashVersionLocalService.deleteTrashVersion(trashVersion);
3499 }
3500 }
3501
3502 return moveArticle(
3503 groupId, article.getArticleId(), newFolderId, serviceContext);
3504 }
3505
3506
3518 @Indexable(type = IndexableType.REINDEX)
3519 @Override
3520 public JournalArticle moveArticleToTrash(
3521 long userId, JournalArticle article)
3522 throws PortalException {
3523
3524
3525
3526 int oldStatus = article.getStatus();
3527
3528 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3529 article.setStatus(WorkflowConstants.STATUS_DRAFT);
3530 }
3531
3532 journalArticlePersistence.update(article);
3533
3534 List<JournalArticle> articleVersions =
3535 journalArticlePersistence.findByG_A(
3536 article.getGroupId(), article.getArticleId());
3537
3538 articleVersions = ListUtil.sort(
3539 articleVersions, new ArticleVersionComparator());
3540
3541 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
3542 new ArrayList<>();
3543
3544 if ((articleVersions != null) && !articleVersions.isEmpty()) {
3545 articleVersionStatusOVPs = getArticleVersionStatuses(
3546 articleVersions);
3547 }
3548
3549 article = updateStatus(
3550 userId, article.getId(), WorkflowConstants.STATUS_IN_TRASH,
3551 new HashMap<String, Serializable>(), new ServiceContext());
3552
3553
3554
3555 JournalArticleResource articleResource =
3556 journalArticleResourceLocalService.getArticleResource(
3557 article.getResourcePrimKey());
3558
3559 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
3560
3561 typeSettingsProperties.put("title", article.getArticleId());
3562
3563 TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
3564 userId, article.getGroupId(), JournalArticle.class.getName(),
3565 article.getResourcePrimKey(), articleResource.getUuid(), null,
3566 oldStatus, articleVersionStatusOVPs, typeSettingsProperties);
3567
3568 String trashArticleId = TrashUtil.getTrashTitle(
3569 trashEntry.getEntryId());
3570
3571 for (JournalArticle articleVersion : articleVersions) {
3572 articleVersion.setArticleId(trashArticleId);
3573 articleVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
3574
3575 journalArticlePersistence.update(articleVersion);
3576 }
3577
3578 articleResource.setArticleId(trashArticleId);
3579
3580 journalArticleResourcePersistence.update(articleResource);
3581
3582 article.setArticleId(trashArticleId);
3583
3584 article = journalArticlePersistence.update(article);
3585
3586
3587
3588 assetEntryLocalService.updateVisible(
3589 JournalArticle.class.getName(), article.getResourcePrimKey(),
3590 false);
3591
3592
3593
3594 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3595
3596 extraDataJSONObject.put("title", article.getTitle());
3597
3598 socialActivityLocalService.addActivity(
3599 userId, article.getGroupId(), JournalArticle.class.getName(),
3600 article.getResourcePrimKey(),
3601 SocialActivityConstants.TYPE_MOVE_TO_TRASH,
3602 extraDataJSONObject.toString(), 0);
3603
3604 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3605 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
3606 article.getCompanyId(), article.getGroupId(),
3607 JournalArticle.class.getName(), article.getId());
3608 }
3609
3610 return article;
3611 }
3612
3613
3626 @Override
3627 public JournalArticle moveArticleToTrash(
3628 long userId, long groupId, String articleId)
3629 throws PortalException {
3630
3631 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3632 groupId, articleId, 0, 1, new ArticleVersionComparator());
3633
3634 if (!articles.isEmpty()) {
3635 return journalArticleLocalService.moveArticleToTrash(
3636 userId, articles.get(0));
3637 }
3638
3639 return null;
3640 }
3641
3642
3661 @Override
3662 public void rebuildTree(long companyId) throws PortalException {
3663 journalFolderLocalService.rebuildTree(companyId);
3664 }
3665
3666
3678 @Indexable(type = IndexableType.REINDEX)
3679 @Override
3680 public JournalArticle removeArticleLocale(
3681 long groupId, String articleId, double version, String languageId)
3682 throws PortalException {
3683
3684 JournalArticle article = journalArticlePersistence.findByG_A_V(
3685 groupId, articleId, version);
3686
3687 String title = article.getTitle();
3688
3689 title = LocalizationUtil.removeLocalization(
3690 title, "static-content", languageId, true);
3691
3692 article.setTitle(title);
3693
3694 String description = article.getDescription();
3695
3696 description = LocalizationUtil.removeLocalization(
3697 description, "static-content", languageId, true);
3698
3699 article.setDescription(description);
3700
3701 String content = article.getContent();
3702
3703 Document document = article.getDocument();
3704
3705 if (document != null) {
3706 content = JournalUtil.removeArticleLocale(
3707 document, content, languageId);
3708
3709 article.setContent(content);
3710 }
3711
3712 journalArticlePersistence.update(article);
3713
3714 return article;
3715 }
3716
3717
3729 @Indexable(type = IndexableType.REINDEX)
3730 @Override
3731 public JournalArticle restoreArticleFromTrash(
3732 long userId, JournalArticle article)
3733 throws PortalException {
3734
3735
3736
3737 String trashArticleId = TrashUtil.getOriginalTitle(
3738 article.getArticleId());
3739
3740 List<JournalArticle> articleVersions =
3741 journalArticlePersistence.findByG_A(
3742 article.getGroupId(), article.getArticleId());
3743
3744 for (JournalArticle articleVersion : articleVersions) {
3745 articleVersion.setArticleId(trashArticleId);
3746
3747 journalArticlePersistence.update(articleVersion);
3748 }
3749
3750 article.setArticleId(trashArticleId);
3751
3752 journalArticlePersistence.update(article);
3753
3754 JournalArticleResource articleResource =
3755 journalArticleResourcePersistence.fetchByPrimaryKey(
3756 article.getResourcePrimKey());
3757
3758 articleResource.setArticleId(trashArticleId);
3759
3760 journalArticleResourcePersistence.update(articleResource);
3761
3762 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3763 JournalArticle.class.getName(), article.getResourcePrimKey());
3764
3765 ServiceContext serviceContext = new ServiceContext();
3766
3767 serviceContext.setScopeGroupId(article.getGroupId());
3768
3769 updateStatus(
3770 userId, article, trashEntry.getStatus(), null, serviceContext,
3771 new HashMap<String, Serializable>());
3772
3773
3774
3775 List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
3776 trashEntry.getEntryId());
3777
3778 for (TrashVersion trashVersion : trashVersions) {
3779 JournalArticle trashArticleVersion =
3780 journalArticlePersistence.findByPrimaryKey(
3781 trashVersion.getClassPK());
3782
3783 trashArticleVersion.setStatus(trashVersion.getStatus());
3784
3785 journalArticlePersistence.update(trashArticleVersion);
3786 }
3787
3788 trashEntryLocalService.deleteEntry(
3789 JournalArticle.class.getName(), article.getResourcePrimKey());
3790
3791
3792
3793 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3794
3795 extraDataJSONObject.put("title", article.getTitle());
3796
3797 socialActivityLocalService.addActivity(
3798 userId, article.getGroupId(), JournalArticle.class.getName(),
3799 article.getResourcePrimKey(),
3800 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
3801 extraDataJSONObject.toString(), 0);
3802
3803 return article;
3804 }
3805
3806
3833 @Override
3834 public List<JournalArticle> search(
3835 long groupId, List<Long> folderIds, int status, int start, int end) {
3836
3837 QueryDefinition<JournalArticle> queryDefinition = new QueryDefinition<>(
3838 status, start, end, null);
3839
3840 return journalArticleFinder.findByG_F(
3841 groupId, folderIds, queryDefinition);
3842 }
3843
3844
3870 @Override
3871 public List<JournalArticle> search(
3872 long groupId, long folderId, int status, int start, int end) {
3873
3874 List<Long> folderIds = new ArrayList<>();
3875
3876 folderIds.add(folderId);
3877
3878 return search(groupId, folderIds, status, start, end);
3879 }
3880
3881
3938 @Override
3939 public List<JournalArticle> search(
3940 long companyId, long groupId, List<Long> folderIds, long classNameId,
3941 String keywords, Double version, String ddmStructureKey,
3942 String ddmTemplateKey, Date displayDateGT, Date displayDateLT,
3943 int status, Date reviewDate, int start, int end,
3944 OrderByComparator<JournalArticle> obc) {
3945
3946 return journalArticleFinder.findByKeywords(
3947 companyId, groupId, folderIds, classNameId, keywords, version,
3948 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
3949 status, reviewDate, start, end, obc);
3950 }
3951
3952
4016 @Override
4017 public List<JournalArticle> search(
4018 long companyId, long groupId, List<Long> folderIds, long classNameId,
4019 String articleId, Double version, String title, String description,
4020 String content, String ddmStructureKey, String ddmTemplateKey,
4021 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4022 boolean andOperator, int start, int end,
4023 OrderByComparator<JournalArticle> obc) {
4024
4025 QueryDefinition<JournalArticle> queryDefinition = new QueryDefinition<>(
4026 status, start, end, obc);
4027
4028 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_S_T_D_R(
4029 companyId, groupId, folderIds, classNameId, articleId, version,
4030 title, description, content, ddmStructureKey, ddmTemplateKey,
4031 displayDateGT, displayDateLT, reviewDate, andOperator,
4032 queryDefinition);
4033 }
4034
4035
4098 @Override
4099 public List<JournalArticle> search(
4100 long companyId, long groupId, List<Long> folderIds, long classNameId,
4101 String articleId, Double version, String title, String description,
4102 String content, String[] ddmStructureKeys, String[] ddmTemplateKeys,
4103 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4104 boolean andOperator, int start, int end,
4105 OrderByComparator<JournalArticle> obc) {
4106
4107 QueryDefinition<JournalArticle> queryDefinition = new QueryDefinition<>(
4108 status, start, end, obc);
4109
4110 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_S_T_D_R(
4111 companyId, groupId, folderIds, classNameId, articleId, version,
4112 title, description, content, ddmStructureKeys, ddmTemplateKeys,
4113 displayDateGT, displayDateLT, reviewDate, andOperator,
4114 queryDefinition);
4115 }
4116
4117
4161 @Override
4162 public Hits search(
4163 long companyId, long groupId, List<Long> folderIds, long classNameId,
4164 String ddmStructureKey, String ddmTemplateKey, String keywords,
4165 LinkedHashMap<String, Object> params, int start, int end, Sort sort) {
4166
4167 String articleId = null;
4168 String title = null;
4169 String description = null;
4170 String content = null;
4171 boolean andOperator = false;
4172
4173 if (Validator.isNotNull(keywords)) {
4174 articleId = keywords;
4175 title = keywords;
4176 description = keywords;
4177 content = keywords;
4178 }
4179 else {
4180 andOperator = true;
4181 }
4182
4183 if (params != null) {
4184 params.put("keywords", keywords);
4185 }
4186
4187 return search(
4188 companyId, groupId, folderIds, classNameId, articleId, title,
4189 description, content, WorkflowConstants.STATUS_ANY, ddmStructureKey,
4190 ddmTemplateKey, params, andOperator, start, end, sort);
4191 }
4192
4193
4249 @Override
4250 public Hits search(
4251 long companyId, long groupId, List<Long> folderIds, long classNameId,
4252 String articleId, String title, String description, String content,
4253 int status, String ddmStructureKey, String ddmTemplateKey,
4254 LinkedHashMap<String, Object> params, boolean andSearch, int start,
4255 int end, Sort sort) {
4256
4257 try {
4258 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
4259 JournalArticle.class);
4260
4261 SearchContext searchContext = buildSearchContext(
4262 companyId, groupId, folderIds, classNameId, articleId, title,
4263 description, content, status, ddmStructureKey, ddmTemplateKey,
4264 params, andSearch, start, end, sort);
4265
4266 return indexer.search(searchContext);
4267 }
4268 catch (Exception e) {
4269 throw new SystemException(e);
4270 }
4271 }
4272
4273
4278 @Deprecated
4279 @Override
4280 public Hits search(
4281 long companyId, long groupId, List<Long> folderIds, long classNameId,
4282 String articleId, String title, String description, String content,
4283 String type, String statusString, String ddmStructureKey,
4284 String ddmTemplateKey, LinkedHashMap<String, Object> params,
4285 boolean andSearch, int start, int end, Sort sort) {
4286
4287 int status = GetterUtil.getInteger(statusString);
4288
4289 return search(
4290 companyId, groupId, folderIds, classNameId, articleId, title,
4291 description, content, status, ddmStructureKey, ddmTemplateKey,
4292 params, andSearch, start, end, sort);
4293 }
4294
4295
4325 @Override
4326 public Hits search(
4327 long groupId, long userId, long creatorUserId, int status,
4328 int start, int end)
4329 throws PortalException {
4330
4331 Indexer indexer = IndexerRegistryUtil.getIndexer(
4332 JournalArticle.class.getName());
4333
4334 SearchContext searchContext = buildSearchContext(
4335 groupId, userId, creatorUserId, status, start, end);
4336
4337 return indexer.search(searchContext);
4338 }
4339
4340
4352 @Override
4353 public int searchCount(long groupId, List<Long> folderIds, int status) {
4354 QueryDefinition<JournalArticle> queryDefinition = new QueryDefinition<>(
4355 status);
4356
4357 return journalArticleFinder.countByG_F(
4358 groupId, folderIds, queryDefinition);
4359 }
4360
4361
4372 @Override
4373 public int searchCount(long groupId, long folderId, int status) {
4374 List<Long> folderIds = new ArrayList<>();
4375
4376 folderIds.add(folderId);
4377
4378 return searchCount(groupId, folderIds, status);
4379 }
4380
4381
4420 @Override
4421 public int searchCount(
4422 long companyId, long groupId, List<Long> folderIds, long classNameId,
4423 String keywords, Double version, String ddmStructureKey,
4424 String ddmTemplateKey, Date displayDateGT, Date displayDateLT,
4425 int status, Date reviewDate) {
4426
4427 return journalArticleFinder.countByKeywords(
4428 companyId, groupId, folderIds, classNameId, keywords, version,
4429 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
4430 status, reviewDate);
4431 }
4432
4433
4478 @Override
4479 public int searchCount(
4480 long companyId, long groupId, List<Long> folderIds, long classNameId,
4481 String articleId, Double version, String title, String description,
4482 String content, String ddmStructureKey, String ddmTemplateKey,
4483 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4484 boolean andOperator) {
4485
4486 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_S_T_D_R(
4487 companyId, groupId, folderIds, classNameId, articleId, version,
4488 title, description, content, ddmStructureKey, ddmTemplateKey,
4489 displayDateGT, displayDateLT, reviewDate, andOperator,
4490 new QueryDefinition<JournalArticle>(status));
4491 }
4492
4493
4540 @Override
4541 public int searchCount(
4542 long companyId, long groupId, List<Long> folderIds, long classNameId,
4543 String articleId, Double version, String title, String description,
4544 String content, String[] ddmStructureKeys, String[] ddmTemplateKeys,
4545 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4546 boolean andOperator) {
4547
4548 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_S_T_D_R(
4549 companyId, groupId, folderIds, classNameId, articleId, version,
4550 title, description, content, ddmStructureKeys, ddmTemplateKeys,
4551 displayDateGT, displayDateLT, reviewDate, andOperator,
4552 new QueryDefinition<JournalArticle>(status));
4553 }
4554
4555
4607 @Override
4608 public BaseModelSearchResult<JournalArticle> searchJournalArticles(
4609 long companyId, long groupId, List<Long> folderIds,
4610 long classNameId, String ddmStructureKey, String ddmTemplateKey,
4611 String keywords, LinkedHashMap<String, Object> params, int start,
4612 int end, Sort sort)
4613 throws PortalException {
4614
4615 String articleId = null;
4616 String title = null;
4617 String description = null;
4618 String content = null;
4619 boolean andOperator = false;
4620
4621 if (Validator.isNotNull(keywords)) {
4622 articleId = keywords;
4623 title = keywords;
4624 description = keywords;
4625 content = keywords;
4626 }
4627 else {
4628 andOperator = true;
4629 }
4630
4631 if (params != null) {
4632 params.put("keywords", keywords);
4633 }
4634
4635 return searchJournalArticles(
4636 companyId, groupId, folderIds, classNameId, articleId, title,
4637 description, content, WorkflowConstants.STATUS_ANY, ddmStructureKey,
4638 ddmTemplateKey, params, andOperator, start, end, sort);
4639 }
4640
4641
4705 @Override
4706 public BaseModelSearchResult<JournalArticle> searchJournalArticles(
4707 long companyId, long groupId, List<Long> folderIds,
4708 long classNameId, String articleId, String title,
4709 String description, String content, int status,
4710 String ddmStructureKey, String ddmTemplateKey,
4711 LinkedHashMap<String, Object> params, boolean andSearch, int start,
4712 int end, Sort sort)
4713 throws PortalException {
4714
4715 SearchContext searchContext = buildSearchContext(
4716 companyId, groupId, folderIds, classNameId, articleId, title,
4717 description, content, status, ddmStructureKey, ddmTemplateKey,
4718 params, andSearch, start, end, sort);
4719
4720 return searchJournalArticles(searchContext);
4721 }
4722
4723
4762 @Override
4763 public BaseModelSearchResult<JournalArticle> searchJournalArticles(
4764 long groupId, long userId, long creatorUserId, int status,
4765 int start, int end)
4766 throws PortalException {
4767
4768 SearchContext searchContext = buildSearchContext(
4769 groupId, userId, creatorUserId, status, start, end);
4770
4771 return searchJournalArticles(searchContext);
4772 }
4773
4774 @Override
4775 public void setTreePaths(
4776 final long folderId, final String treePath, final boolean reindex)
4777 throws PortalException {
4778
4779 ActionableDynamicQuery actionableDynamicQuery =
4780 getActionableDynamicQuery();
4781
4782 actionableDynamicQuery.setAddCriteriaMethod(
4783 new ActionableDynamicQuery.AddCriteriaMethod() {
4784
4785 @Override
4786 public void addCriteria(DynamicQuery dynamicQuery) {
4787 Property folderIdProperty = PropertyFactoryUtil.forName(
4788 "folderId");
4789
4790 dynamicQuery.add(folderIdProperty.eq(folderId));
4791
4792 Property treePathProperty = PropertyFactoryUtil.forName(
4793 "treePath");
4794
4795 dynamicQuery.add(treePathProperty.ne(treePath));
4796 }
4797
4798 });
4799
4800 final Indexer indexer = IndexerRegistryUtil.getIndexer(
4801 JournalArticle.class.getName());
4802
4803 actionableDynamicQuery.setPerformActionMethod(
4804 new ActionableDynamicQuery.PerformActionMethod() {
4805
4806 @Override
4807 public void performAction(Object object)
4808 throws PortalException {
4809
4810 JournalArticle article = (JournalArticle)object;
4811
4812 article.setTreePath(treePath);
4813
4814 updateJournalArticle(article);
4815
4816 if (!reindex) {
4817 return;
4818 }
4819
4820 indexer.reindex(article);
4821 }
4822
4823 });
4824
4825 actionableDynamicQuery.performActions();
4826 }
4827
4828
4837 @Override
4838 public void subscribeStructure(
4839 long groupId, long userId, long ddmStructureId)
4840 throws PortalException {
4841
4842 subscriptionLocalService.addSubscription(
4843 userId, groupId, DDMStructure.class.getName(), ddmStructureId);
4844 }
4845
4846
4856 @Override
4857 public void unsubscribeStructure(
4858 long groupId, long userId, long ddmStructureId)
4859 throws PortalException {
4860
4861 subscriptionLocalService.deleteSubscription(
4862 userId, DDMStructure.class.getName(), ddmStructureId);
4863 }
4864
4865
4900 @Override
4901 public JournalArticle updateArticle(
4902 long userId, long groupId, long folderId, String articleId,
4903 double version, Map<Locale, String> titleMap,
4904 Map<Locale, String> descriptionMap, String content,
4905 String layoutUuid, ServiceContext serviceContext)
4906 throws PortalException {
4907
4908 User user = userPersistence.findByPrimaryKey(userId);
4909
4910 JournalArticle article = journalArticlePersistence.findByG_A_V(
4911 groupId, articleId, version);
4912
4913 Date displayDate = article.getDisplayDate();
4914
4915 int displayDateMonth = 0;
4916 int displayDateDay = 0;
4917 int displayDateYear = 0;
4918 int displayDateHour = 0;
4919 int displayDateMinute = 0;
4920
4921 if (displayDate != null) {
4922 Calendar displayCal = CalendarFactoryUtil.getCalendar(
4923 user.getTimeZone());
4924
4925 displayCal.setTime(displayDate);
4926
4927 displayDateMonth = displayCal.get(Calendar.MONTH);
4928 displayDateDay = displayCal.get(Calendar.DATE);
4929 displayDateYear = displayCal.get(Calendar.YEAR);
4930 displayDateHour = displayCal.get(Calendar.HOUR);
4931 displayDateMinute = displayCal.get(Calendar.MINUTE);
4932
4933 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
4934 displayDateHour += 12;
4935 }
4936 }
4937
4938 Date expirationDate = article.getExpirationDate();
4939
4940 int expirationDateMonth = 0;
4941 int expirationDateDay = 0;
4942 int expirationDateYear = 0;
4943 int expirationDateHour = 0;
4944 int expirationDateMinute = 0;
4945 boolean neverExpire = true;
4946
4947 if (expirationDate != null) {
4948 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
4949 user.getTimeZone());
4950
4951 expirationCal.setTime(expirationDate);
4952
4953 expirationDateMonth = expirationCal.get(Calendar.MONTH);
4954 expirationDateDay = expirationCal.get(Calendar.DATE);
4955 expirationDateYear = expirationCal.get(Calendar.YEAR);
4956 expirationDateHour = expirationCal.get(Calendar.HOUR);
4957 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
4958 neverExpire = false;
4959
4960 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
4961 expirationDateHour += 12;
4962 }
4963 }
4964
4965 Date reviewDate = article.getReviewDate();
4966
4967 int reviewDateMonth = 0;
4968 int reviewDateDay = 0;
4969 int reviewDateYear = 0;
4970 int reviewDateHour = 0;
4971 int reviewDateMinute = 0;
4972 boolean neverReview = true;
4973
4974 if (reviewDate != null) {
4975 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
4976 user.getTimeZone());
4977
4978 reviewCal.setTime(reviewDate);
4979
4980 reviewDateMonth = reviewCal.get(Calendar.MONTH);
4981 reviewDateDay = reviewCal.get(Calendar.DATE);
4982 reviewDateYear = reviewCal.get(Calendar.YEAR);
4983 reviewDateHour = reviewCal.get(Calendar.HOUR);
4984 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
4985 neverReview = false;
4986
4987 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
4988 reviewDateHour += 12;
4989 }
4990 }
4991
4992 return journalArticleLocalService.updateArticle(
4993 userId, groupId, folderId, articleId, version, titleMap,
4994 descriptionMap, content, article.getDDMStructureKey(),
4995 article.getDDMTemplateKey(), layoutUuid, displayDateMonth,
4996 displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
4997 expirationDateMonth, expirationDateDay, expirationDateYear,
4998 expirationDateHour, expirationDateMinute, neverExpire,
4999 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
5000 reviewDateMinute, neverReview, article.getIndexable(),
5001 article.isSmallImage(), article.getSmallImageURL(), null, null,
5002 null, serviceContext);
5003 }
5004
5005
5088 @Indexable(type = IndexableType.REINDEX)
5089 @Override
5090 public JournalArticle updateArticle(
5091 long userId, long groupId, long folderId, String articleId,
5092 double version, Map<Locale, String> titleMap,
5093 Map<Locale, String> descriptionMap, String content,
5094 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
5095 int displayDateMonth, int displayDateDay, int displayDateYear,
5096 int displayDateHour, int displayDateMinute, int expirationDateMonth,
5097 int expirationDateDay, int expirationDateYear,
5098 int expirationDateHour, int expirationDateMinute,
5099 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
5100 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
5101 boolean neverReview, boolean indexable, boolean smallImage,
5102 String smallImageURL, File smallImageFile,
5103 Map<String, byte[]> images, String articleURL,
5104 ServiceContext serviceContext)
5105 throws PortalException {
5106
5107
5108
5109 User user = userPersistence.findByPrimaryKey(userId);
5110 articleId = StringUtil.toUpperCase(articleId.trim());
5111
5112 byte[] smallImageBytes = null;
5113
5114 try {
5115 smallImageBytes = FileUtil.getBytes(smallImageFile);
5116 }
5117 catch (IOException ioe) {
5118 }
5119
5120 JournalArticle latestArticle = getLatestArticle(
5121 groupId, articleId, WorkflowConstants.STATUS_ANY);
5122
5123 JournalArticle article = latestArticle;
5124
5125 boolean imported = ExportImportThreadLocal.isImportInProcess();
5126
5127 double latestVersion = latestArticle.getVersion();
5128
5129 boolean addNewVersion = false;
5130
5131 if (imported) {
5132 article = getArticle(groupId, articleId, version);
5133 }
5134 else {
5135 if ((version > 0) && (version != latestVersion)) {
5136 throw new ArticleVersionException();
5137 }
5138
5139 serviceContext.validateModifiedDate(
5140 latestArticle, ArticleVersionException.class);
5141
5142 if (latestArticle.isApproved() || latestArticle.isExpired() ||
5143 latestArticle.isScheduled()) {
5144
5145 addNewVersion = true;
5146
5147 version = MathUtil.format(latestVersion + 0.1, 1, 1);
5148 }
5149 }
5150
5151 Date displayDate = null;
5152 Date expirationDate = null;
5153 Date reviewDate = null;
5154
5155 if (article.getClassNameId() ==
5156 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5157
5158 displayDate = PortalUtil.getDate(
5159 displayDateMonth, displayDateDay, displayDateYear,
5160 displayDateHour, displayDateMinute, user.getTimeZone(),
5161 ArticleDisplayDateException.class);
5162
5163 if (!neverExpire) {
5164 expirationDate = PortalUtil.getDate(
5165 expirationDateMonth, expirationDateDay, expirationDateYear,
5166 expirationDateHour, expirationDateMinute,
5167 user.getTimeZone(), ArticleExpirationDateException.class);
5168 }
5169
5170 if (!neverReview) {
5171 reviewDate = PortalUtil.getDate(
5172 reviewDateMonth, reviewDateDay, reviewDateYear,
5173 reviewDateHour, reviewDateMinute, user.getTimeZone(),
5174 ArticleReviewDateException.class);
5175 }
5176 }
5177
5178 Date now = new Date();
5179
5180 boolean expired = false;
5181
5182 if ((expirationDate != null) && expirationDate.before(now)) {
5183 expired = true;
5184 }
5185
5186 validate(
5187 user.getCompanyId(), groupId, latestArticle.getClassNameId(),
5188 titleMap, content, ddmStructureKey, ddmTemplateKey, expirationDate,
5189 smallImage, smallImageURL, smallImageFile, smallImageBytes,
5190 serviceContext);
5191
5192 if (addNewVersion) {
5193 long id = counterLocalService.increment();
5194
5195 article = journalArticlePersistence.create(id);
5196
5197 article.setResourcePrimKey(latestArticle.getResourcePrimKey());
5198 article.setGroupId(latestArticle.getGroupId());
5199 article.setCompanyId(latestArticle.getCompanyId());
5200 article.setUserId(user.getUserId());
5201 article.setUserName(user.getFullName());
5202 article.setCreateDate(latestArticle.getCreateDate());
5203 article.setClassNameId(latestArticle.getClassNameId());
5204 article.setClassPK(latestArticle.getClassPK());
5205 article.setArticleId(articleId);
5206 article.setVersion(version);
5207 article.setSmallImageId(latestArticle.getSmallImageId());
5208 }
5209
5210 Locale locale = getArticleDefaultLocale(content);
5211
5212 String title = titleMap.get(locale);
5213
5214 content = format(
5215 user, groupId, articleId, article.getVersion(), addNewVersion,
5216 content, images);
5217
5218 article.setFolderId(folderId);
5219 article.setTreePath(article.buildTreePath());
5220 article.setTitleMap(titleMap, locale);
5221 article.setUrlTitle(
5222 getUniqueUrlTitle(
5223 article.getId(), groupId, article.getArticleId(), title,
5224 latestArticle.getUrlTitle(), serviceContext));
5225 article.setDescriptionMap(descriptionMap, locale);
5226 article.setContent(content);
5227 article.setDDMStructureKey(ddmStructureKey);
5228 article.setDDMTemplateKey(ddmTemplateKey);
5229 article.setLayoutUuid(layoutUuid);
5230 article.setDisplayDate(displayDate);
5231 article.setExpirationDate(expirationDate);
5232 article.setReviewDate(reviewDate);
5233 article.setIndexable(indexable);
5234 article.setSmallImage(smallImage);
5235
5236 if (smallImage) {
5237 if ((smallImageFile != null) && (smallImageBytes != null)) {
5238 article.setSmallImageId(counterLocalService.increment());
5239 }
5240 }
5241 else {
5242 article.setSmallImageId(0);
5243 }
5244
5245 article.setSmallImageURL(smallImageURL);
5246
5247 if (latestArticle.isPending()) {
5248 article.setStatus(latestArticle.getStatus());
5249 }
5250 else if (!expired) {
5251 article.setStatus(WorkflowConstants.STATUS_DRAFT);
5252 }
5253 else {
5254 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5255 }
5256
5257 ExpandoBridgeUtil.setExpandoBridgeAttributes(
5258 latestArticle.getExpandoBridge(), article.getExpandoBridge(),
5259 serviceContext);
5260
5261 journalArticlePersistence.update(article);
5262
5263
5264
5265 updateAsset(
5266 userId, article, serviceContext.getAssetCategoryIds(),
5267 serviceContext.getAssetTagNames(),
5268 serviceContext.getAssetLinkEntryIds());
5269
5270
5271
5272 if (classNameLocalService.getClassNameId(DDMStructure.class) ==
5273 article.getClassNameId()) {
5274
5275 updateDDMStructurePredefinedValues(
5276 article.getClassPK(), content, serviceContext);
5277 }
5278 else {
5279 updateDDMLinks(
5280 article.getId(), groupId, ddmStructureKey, ddmTemplateKey,
5281 addNewVersion);
5282 }
5283
5284
5285
5286 saveImages(
5287 smallImage, article.getSmallImageId(), smallImageFile,
5288 smallImageBytes);
5289
5290
5291
5292 PortletPreferences preferences =
5293 ServiceContextUtil.getPortletPreferences(serviceContext);
5294
5295
5296
5297 if (expired && imported) {
5298 updateStatus(
5299 userId, article, article.getStatus(), articleURL,
5300 serviceContext, new HashMap<String, Serializable>());
5301 }
5302
5303 if (serviceContext.getWorkflowAction() ==
5304 WorkflowConstants.ACTION_PUBLISH) {
5305
5306 articleURL = buildArticleURL(
5307 articleURL, groupId, folderId, articleId);
5308
5309 serviceContext.setAttribute("articleURL", articleURL);
5310
5311 sendEmail(
5312 article, articleURL, preferences, "requested", serviceContext);
5313
5314 startWorkflowInstance(userId, article, serviceContext);
5315 }
5316
5317 return journalArticlePersistence.findByPrimaryKey(article.getId());
5318 }
5319
5320
5350 @Override
5351 public JournalArticle updateArticle(
5352 long userId, long groupId, long folderId, String articleId,
5353 double version, String content, ServiceContext serviceContext)
5354 throws PortalException {
5355
5356 JournalArticle article = journalArticlePersistence.findByG_A_V(
5357 groupId, articleId, version);
5358
5359 return journalArticleLocalService.updateArticle(
5360 userId, groupId, folderId, articleId, version,
5361 article.getTitleMap(), article.getDescriptionMap(), content,
5362 article.getLayoutUuid(), serviceContext);
5363 }
5364
5365
5370 @Deprecated
5371 @Override
5372 public JournalArticle updateArticleTranslation(
5373 long groupId, String articleId, double version, Locale locale,
5374 String title, String description, String content,
5375 Map<String, byte[]> images)
5376 throws PortalException {
5377
5378 return journalArticleLocalService.updateArticleTranslation(
5379 groupId, articleId, version, locale, title, description, content,
5380 images, null);
5381 }
5382
5383
5406 @Indexable(type = IndexableType.REINDEX)
5407 @Override
5408 public JournalArticle updateArticleTranslation(
5409 long groupId, String articleId, double version, Locale locale,
5410 String title, String description, String content,
5411 Map<String, byte[]> images, ServiceContext serviceContext)
5412 throws PortalException {
5413
5414 validateContent(content);
5415
5416 JournalArticle oldArticle = getLatestArticle(
5417 groupId, articleId, WorkflowConstants.STATUS_ANY);
5418
5419 double oldVersion = oldArticle.getVersion();
5420
5421 if ((version > 0) && (version != oldVersion)) {
5422 throw new ArticleVersionException();
5423 }
5424
5425 boolean incrementVersion = false;
5426
5427 if (oldArticle.isApproved() || oldArticle.isExpired()) {
5428 incrementVersion = true;
5429 }
5430
5431 if (serviceContext != null) {
5432 serviceContext.validateModifiedDate(
5433 oldArticle, ArticleVersionException.class);
5434 }
5435
5436 JournalArticle article = null;
5437
5438 User user = userPersistence.fetchByC_U(
5439 oldArticle.getCompanyId(), oldArticle.getUserId());
5440
5441 if (user == null) {
5442 user = userPersistence.fetchByC_DU(oldArticle.getCompanyId(), true);
5443 }
5444
5445 Locale defaultLocale = getArticleDefaultLocale(content);
5446
5447 if (incrementVersion) {
5448 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
5449
5450 long id = counterLocalService.increment();
5451
5452 article = journalArticlePersistence.create(id);
5453
5454 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
5455 article.setGroupId(oldArticle.getGroupId());
5456 article.setCompanyId(oldArticle.getCompanyId());
5457 article.setUserId(oldArticle.getUserId());
5458 article.setUserName(user.getFullName());
5459 article.setCreateDate(oldArticle.getCreateDate());
5460 article.setFolderId(oldArticle.getFolderId());
5461 article.setClassNameId(oldArticle.getClassNameId());
5462 article.setClassPK(oldArticle.getClassPK());
5463 article.setArticleId(articleId);
5464 article.setVersion(newVersion);
5465 article.setTitleMap(oldArticle.getTitleMap(), defaultLocale);
5466 article.setUrlTitle(
5467 getUniqueUrlTitle(
5468 id, groupId, articleId, title, oldArticle.getUrlTitle(),
5469 serviceContext));
5470 article.setDescriptionMap(oldArticle.getDescriptionMap());
5471 article.setDDMStructureKey(oldArticle.getDDMStructureKey());
5472 article.setDDMTemplateKey(oldArticle.getDDMTemplateKey());
5473 article.setLayoutUuid(oldArticle.getLayoutUuid());
5474 article.setDisplayDate(oldArticle.getDisplayDate());
5475 article.setExpirationDate(oldArticle.getExpirationDate());
5476 article.setReviewDate(oldArticle.getReviewDate());
5477 article.setIndexable(oldArticle.getIndexable());
5478 article.setSmallImage(oldArticle.getSmallImage());
5479 article.setSmallImageId(oldArticle.getSmallImageId());
5480
5481 if (article.getSmallImageId() == 0) {
5482 article.setSmallImageId(counterLocalService.increment());
5483 }
5484
5485 article.setSmallImageURL(oldArticle.getSmallImageURL());
5486
5487 article.setStatus(WorkflowConstants.STATUS_DRAFT);
5488 article.setStatusDate(new Date());
5489
5490 ExpandoBridgeUtil.copyExpandoBridgeAttributes(
5491 oldArticle.getExpandoBridge(), article.getExpandoBridge());
5492
5493
5494
5495 updateDDMLinks(
5496 id, groupId, oldArticle.getDDMStructureKey(),
5497 oldArticle.getDDMTemplateKey(), true);
5498 }
5499 else {
5500 article = oldArticle;
5501 }
5502
5503 Map<Locale, String> titleMap = article.getTitleMap();
5504
5505 titleMap.put(locale, title);
5506
5507 article.setTitleMap(titleMap, defaultLocale);
5508
5509 Map<Locale, String> descriptionMap = article.getDescriptionMap();
5510
5511 descriptionMap.put(locale, description);
5512
5513 article.setDescriptionMap(descriptionMap);
5514
5515 content = format(
5516 user, groupId, articleId, article.getVersion(),
5517 !oldArticle.isDraft(), content, images);
5518
5519 article.setContent(content);
5520
5521 journalArticlePersistence.update(article);
5522
5523 return article;
5524 }
5525
5526
5538 @Override
5539 public void updateAsset(
5540 long userId, JournalArticle article, long[] assetCategoryIds,
5541 String[] assetTagNames, long[] assetLinkEntryIds)
5542 throws PortalException {
5543
5544 boolean visible = article.isApproved();
5545
5546 if (article.getClassNameId() !=
5547 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5548
5549 visible = false;
5550 }
5551
5552 boolean addDraftAssetEntry = false;
5553
5554 if (!article.isApproved() &&
5555 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
5556
5557 int approvedArticlesCount = journalArticlePersistence.countByG_A_ST(
5558 article.getGroupId(), article.getArticleId(),
5559 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
5560
5561 if (approvedArticlesCount > 0) {
5562 addDraftAssetEntry = true;
5563 }
5564 }
5565
5566 AssetEntry assetEntry = null;
5567
5568 if (addDraftAssetEntry) {
5569 assetEntry = assetEntryLocalService.updateEntry(
5570 userId, article.getGroupId(), article.getCreateDate(),
5571 article.getModifiedDate(), JournalArticle.class.getName(),
5572 article.getPrimaryKey(), article.getUuid(),
5573 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
5574 null, null, null, ContentTypes.TEXT_HTML, article.getTitle(),
5575 article.getDescription(), article.getDescription(), null,
5576 article.getLayoutUuid(), 0, 0, null);
5577 }
5578 else {
5579 JournalArticleResource journalArticleResource =
5580 journalArticleResourceLocalService.getArticleResource(
5581 article.getResourcePrimKey());
5582
5583 assetEntry = assetEntryLocalService.updateEntry(
5584 userId, article.getGroupId(), article.getCreateDate(),
5585 article.getModifiedDate(), JournalArticle.class.getName(),
5586 journalArticleResource.getResourcePrimKey(),
5587 journalArticleResource.getUuid(), getClassTypeId(article),
5588 assetCategoryIds, assetTagNames, visible, null, null, null,
5589 ContentTypes.TEXT_HTML, article.getTitle(),
5590 article.getDescription(), article.getDescription(), null,
5591 article.getLayoutUuid(), 0, 0, null);
5592 }
5593
5594 assetLinkLocalService.updateLinks(
5595 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5596 AssetLinkConstants.TYPE_RELATED);
5597 }
5598
5599
5616 @Indexable(type = IndexableType.REINDEX)
5617 @Override
5618 public JournalArticle updateContent(
5619 long groupId, String articleId, double version, String content)
5620 throws PortalException {
5621
5622 JournalArticle article = journalArticlePersistence.findByG_A_V(
5623 groupId, articleId, version);
5624
5625 article.setContent(content);
5626
5627 journalArticlePersistence.update(article);
5628
5629 return article;
5630 }
5631
5632
5646 @Override
5647 public void updateDDMTemplateKey(
5648 long groupId, long classNameId, String oldDDMTemplateKey,
5649 String newDDMTemplateKey) {
5650
5651 List<JournalArticle> articles =
5652 journalArticlePersistence.findByG_C_DDMTK(
5653 groupId, classNameId, oldDDMTemplateKey);
5654
5655 for (JournalArticle article : articles) {
5656 article.setDDMTemplateKey(newDDMTemplateKey);
5657
5658 journalArticlePersistence.update(article);
5659 }
5660 }
5661
5662
5684 @Indexable(type = IndexableType.REINDEX)
5685 @Override
5686 public JournalArticle updateStatus(
5687 long userId, JournalArticle article, int status, String articleURL,
5688 ServiceContext serviceContext,
5689 Map<String, Serializable> workflowContext)
5690 throws PortalException {
5691
5692
5693
5694 User user = userPersistence.findByPrimaryKey(userId);
5695 Date now = new Date();
5696
5697 if ((status == WorkflowConstants.STATUS_APPROVED) &&
5698 (article.getClassNameId() ==
5699 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5700 (article.getDisplayDate() != null) &&
5701 now.before(article.getDisplayDate())) {
5702
5703 status = WorkflowConstants.STATUS_SCHEDULED;
5704 }
5705
5706 int oldStatus = article.getStatus();
5707
5708 if (status == WorkflowConstants.STATUS_APPROVED) {
5709 Date expirationDate = article.getExpirationDate();
5710
5711 if ((expirationDate != null) && expirationDate.before(now)) {
5712 article.setExpirationDate(null);
5713 }
5714 }
5715
5716 if (status == WorkflowConstants.STATUS_EXPIRED) {
5717 article.setExpirationDate(now);
5718 }
5719
5720 article.setStatus(status);
5721 article.setStatusByUserId(user.getUserId());
5722 article.setStatusByUserName(user.getFullName());
5723 article.setStatusDate(serviceContext.getModifiedDate(now));
5724
5725 journalArticlePersistence.update(article);
5726
5727 if (hasModifiedLatestApprovedVersion(
5728 article.getGroupId(), article.getArticleId(),
5729 article.getVersion())) {
5730
5731 if (status == WorkflowConstants.STATUS_APPROVED) {
5732 updateUrlTitles(
5733 article.getGroupId(), article.getArticleId(),
5734 article.getUrlTitle());
5735
5736
5737
5738 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
5739 (article.getVersion() !=
5740 JournalArticleConstants.VERSION_DEFAULT)) {
5741
5742 AssetEntry draftAssetEntry =
5743 assetEntryLocalService.fetchEntry(
5744 JournalArticle.class.getName(),
5745 article.getPrimaryKey());
5746
5747 if (draftAssetEntry != null) {
5748 long[] assetCategoryIds =
5749 draftAssetEntry.getCategoryIds();
5750 String[] assetTagNames = draftAssetEntry.getTagNames();
5751
5752 List<AssetLink> assetLinks =
5753 assetLinkLocalService.getDirectLinks(
5754 draftAssetEntry.getEntryId(),
5755 AssetLinkConstants.TYPE_RELATED);
5756
5757 long[] assetLinkEntryIds = ListUtil.toLongArray(
5758 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR);
5759
5760 AssetEntry assetEntry =
5761 assetEntryLocalService.updateEntry(
5762 userId, article.getGroupId(),
5763 article.getCreateDate(),
5764 article.getModifiedDate(),
5765 JournalArticle.class.getName(),
5766 article.getResourcePrimKey(), article.getUuid(),
5767 getClassTypeId(article), assetCategoryIds,
5768 assetTagNames, false, null, null, null,
5769 ContentTypes.TEXT_HTML, article.getTitle(),
5770 article.getDescription(),
5771 article.getDescription(), null,
5772 article.getLayoutUuid(), 0, 0, null);
5773
5774 assetLinkLocalService.updateLinks(
5775 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5776 AssetLinkConstants.TYPE_RELATED);
5777
5778 assetEntryLocalService.deleteEntry(draftAssetEntry);
5779 }
5780 }
5781
5782 if (article.getClassNameId() ==
5783 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5784
5785 assetEntryLocalService.updateEntry(
5786 JournalArticle.class.getName(),
5787 article.getResourcePrimKey(), article.getDisplayDate(),
5788 article.getExpirationDate(), true);
5789 }
5790
5791
5792
5793 JSONObject extraDataJSONObject =
5794 JSONFactoryUtil.createJSONObject();
5795
5796 extraDataJSONObject.put("title", article.getTitle());
5797
5798 if (serviceContext.isCommandUpdate()) {
5799 socialActivityLocalService.addActivity(
5800 user.getUserId(), article.getGroupId(),
5801 JournalArticle.class.getName(),
5802 article.getResourcePrimKey(),
5803 JournalActivityKeys.UPDATE_ARTICLE,
5804 extraDataJSONObject.toString(), 0);
5805 }
5806 else {
5807 socialActivityLocalService.addUniqueActivity(
5808 user.getUserId(), article.getGroupId(),
5809 JournalArticle.class.getName(),
5810 article.getResourcePrimKey(),
5811 JournalActivityKeys.ADD_ARTICLE,
5812 extraDataJSONObject.toString(), 0);
5813 }
5814 }
5815 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
5816 updatePreviousApprovedArticle(article);
5817 }
5818 }
5819
5820 if ((article.getClassNameId() ==
5821 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5822 (oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
5823 (status != WorkflowConstants.STATUS_IN_TRASH)) {
5824
5825
5826
5827 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
5828 ((status == WorkflowConstants.STATUS_APPROVED) ||
5829 (status == WorkflowConstants.STATUS_DENIED))) {
5830
5831 String msg = "granted";
5832
5833 if (status == WorkflowConstants.STATUS_DENIED) {
5834 msg = "denied";
5835 }
5836
5837 try {
5838 PortletPreferences preferences =
5839 ServiceContextUtil.getPortletPreferences(
5840 serviceContext);
5841
5842 articleURL = buildArticleURL(
5843 articleURL, article.getGroupId(), article.getFolderId(),
5844 article.getArticleId());
5845
5846 sendEmail(
5847 article, articleURL, preferences, msg, serviceContext);
5848 }
5849 catch (Exception e) {
5850 _log.error(
5851 "Unable to send email to notify the change of status " +
5852 " to " + msg + " for article " + article.getId() +
5853 ": " + e.getMessage());
5854 }
5855 }
5856
5857
5858
5859 String action = "update";
5860
5861 if (article.getVersion() == 1.0) {
5862 action = "add";
5863 }
5864
5865 notifySubscribers(
5866 user.getUserId(), article,
5867 (String)workflowContext.get(WorkflowConstants.CONTEXT_URL),
5868 action, serviceContext);
5869 }
5870
5871 return article;
5872 }
5873
5874
5894 @Override
5895 public JournalArticle updateStatus(
5896 long userId, long classPK, int status,
5897 Map<String, Serializable> workflowContext,
5898 ServiceContext serviceContext)
5899 throws PortalException {
5900
5901 JournalArticle article = getArticle(classPK);
5902
5903 return journalArticleLocalService.updateStatus(
5904 userId, article, status, null, serviceContext, workflowContext);
5905 }
5906
5907
5928 @Override
5929 public JournalArticle updateStatus(
5930 long userId, long groupId, String articleId, double version,
5931 int status, String articleURL,
5932 Map<String, Serializable> workflowContext,
5933 ServiceContext serviceContext)
5934 throws PortalException {
5935
5936 JournalArticle article = journalArticlePersistence.findByG_A_V(
5937 groupId, articleId, version);
5938
5939 return journalArticleLocalService.updateStatus(
5940 userId, article, status, articleURL, serviceContext,
5941 workflowContext);
5942 }
5943
5944
5960 @Deprecated
5961 @Override
5962 public void updateTemplateId(
5963 long groupId, long classNameId, String oldDDMTemplateKey,
5964 String newDDMTemplateKey) {
5965
5966 updateDDMTemplateKey(
5967 groupId, classNameId, oldDDMTemplateKey, newDDMTemplateKey);
5968 }
5969
5970 protected String buildArticleURL(
5971 String articleURL, long groupId, long folderId, String articleId) {
5972
5973 StringBundler sb = new StringBundler(13);
5974
5975 sb.append(articleURL);
5976 sb.append(StringPool.AMPERSAND);
5977
5978 String portletId = PortletProviderUtil.getPortletId(
5979 JournalArticle.class.getName(), PortletProvider.Action.EDIT);
5980
5981 sb.append(PortalUtil.getPortletNamespace(portletId));
5982
5983 sb.append("groupId=");
5984 sb.append(groupId);
5985 sb.append(StringPool.AMPERSAND);
5986 sb.append(PortalUtil.getPortletNamespace(portletId));
5987 sb.append("folderId=");
5988 sb.append(folderId);
5989 sb.append(StringPool.AMPERSAND);
5990 sb.append(PortalUtil.getPortletNamespace(portletId));
5991 sb.append("articleId=");
5992 sb.append(articleId);
5993
5994 return sb.toString();
5995 }
5996
5997 protected SearchContext buildSearchContext(
5998 long companyId, long groupId, List<Long> folderIds, long classNameId,
5999 String articleId, String title, String description, String content,
6000 int status, String ddmStructureKey, String ddmTemplateKey,
6001 LinkedHashMap<String, Object> params, boolean andSearch, int start,
6002 int end, Sort sort) {
6003
6004 SearchContext searchContext = new SearchContext();
6005
6006 searchContext.setAndSearch(andSearch);
6007
6008 Map<String, Serializable> attributes = new HashMap<>();
6009
6010 attributes.put(Field.ARTICLE_ID, articleId);
6011 attributes.put(Field.CLASS_NAME_ID, classNameId);
6012 attributes.put(Field.CONTENT, content);
6013 attributes.put(Field.DESCRIPTION, description);
6014 attributes.put(Field.STATUS, status);
6015 attributes.put(Field.TITLE, title);
6016 attributes.put("ddmStructureKey", ddmStructureKey);
6017 attributes.put("ddmTemplateKey", ddmTemplateKey);
6018 attributes.put("params", params);
6019
6020 searchContext.setAttributes(attributes);
6021
6022 searchContext.setCompanyId(companyId);
6023 searchContext.setEnd(end);
6024 searchContext.setFolderIds(folderIds);
6025 searchContext.setGroupIds(new long[] {groupId});
6026 searchContext.setIncludeDiscussions(
6027 GetterUtil.getBoolean(params.get("includeDiscussions")));
6028
6029 if (params != null) {
6030 String keywords = (String)params.remove("keywords");
6031
6032 if (Validator.isNotNull(keywords)) {
6033 searchContext.setKeywords(keywords);
6034 }
6035 }
6036
6037 QueryConfig queryConfig = new QueryConfig();
6038
6039 queryConfig.setHighlightEnabled(false);
6040 queryConfig.setScoreEnabled(false);
6041
6042 searchContext.setQueryConfig(queryConfig);
6043
6044 if (sort != null) {
6045 searchContext.setSorts(sort);
6046 }
6047
6048 searchContext.setStart(start);
6049
6050 return searchContext;
6051 }
6052
6053 protected SearchContext buildSearchContext(
6054 long groupId, long userId, long creatorUserId, int status,
6055 int start, int end)
6056 throws PortalException {
6057
6058 SearchContext searchContext = new SearchContext();
6059
6060 searchContext.setAttribute(Field.STATUS, status);
6061
6062 searchContext.setAttribute("paginationType", "none");
6063
6064 if (creatorUserId > 0) {
6065 searchContext.setAttribute(
6066 Field.USER_ID, String.valueOf(creatorUserId));
6067 }
6068
6069 Group group = groupLocalService.getGroup(groupId);
6070
6071 searchContext.setCompanyId(group.getCompanyId());
6072
6073 searchContext.setEnd(end);
6074 searchContext.setGroupIds(new long[] {groupId});
6075 searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true));
6076 searchContext.setStart(start);
6077 searchContext.setUserId(userId);
6078
6079 return searchContext;
6080 }
6081
6082 protected void checkArticlesByDisplayDate(Date displayDate)
6083 throws PortalException {
6084
6085 String portletId = PortletProviderUtil.getPortletId(
6086 JournalArticle.class.getName(), PortletProvider.Action.EDIT);
6087
6088 List<JournalArticle> articles = journalArticlePersistence.findByLtD_S(
6089 displayDate, WorkflowConstants.STATUS_SCHEDULED);
6090
6091 for (JournalArticle article : articles) {
6092 ServiceContext serviceContext = new ServiceContext();
6093
6094 serviceContext.setCommand(Constants.UPDATE);
6095
6096 String layoutFullURL = PortalUtil.getLayoutFullURL(
6097 article.getGroupId(), portletId);
6098
6099 serviceContext.setLayoutFullURL(layoutFullURL);
6100
6101 serviceContext.setScopeGroupId(article.getGroupId());
6102
6103 journalArticleLocalService.updateStatus(
6104 article.getUserId(), article, WorkflowConstants.STATUS_APPROVED,
6105 null, serviceContext, new HashMap<String, Serializable>());
6106 }
6107 }
6108
6109 protected void checkArticlesByExpirationDate(Date expirationDate)
6110 throws PortalException {
6111
6112 List<JournalArticle> articles =
6113 journalArticleFinder.findByExpirationDate(
6114 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
6115 new Date(
6116 expirationDate.getTime() + _JOURNAL_ARTICLE_CHECK_INTERVAL),
6117 new QueryDefinition<JournalArticle>(
6118 WorkflowConstants.STATUS_APPROVED));
6119
6120 if (_log.isDebugEnabled()) {
6121 _log.debug("Expiring " + articles.size() + " articles");
6122 }
6123
6124 Set<Long> companyIds = new HashSet<>();
6125
6126 for (JournalArticle article : articles) {
6127 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
6128 List<JournalArticle> currentArticles =
6129 journalArticlePersistence.findByG_A(
6130 article.getGroupId(), article.getArticleId(),
6131 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
6132 new ArticleVersionComparator(true));
6133
6134 for (JournalArticle currentArticle : currentArticles) {
6135 currentArticle.setExpirationDate(
6136 article.getExpirationDate());
6137 currentArticle.setStatus(WorkflowConstants.STATUS_EXPIRED);
6138
6139 journalArticlePersistence.update(currentArticle);
6140 }
6141 }
6142 else {
6143 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
6144
6145 journalArticlePersistence.update(article);
6146 }
6147
6148 updatePreviousApprovedArticle(article);
6149
6150 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6151 JournalArticle.class);
6152
6153 indexer.reindex(article);
6154
6155 JournalContentUtil.clearCache(
6156 article.getGroupId(), article.getArticleId(),
6157 article.getDDMTemplateKey());
6158
6159 companyIds.add(article.getCompanyId());
6160 }
6161
6162 for (long companyId : companyIds) {
6163 CacheUtil.clearCache(companyId);
6164 }
6165
6166 if (_previousCheckDate == null) {
6167 _previousCheckDate = new Date(
6168 expirationDate.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL);
6169 }
6170 }
6171
6172 protected void checkArticlesByReviewDate(Date reviewDate)
6173 throws PortalException {
6174
6175 List<JournalArticle> latestArticles = new ArrayList<>();
6176
6177 List<JournalArticle> articles = journalArticleFinder.findByReviewDate(
6178 JournalArticleConstants.CLASSNAME_ID_DEFAULT, reviewDate,
6179 _previousCheckDate);
6180
6181 for (JournalArticle article : articles) {
6182 long groupId = article.getGroupId();
6183 String articleId = article.getArticleId();
6184 double version = article.getVersion();
6185
6186 if (!journalArticleLocalService.isLatestVersion(
6187 groupId, articleId, version)) {
6188
6189 article = journalArticleLocalService.getLatestArticle(
6190 groupId, articleId);
6191 }
6192
6193 if (!latestArticles.contains(article)) {
6194 if (_log.isDebugEnabled()) {
6195 _log.debug(
6196 "Sending review notification for article " +
6197 article.getId());
6198 }
6199
6200 latestArticles.add(article);
6201
6202 String articleURL = StringPool.BLANK;
6203
6204 long ownerId = article.getGroupId();
6205 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
6206 long plid = PortletKeys.PREFS_PLID_SHARED;
6207 String portletId = PortletProviderUtil.getPortletId(
6208 JournalArticle.class.getName(),
6209 PortletProvider.Action.EDIT);
6210
6211 PortletPreferences preferences =
6212 portletPreferencesLocalService.getPreferences(
6213 article.getCompanyId(), ownerId, ownerType, plid,
6214 portletId);
6215
6216 sendEmail(
6217 article, articleURL, preferences, "review",
6218 new ServiceContext());
6219 }
6220 }
6221 }
6222
6223 protected void checkStructure(Document contentDocument, DDMForm ddmForm)
6224 throws PortalException {
6225
6226 for (DDMFormField ddmFormField : ddmForm.getDDMFormFields()) {
6227 checkStructureField(ddmFormField, contentDocument.getRootElement());
6228 }
6229 }
6230
6231 protected void checkStructure(JournalArticle article)
6232 throws PortalException {
6233
6234 DDMStructure ddmStructure = article.getDDMStructure();
6235
6236 try {
6237 checkStructure(article, ddmStructure);
6238 }
6239 catch (StructureDefinitionException sde) {
6240 if (_log.isWarnEnabled()) {
6241 StringBundler sb = new StringBundler(8);
6242
6243 sb.append("Article {groupId=");
6244 sb.append(article.getGroupId());
6245 sb.append(", articleId=");
6246 sb.append(article.getArticleId());
6247 sb.append(", version=");
6248 sb.append(article.getVersion());
6249 sb.append("} has content that does not match its structure: ");
6250 sb.append(sde.getMessage());
6251
6252 _log.warn(sb.toString());
6253 }
6254 }
6255 }
6256
6257 protected void checkStructure(
6258 JournalArticle article, DDMStructure ddmStructure)
6259 throws PortalException {
6260
6261 checkStructure(article.getDocument(), ddmStructure.getDDMForm());
6262 }
6263
6264 protected void checkStructureField(
6265 DDMFormField ddmFormField, Element contentElement)
6266 throws PortalException {
6267
6268 String fieldName = ddmFormField.getName();
6269
6270 boolean hasField = false;
6271
6272 for (Element childElement : contentElement.elements()) {
6273 if (fieldName.equals(
6274 childElement.attributeValue("name", StringPool.BLANK))) {
6275
6276 hasField = true;
6277
6278 for (DDMFormField childDDMFormField :
6279 ddmFormField.getNestedDDMFormFields()) {
6280
6281 checkStructureField(childDDMFormField, childElement);
6282 }
6283
6284 break;
6285 }
6286 }
6287
6288 if (!hasField) {
6289 String contentElementType = contentElement.attributeValue(
6290 "type", StringPool.BLANK);
6291
6292 if (!contentElementType.equals("list") &&
6293 !contentElementType.equals("multi-list")) {
6294
6295 throw new StructureDefinitionException(fieldName);
6296 }
6297 }
6298 }
6299
6300 protected void copyArticleImages(
6301 JournalArticle oldArticle, JournalArticle newArticle)
6302 throws Exception {
6303
6304 Document contentDocument = oldArticle.getDocument();
6305
6306 contentDocument = contentDocument.clone();
6307
6308 XPath xPathSelector = SAXReaderUtil.createXPath(
6309 "
6310
6311 List<Node> imageNodes = xPathSelector.selectNodes(contentDocument);
6312
6313 for (Node imageNode : imageNodes) {
6314 Element imageEl = (Element)imageNode;
6315
6316 String elInstanceId = imageEl.attributeValue("instance-id");
6317 String elName = imageEl.attributeValue("name");
6318 String elIndex = imageEl.attributeValue("index");
6319
6320 String name = elName + StringPool.UNDERLINE + elIndex;
6321
6322 List<Element> dynamicContentEls = imageEl.elements(
6323 "dynamic-content");
6324
6325 for (Element dynamicContentEl : dynamicContentEls) {
6326 long imageId = GetterUtil.getLong(
6327 dynamicContentEl.attributeValue("id"));
6328 String languageId =
6329 StringPool.UNDERLINE +
6330 dynamicContentEl.attributeValue("language-id");
6331
6332 Image oldImage = imageLocalService.fetchImage(imageId);
6333
6334 if (oldImage == null) {
6335 continue;
6336 }
6337
6338 imageId = journalArticleImageLocalService.getArticleImageId(
6339 newArticle.getGroupId(), newArticle.getArticleId(),
6340 newArticle.getVersion(), elInstanceId, name, languageId);
6341
6342 imageLocalService.updateImage(imageId, oldImage.getTextObj());
6343
6344 String elContent =
6345 "/image/journal/article?img_id=" + imageId + "&t=" +
6346 WebServerServletTokenUtil.getToken(imageId);
6347
6348 dynamicContentEl.setText(elContent);
6349 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
6350 }
6351 }
6352
6353 newArticle.setContent(contentDocument.formattedString());
6354 }
6355
6356 protected Map<String, String> createFieldsValuesMap(Element parentElement) {
6357 Map<String, String> fieldsValuesMap = new HashMap<>();
6358
6359 List<Element> dynamicElementElements = parentElement.elements(
6360 "dynamic-element");
6361
6362 for (Element dynamicElementElement : dynamicElementElements) {
6363 String fieldName = dynamicElementElement.attributeValue(
6364 "name", StringPool.BLANK);
6365
6366 List<Element> dynamicContentElements =
6367 dynamicElementElement.elements("dynamic-content");
6368
6369 for (Element dynamicContentElement : dynamicContentElements) {
6370 String value = dynamicContentElement.getText();
6371
6372 fieldsValuesMap.put(fieldName, value);
6373 }
6374
6375 fieldsValuesMap.putAll(
6376 createFieldsValuesMap(dynamicElementElement));
6377 }
6378
6379 return fieldsValuesMap;
6380 }
6381
6382 protected Map<String, String> createFieldsValuesMap(String content) {
6383 try {
6384 Document document = SAXReaderUtil.read(content);
6385
6386 Element rootElement = document.getRootElement();
6387
6388 return createFieldsValuesMap(rootElement);
6389 }
6390 catch (DocumentException de) {
6391 throw new SystemException(de);
6392 }
6393 }
6394
6395 protected void format(
6396 User user, long groupId, String articleId, double version,
6397 boolean incrementVersion, Element root, Map<String, byte[]> images)
6398 throws PortalException {
6399
6400 for (Element element : root.elements()) {
6401 String elInstanceId = element.attributeValue(
6402 "instance-id", StringPool.BLANK);
6403 String elType = element.attributeValue("type", StringPool.BLANK);
6404
6405 if (elType.equals("document_library")) {
6406 formatDocumentLibrary(element);
6407 }
6408 else if (elType.equals("image")) {
6409 String elName = element.attributeValue(
6410 "name", StringPool.BLANK);
6411 String elIndex = element.attributeValue(
6412 "index", StringPool.BLANK);
6413
6414 String name = elName + StringPool.UNDERLINE + elIndex;
6415
6416 formatImage(
6417 groupId, articleId, version, incrementVersion, element,
6418 elInstanceId, name, images);
6419 }
6420 else if (elType.equals("text_area") || elType.equals("text") ||
6421 elType.equals("text_box")) {
6422
6423 List<Element> dynamicContentElements = element.elements(
6424 "dynamic-content");
6425
6426 for (Element dynamicContentElement : dynamicContentElements) {
6427 String dynamicContent = dynamicContentElement.getText();
6428
6429 if (Validator.isNotNull(dynamicContent)) {
6430 String contentType = ContentTypes.TEXT_PLAIN;
6431
6432 if (elType.equals("text_area")) {
6433 contentType = ContentTypes.TEXT_HTML;
6434 }
6435
6436 dynamicContent = SanitizerUtil.sanitize(
6437 user.getCompanyId(), groupId, user.getUserId(),
6438 JournalArticle.class.getName(), 0, contentType,
6439 dynamicContent);
6440
6441 dynamicContentElement.clearContent();
6442
6443 dynamicContentElement.addCDATA(dynamicContent);
6444 }
6445 }
6446 }
6447
6448 format(
6449 user, groupId, articleId, version, incrementVersion, element,
6450 images);
6451 }
6452 }
6453
6454 protected String format(
6455 User user, long groupId, String articleId, double version,
6456 boolean incrementVersion, String content,
6457 Map<String, byte[]> images)
6458 throws PortalException {
6459
6460 Document document = null;
6461
6462 try {
6463 document = SAXReaderUtil.read(content);
6464
6465 Element rootElement = document.getRootElement();
6466
6467 format(
6468 user, groupId, articleId, version, incrementVersion,
6469 rootElement, images);
6470
6471 content = DDMXMLUtil.formatXML(document);
6472 }
6473 catch (DocumentException de) {
6474 _log.error(de, de);
6475 }
6476
6477 return content;
6478 }
6479
6480 protected void formatDocumentLibrary(Element dynamicElementElement)
6481 throws PortalException {
6482
6483 if (ExportImportThreadLocal.isImportInProcess()) {
6484 return;
6485 }
6486
6487 for (Element dynamicContentElement :
6488 dynamicElementElement.elements("dynamic-content")) {
6489
6490 String value = dynamicContentElement.getText();
6491
6492 if (Validator.isNull(value)) {
6493 continue;
6494 }
6495
6496 JSONObject jsonObject = JSONFactoryUtil.createJSONObject(value);
6497
6498 String uuid = jsonObject.getString("uuid");
6499 long groupId = jsonObject.getLong("groupId");
6500 boolean tempFile = jsonObject.getBoolean("tempFile");
6501
6502 FileEntry fileEntry =
6503 dlAppLocalService.getFileEntryByUuidAndGroupId(uuid, groupId);
6504
6505 if (tempFile) {
6506 String fileEntryName = DLUtil.getFileName(
6507 fileEntry.getGroupId(), fileEntry.getFolderId(),
6508 fileEntry.getFileName());
6509
6510 fileEntry = dlAppLocalService.addFileEntry(
6511 fileEntry.getUserId(), fileEntry.getGroupId(), 0,
6512 fileEntryName, fileEntry.getMimeType(), fileEntryName,
6513 StringPool.BLANK, StringPool.BLANK,
6514 fileEntry.getContentStream(), fileEntry.getSize(),
6515 new ServiceContext());
6516 }
6517
6518 String previewURL = DLUtil.getPreviewURL(
6519 fileEntry, fileEntry.getFileVersion(), null, StringPool.BLANK,
6520 false, true);
6521
6522 dynamicContentElement.clearContent();
6523
6524 dynamicContentElement.addCDATA(previewURL);
6525 }
6526 }
6527
6528 protected void formatImage(
6529 long groupId, String articleId, double version,
6530 boolean incrementVersion, Element el, String elInstanceId,
6531 String elName, Map<String, byte[]> images)
6532 throws PortalException {
6533
6534 List<Element> imageContents = el.elements("dynamic-content");
6535
6536 for (Element dynamicContent : imageContents) {
6537 String elLanguage = dynamicContent.attributeValue(
6538 "language-id", StringPool.BLANK);
6539
6540 if (!elLanguage.equals(StringPool.BLANK)) {
6541 elLanguage = "_" + elLanguage;
6542 }
6543
6544 long imageId = journalArticleImageLocalService.getArticleImageId(
6545 groupId, articleId, version, elInstanceId, elName, elLanguage);
6546
6547 if (dynamicContent.getText().equals("delete") ||
6548 Validator.isNull(dynamicContent.getText())) {
6549
6550 dynamicContent.setText(StringPool.BLANK);
6551
6552 imageLocalService.deleteImage(imageId);
6553
6554 String defaultElLanguage = "";
6555
6556 if (Validator.isNull(elLanguage)) {
6557 defaultElLanguage =
6558 "_" +
6559 LocaleUtil.toLanguageId(
6560 LocaleUtil.getSiteDefault());
6561 }
6562
6563 long defaultImageId =
6564 journalArticleImageLocalService.getArticleImageId(
6565 groupId, articleId, version, elInstanceId, elName,
6566 defaultElLanguage);
6567
6568 imageLocalService.deleteImage(defaultImageId);
6569
6570 continue;
6571 }
6572
6573 String elContent =
6574 "/image/journal/article?img_id=" + imageId + "&t=" +
6575 WebServerServletTokenUtil.getToken(imageId);
6576
6577 byte[] bytes = null;
6578
6579 if (images != null) {
6580 bytes = images.get(elInstanceId + "_" + elName + elLanguage);
6581 }
6582
6583 if (ArrayUtil.isNotEmpty(bytes)) {
6584 dynamicContent.setText(elContent);
6585 dynamicContent.addAttribute("id", String.valueOf(imageId));
6586
6587 imageLocalService.updateImage(imageId, bytes);
6588
6589 continue;
6590 }
6591
6592 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
6593 incrementVersion) {
6594
6595 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
6596
6597 long oldImageId = 0;
6598
6599 if ((oldVersion >= 1) && incrementVersion) {
6600 oldImageId =
6601 journalArticleImageLocalService.getArticleImageId(
6602 groupId, articleId, oldVersion, elInstanceId,
6603 elName, elLanguage);
6604 }
6605
6606 Image oldImage = null;
6607
6608 if (oldImageId > 0) {
6609 oldImage = imageLocalService.getImage(oldImageId);
6610 }
6611
6612 if (oldImage != null) {
6613 dynamicContent.setText(elContent);
6614 dynamicContent.addAttribute("id", String.valueOf(imageId));
6615
6616 bytes = oldImage.getTextObj();
6617
6618 imageLocalService.updateImage(imageId, bytes);
6619 }
6620 else if (dynamicContent.getText().equals("update")) {
6621 dynamicContent.setText(StringPool.BLANK);
6622 }
6623
6624 continue;
6625 }
6626
6627 Image image = imageLocalService.getImage(imageId);
6628
6629 if (image != null) {
6630 dynamicContent.setText(elContent);
6631 dynamicContent.addAttribute("id", String.valueOf(imageId));
6632
6633 continue;
6634 }
6635 else if (dynamicContent.getText().equals("update")) {
6636 dynamicContent.setText(StringPool.BLANK);
6637
6638 continue;
6639 }
6640
6641 long contentImageId = GetterUtil.getLong(
6642 HttpUtil.getParameter(dynamicContent.getText(), "img_id"));
6643
6644 if (contentImageId <= 0) {
6645 contentImageId = GetterUtil.getLong(
6646 HttpUtil.getParameter(
6647 dynamicContent.getText(), "img_id", false));
6648 }
6649
6650 if (contentImageId > 0) {
6651 image = imageLocalService.getImage(contentImageId);
6652
6653 if (image != null) {
6654 dynamicContent.addAttribute(
6655 "id", String.valueOf(contentImageId));
6656
6657 continue;
6658 }
6659 }
6660
6661 String defaultElLanguage = "";
6662
6663 if (Validator.isNull(elLanguage)) {
6664 defaultElLanguage =
6665 "_" + LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
6666 }
6667
6668 long defaultImageId =
6669 journalArticleImageLocalService.getArticleImageId(
6670 groupId, articleId, version, elInstanceId, elName,
6671 defaultElLanguage);
6672
6673 Image defaultImage = imageLocalService.getImage(defaultImageId);
6674
6675 if (defaultImage != null) {
6676 dynamicContent.setText(elContent);
6677 dynamicContent.addAttribute(
6678 "id", String.valueOf(defaultImageId));
6679
6680 bytes = defaultImage.getTextObj();
6681
6682 imageLocalService.updateImage(defaultImageId, bytes);
6683
6684 continue;
6685 }
6686
6687 if (Validator.isNotNull(elLanguage)) {
6688 dynamicContent.setText(StringPool.BLANK);
6689 }
6690 }
6691 }
6692
6693 protected Locale getArticleDefaultLocale(String content) {
6694 String defaultLanguageId = LocalizationUtil.getDefaultLanguageId(
6695 content);
6696
6697 if (Validator.isNotNull(defaultLanguageId)) {
6698 return LocaleUtil.fromLanguageId(defaultLanguageId);
6699 }
6700
6701 return LocaleUtil.getSiteDefault();
6702 }
6703
6704 protected JournalArticleDisplay getArticleDisplay(
6705 JournalArticle article, String ddmTemplateKey, String viewMode,
6706 String languageId, int page,
6707 PortletRequestModel portletRequestModel, ThemeDisplay themeDisplay,
6708 boolean propagateException)
6709 throws PortalException {
6710
6711 String content = null;
6712
6713 if (page < 1) {
6714 page = 1;
6715 }
6716
6717 int numberOfPages = 1;
6718 boolean paginate = false;
6719 boolean pageFlow = false;
6720
6721 boolean cacheable = true;
6722
6723 Map<String, String> tokens = JournalUtil.getTokens(
6724 article.getGroupId(), portletRequestModel, themeDisplay);
6725
6726 if ((themeDisplay == null) && (portletRequestModel == null)) {
6727 tokens.put("company_id", String.valueOf(article.getCompanyId()));
6728
6729 Group companyGroup = groupLocalService.getCompanyGroup(
6730 article.getCompanyId());
6731
6732 tokens.put(
6733 "article_group_id", String.valueOf(article.getGroupId()));
6734 tokens.put(
6735 "company_group_id", String.valueOf(companyGroup.getGroupId()));
6736
6737
6738
6739 tokens.put("group_id", String.valueOf(article.getGroupId()));
6740 }
6741
6742 tokens.put(
6743 TemplateConstants.CLASS_NAME_ID,
6744 String.valueOf(
6745 classNameLocalService.getClassNameId(DDMStructure.class)));
6746 tokens.put(
6747 "article_resource_pk",
6748 String.valueOf(article.getResourcePrimKey()));
6749
6750 DDMStructure ddmStructure = article.getDDMStructure();
6751
6752 tokens.put(
6753 "ddm_structure_key",
6754 String.valueOf(ddmStructure.getStructureKey()));
6755 tokens.put(
6756 "ddm_structure_id", String.valueOf(ddmStructure.getStructureId()));
6757
6758
6759
6760 tokens.put("structure_id", article.getDDMStructureKey());
6761
6762 String defaultDDMTemplateKey = article.getDDMTemplateKey();
6763
6764 if (Validator.isNull(ddmTemplateKey)) {
6765 ddmTemplateKey = defaultDDMTemplateKey;
6766 }
6767
6768 Document document = article.getDocument();
6769
6770 document = document.clone();
6771
6772 Element rootElement = document.getRootElement();
6773
6774 List<Element> pages = rootElement.elements("page");
6775
6776 if (!pages.isEmpty()) {
6777 pageFlow = true;
6778
6779 String targetPage = null;
6780
6781 Map<String, String[]> parameters =
6782 portletRequestModel.getParameters();
6783
6784 if (parameters != null) {
6785 String[] values = parameters.get("targetPage");
6786
6787 if ((values != null) && (values.length > 0)) {
6788 targetPage = values[0];
6789 }
6790 }
6791
6792 Element pageElement = null;
6793
6794 if (Validator.isNotNull(targetPage)) {
6795 targetPage = HtmlUtil.escapeXPathAttribute(targetPage);
6796
6797 XPath xPathSelector = SAXReaderUtil.createXPath(
6798 "/root/page[@id = " + targetPage + "]");
6799
6800 pageElement = (Element)xPathSelector.selectSingleNode(document);
6801 }
6802
6803 if (pageElement != null) {
6804 document = SAXReaderUtil.createDocument(pageElement);
6805
6806 rootElement = document.getRootElement();
6807
6808 numberOfPages = pages.size();
6809 }
6810 else {
6811 if (page > pages.size()) {
6812 page = 1;
6813 }
6814
6815 pageElement = pages.get(page - 1);
6816
6817 document = SAXReaderUtil.createDocument(pageElement);
6818
6819 rootElement = document.getRootElement();
6820
6821 numberOfPages = pages.size();
6822 paginate = true;
6823 }
6824 }
6825
6826 JournalUtil.addAllReservedEls(
6827 rootElement, tokens, article, languageId, themeDisplay);
6828
6829 try {
6830 if (_log.isDebugEnabled()) {
6831 _log.debug(
6832 "Transforming " + article.getArticleId() + " " +
6833 article.getVersion() + " " + languageId);
6834 }
6835
6836
6837
6838
6839
6840
6841 DDMTemplate ddmTemplate = null;
6842
6843 try {
6844 ddmTemplate = ddmTemplateLocalService.getTemplate(
6845 PortalUtil.getSiteGroupId(article.getGroupId()),
6846 classNameLocalService.getClassNameId(DDMStructure.class),
6847 ddmTemplateKey, true);
6848
6849 Group companyGroup = groupLocalService.getCompanyGroup(
6850 article.getCompanyId());
6851
6852 if (companyGroup.getGroupId() == ddmTemplate.getGroupId()) {
6853 tokens.put(
6854 "company_group_id",
6855 String.valueOf(companyGroup.getGroupId()));
6856 }
6857 }
6858 catch (NoSuchTemplateException nste) {
6859 if (!defaultDDMTemplateKey.equals(ddmTemplateKey)) {
6860 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
6861 PortalUtil.getSiteGroupId(article.getGroupId()),
6862 classNameLocalService.getClassNameId(
6863 DDMStructure.class),
6864 defaultDDMTemplateKey);
6865 }
6866 else {
6867 throw nste;
6868 }
6869 }
6870
6871 tokens.put(
6872 "ddm_template_key",
6873 String.valueOf(ddmTemplate.getTemplateKey()));
6874 tokens.put(
6875 "ddm_template_id", String.valueOf(ddmTemplate.getTemplateId()));
6876
6877
6878
6879 tokens.put("template_id", ddmTemplateKey);
6880
6881 String script = ddmTemplate.getScript();
6882 String langType = ddmTemplate.getLanguage();
6883 cacheable = ddmTemplate.isCacheable();
6884
6885 content = JournalUtil.transform(
6886 themeDisplay, tokens, viewMode, languageId, document,
6887 portletRequestModel, script, langType, propagateException);
6888
6889 if (!pageFlow) {
6890 String[] pieces = StringUtil.split(
6891 content, PropsValues.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
6892
6893 if (pieces.length > 1) {
6894 if (page > pieces.length) {
6895 page = 1;
6896 }
6897
6898 content = pieces[page - 1];
6899 numberOfPages = pieces.length;
6900 paginate = true;
6901 }
6902 }
6903 }
6904 catch (Exception e) {
6905 throw new SystemException(e);
6906 }
6907
6908 return new JournalArticleDisplayImpl(
6909 article.getCompanyId(), article.getId(),
6910 article.getResourcePrimKey(), article.getGroupId(),
6911 article.getUserId(), article.getArticleId(), article.getVersion(),
6912 article.getTitle(languageId), article.getUrlTitle(),
6913 article.getDescription(languageId),
6914 article.getAvailableLanguageIds(), content,
6915 article.getDDMStructureKey(), ddmTemplateKey,
6916 article.isSmallImage(), article.getSmallImageId(),
6917 article.getSmallImageURL(), numberOfPages, page, paginate,
6918 cacheable);
6919 }
6920
6921 protected List<ObjectValuePair<Long, Integer>> getArticleVersionStatuses(
6922 List<JournalArticle> articles) {
6923
6924 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
6925 new ArrayList<>(articles.size());
6926
6927 for (JournalArticle article : articles) {
6928 int status = article.getStatus();
6929
6930 if (status == WorkflowConstants.STATUS_PENDING) {
6931 status = WorkflowConstants.STATUS_DRAFT;
6932 }
6933
6934 ObjectValuePair<Long, Integer> articleVersionStatusOVP =
6935 new ObjectValuePair<>(article.getId(), status);
6936
6937 articleVersionStatusOVPs.add(articleVersionStatusOVP);
6938 }
6939
6940 return articleVersionStatusOVPs;
6941 }
6942
6943 protected long getClassTypeId(JournalArticle article)
6944 throws PortalException {
6945
6946 long classNameId = classNameLocalService.getClassNameId(
6947 JournalArticle.class);
6948
6949 DDMStructure ddmStructure = ddmStructureLocalService.fetchStructure(
6950 article.getGroupId(), classNameId, article.getDDMStructureKey(),
6951 true);
6952
6953 return ddmStructure.getStructureId();
6954 }
6955
6956 protected JournalArticle getFirstArticle(
6957 long groupId, String articleId, int status,
6958 OrderByComparator<JournalArticle> orderByComparator)
6959 throws PortalException {
6960
6961 if (status == WorkflowConstants.STATUS_ANY) {
6962 return journalArticlePersistence.findByG_A_NotST_First(
6963 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH,
6964 orderByComparator);
6965 }
6966 else {
6967 return journalArticlePersistence.findByG_A_ST_First(
6968 groupId, articleId, status, orderByComparator);
6969 }
6970 }
6971
6972 protected String getUniqueUrlTitle(
6973 long id, long groupId, String articleId, String title)
6974 throws PortalException {
6975
6976 String urlTitle = JournalUtil.getUrlTitle(id, title);
6977
6978 return getUniqueUrlTitle(groupId, articleId, urlTitle);
6979 }
6980
6981 protected String getUniqueUrlTitle(
6982 long id, long groupId, String articleId, String title,
6983 String oldUrlTitle, ServiceContext serviceContext)
6984 throws PortalException {
6985
6986 String serviceContextUrlTitle = ParamUtil.getString(
6987 serviceContext, "urlTitle");
6988
6989 String urlTitle = null;
6990
6991 if (Validator.isNotNull(serviceContextUrlTitle)) {
6992 urlTitle = JournalUtil.getUrlTitle(id, serviceContextUrlTitle);
6993 }
6994 else if (Validator.isNotNull(oldUrlTitle)) {
6995 return oldUrlTitle;
6996 }
6997 else {
6998 urlTitle = getUniqueUrlTitle(id, groupId, articleId, title);
6999 }
7000
7001 JournalArticle urlTitleArticle = fetchArticleByUrlTitle(
7002 groupId, urlTitle);
7003
7004 if ((urlTitleArticle != null) &&
7005 !Validator.equals(
7006 urlTitleArticle.getArticleId(), articleId)) {
7007
7008 urlTitle = getUniqueUrlTitle(id, groupId, articleId, urlTitle);
7009 }
7010
7011 return urlTitle;
7012 }
7013
7014 protected boolean hasModifiedLatestApprovedVersion(
7015 long groupId, String articleId, double version) {
7016
7017 JournalArticle article = fetchLatestArticle(
7018 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
7019
7020 if ((article == null) || (article.getVersion() <= version)) {
7021 return true;
7022 }
7023
7024 return false;
7025 }
7026
7027 protected void notifySubscribers(
7028 long userId, JournalArticle article, String articleURL,
7029 String action, ServiceContext serviceContext)
7030 throws PortalException {
7031
7032 if (!article.isApproved() || Validator.isNull(articleURL)) {
7033 return;
7034 }
7035
7036 String articleTitle = article.getTitle(serviceContext.getLanguageId());
7037
7038 articleURL = buildArticleURL(
7039 articleURL, article.getGroupId(), article.getFolderId(),
7040 article.getArticleId());
7041
7042 PortletPreferences preferences =
7043 ServiceContextUtil.getPortletPreferences(serviceContext);
7044
7045 if (preferences == null) {
7046 long ownerId = article.getGroupId();
7047 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
7048 long plid = PortletKeys.PREFS_PLID_SHARED;
7049 String portletId = PortletProviderUtil.getPortletId(
7050 JournalArticle.class.getName(), PortletProvider.Action.EDIT);
7051 String defaultPreferences = null;
7052
7053 preferences = portletPreferencesLocalService.getPreferences(
7054 article.getCompanyId(), ownerId, ownerType, plid, portletId,
7055 defaultPreferences);
7056 }
7057
7058 if (action.equals("add") &&
7059 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
7060 }
7061 else if (action.equals("move_to") &&
7062 JournalUtil.getEmailArticleMovedToFolderEnabled(preferences)) {
7063 }
7064 else if (action.equals("move_from") &&
7065 JournalUtil.getEmailArticleMovedFromFolderEnabled(
7066 preferences)) {
7067 }
7068 else if (action.equals("update") &&
7069 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
7070 }
7071 else {
7072 return;
7073 }
7074
7075 String fromName = JournalUtil.getEmailFromName(
7076 preferences, article.getCompanyId());
7077 String fromAddress = JournalUtil.getEmailFromAddress(
7078 preferences, article.getCompanyId());
7079
7080 Map<Locale, String> localizedSubjectMap = null;
7081 Map<Locale, String> localizedBodyMap = null;
7082
7083 if (action.equals("add")) {
7084 localizedSubjectMap = JournalUtil.getEmailArticleAddedSubjectMap(
7085 preferences);
7086 localizedBodyMap = JournalUtil.getEmailArticleAddedBodyMap(
7087 preferences);
7088 }
7089 else if (action.equals("move_to")) {
7090 localizedSubjectMap =
7091 JournalUtil.getEmailArticleMovedToFolderSubjectMap(preferences);
7092 localizedBodyMap = JournalUtil.getEmailArticleMovedToFolderBodyMap(
7093 preferences);
7094 }
7095 else if (action.equals("move_from")) {
7096 localizedSubjectMap =
7097 JournalUtil.getEmailArticleMovedFromFolderSubjectMap(
7098 preferences);
7099 localizedBodyMap =
7100 JournalUtil.getEmailArticleMovedFromFolderBodyMap(preferences);
7101 }
7102 else if (action.equals("update")) {
7103 localizedSubjectMap = JournalUtil.getEmailArticleUpdatedSubjectMap(
7104 preferences);
7105 localizedBodyMap = JournalUtil.getEmailArticleUpdatedBodyMap(
7106 preferences);
7107 }
7108
7109 String articleContent = StringPool.BLANK;
7110 String articleDiffs = StringPool.BLANK;
7111
7112 JournalArticle previousApprovedArticle = getPreviousApprovedArticle(
7113 article);
7114
7115 try {
7116 PortletRequestModel portletRequestModel = new PortletRequestModel(
7117 serviceContext.getLiferayPortletRequest(),
7118 serviceContext.getLiferayPortletResponse());
7119
7120 JournalArticleDisplay articleDisplay = getArticleDisplay(
7121 article, null, Constants.VIEW,
7122 LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault()), 1,
7123 portletRequestModel, serviceContext.getThemeDisplay());
7124
7125 articleContent = articleDisplay.getContent();
7126
7127 articleDiffs = JournalUtil.diffHtml(
7128 article.getGroupId(), article.getArticleId(),
7129 previousApprovedArticle.getVersion(), article.getVersion(),
7130 LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault()),
7131 portletRequestModel, serviceContext.getThemeDisplay());
7132 }
7133 catch (Exception e) {
7134 }
7135
7136 SubscriptionSender subscriptionSender =
7137 new GroupSubscriptionCheckSubscriptionSender(
7138 JournalPermission.RESOURCE_NAME);
7139
7140 subscriptionSender.setClassName(article.getModelClassName());
7141 subscriptionSender.setClassPK(article.getId());
7142 subscriptionSender.setCompanyId(article.getCompanyId());
7143 subscriptionSender.setContextAttribute(
7144 "[$ARTICLE_CONTENT$]", articleContent, false);
7145 subscriptionSender.setContextAttribute(
7146 "[$ARTICLE_DIFFS$]", DiffHtmlUtil.replaceStyles(articleDiffs),
7147 false);
7148
7149 JournalFolder folder = article.getFolder();
7150
7151 subscriptionSender.setContextAttributes(
7152 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
7153 articleTitle, "[$ARTICLE_URL$]", articleURL, "[$ARTICLE_VERSION$]",
7154 article.getVersion(), "[$FOLDER_NAME$]", folder.getName());
7155
7156 subscriptionSender.setContextCreatorUserPrefix("ARTICLE");
7157 subscriptionSender.setCreatorUserId(article.getUserId());
7158 subscriptionSender.setCurrentUserId(userId);
7159 subscriptionSender.setEntryTitle(articleTitle);
7160 subscriptionSender.setEntryURL(articleURL);
7161 subscriptionSender.setFrom(fromAddress, fromName);
7162 subscriptionSender.setHtmlFormat(true);
7163 subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
7164 subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
7165 subscriptionSender.setMailId("journal_article", article.getId());
7166
7167 int notificationType =
7168 UserNotificationDefinition.NOTIFICATION_TYPE_ADD_ENTRY;
7169
7170 if (serviceContext.isCommandUpdate()) {
7171 notificationType =
7172 UserNotificationDefinition.NOTIFICATION_TYPE_UPDATE_ENTRY;
7173 }
7174
7175 subscriptionSender.setNotificationType(notificationType);
7176
7177 String portletId = PortletProviderUtil.getPortletId(
7178 JournalArticle.class.getName(), PortletProvider.Action.EDIT);
7179
7180 subscriptionSender.setPortletId(portletId);
7181
7182 subscriptionSender.setReplyToAddress(fromAddress);
7183 subscriptionSender.setScopeGroupId(article.getGroupId());
7184 subscriptionSender.setServiceContext(serviceContext);
7185
7186 subscriptionSender.addPersistedSubscribers(
7187 JournalFolder.class.getName(), article.getGroupId());
7188
7189 if (folder != null) {
7190 subscriptionSender.addPersistedSubscribers(
7191 JournalFolder.class.getName(), folder.getFolderId());
7192
7193 for (Long ancestorFolderId : folder.getAncestorFolderIds()) {
7194 subscriptionSender.addPersistedSubscribers(
7195 JournalFolder.class.getName(), ancestorFolderId);
7196 }
7197 }
7198
7199 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
7200 article.getGroupId(),
7201 classNameLocalService.getClassNameId(JournalArticle.class),
7202 article.getDDMStructureKey(), true);
7203
7204 subscriptionSender.addPersistedSubscribers(
7205 DDMStructure.class.getName(), ddmStructure.getStructureId());
7206
7207 subscriptionSender.addPersistedSubscribers(
7208 JournalArticle.class.getName(), article.getResourcePrimKey());
7209
7210 subscriptionSender.flushNotificationsAsync();
7211 }
7212
7213 protected void saveImages(
7214 boolean smallImage, long smallImageId, File smallImageFile,
7215 byte[] smallImageBytes)
7216 throws PortalException {
7217
7218 if (smallImage) {
7219 if ((smallImageFile != null) && (smallImageBytes != null)) {
7220 imageLocalService.updateImage(smallImageId, smallImageBytes);
7221 }
7222 }
7223 else {
7224 imageLocalService.deleteImage(smallImageId);
7225 }
7226 }
7227
7228 protected BaseModelSearchResult<JournalArticle> searchJournalArticles(
7229 SearchContext searchContext)
7230 throws PortalException {
7231
7232 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
7233 JournalArticle.class);
7234
7235 for (int i = 0; i < 10; i++) {
7236 Hits hits = indexer.search(
7237 searchContext, JournalUtil.SELECTED_FIELD_NAMES);
7238
7239 List<JournalArticle> articles = JournalUtil.getArticles(hits);
7240
7241 if (articles != null) {
7242 return new BaseModelSearchResult<>(articles, hits.getLength());
7243 }
7244 }
7245
7246 throw new SearchException(
7247 "Unable to fix the search index after 10 attempts");
7248 }
7249
7250 protected void sendEmail(
7251 JournalArticle article, String articleURL,
7252 PortletPreferences preferences, String emailType,
7253 ServiceContext serviceContext)
7254 throws PortalException {
7255
7256 if (preferences == null) {
7257 return;
7258 }
7259 else if (emailType.equals("denied") &&
7260 JournalUtil.getEmailArticleApprovalDeniedEnabled(
7261 preferences)) {
7262 }
7263 else if (emailType.equals("granted") &&
7264 JournalUtil.getEmailArticleApprovalGrantedEnabled(
7265 preferences)) {
7266 }
7267 else if (emailType.equals("requested") &&
7268 JournalUtil.getEmailArticleApprovalRequestedEnabled(
7269 preferences)) {
7270 }
7271 else if (emailType.equals("review") &&
7272 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
7273 }
7274 else {
7275 return;
7276 }
7277
7278 Company company = companyPersistence.findByPrimaryKey(
7279 article.getCompanyId());
7280
7281 User user = userPersistence.findByPrimaryKey(article.getUserId());
7282
7283 String fromName = JournalUtil.getEmailFromName(
7284 preferences, article.getCompanyId());
7285 String fromAddress = JournalUtil.getEmailFromAddress(
7286 preferences, article.getCompanyId());
7287
7288 String toName = user.getFullName();
7289 String toAddress = user.getEmailAddress();
7290
7291 if (emailType.equals("requested")) {
7292 String tempToName = fromName;
7293 String tempToAddress = fromAddress;
7294
7295 fromName = toName;
7296 fromAddress = toAddress;
7297
7298 toName = tempToName;
7299 toAddress = tempToAddress;
7300 }
7301
7302 Map<Locale, String> localizedSubjectMap = null;
7303 Map<Locale, String> localizedBodyMap = null;
7304
7305 if (emailType.equals("denied")) {
7306 localizedSubjectMap =
7307 JournalUtil.getEmailArticleApprovalDeniedSubjectMap(
7308 preferences);
7309 localizedBodyMap = JournalUtil.getEmailArticleApprovalDeniedBodyMap(
7310 preferences);
7311 }
7312 else if (emailType.equals("granted")) {
7313 localizedSubjectMap =
7314 JournalUtil.getEmailArticleApprovalGrantedSubjectMap(
7315 preferences);
7316 localizedBodyMap =
7317 JournalUtil.getEmailArticleApprovalGrantedBodyMap(preferences);
7318 }
7319 else if (emailType.equals("requested")) {
7320 localizedSubjectMap =
7321 JournalUtil.getEmailArticleApprovalRequestedSubjectMap(
7322 preferences);
7323 localizedBodyMap =
7324 JournalUtil.getEmailArticleApprovalRequestedBodyMap(
7325 preferences);
7326 }
7327 else if (emailType.equals("review")) {
7328 localizedSubjectMap = JournalUtil.getEmailArticleReviewSubjectMap(
7329 preferences);
7330 localizedBodyMap = JournalUtil.getEmailArticleReviewBodyMap(
7331 preferences);
7332 }
7333
7334 SubscriptionSender subscriptionSender = new SubscriptionSender();
7335
7336 subscriptionSender.setCompanyId(company.getCompanyId());
7337 subscriptionSender.setContextAttributes(
7338 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
7339 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
7340 articleURL, "[$ARTICLE_USER_NAME$]", article.getUserName(),
7341 "[$ARTICLE_VERSION$]", article.getVersion());
7342 subscriptionSender.setContextCreatorUserPrefix("ARTICLE");
7343 subscriptionSender.setCreatorUserId(article.getUserId());
7344 subscriptionSender.setFrom(fromAddress, fromName);
7345 subscriptionSender.setHtmlFormat(true);
7346 subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
7347 subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
7348 subscriptionSender.setMailId("journal_article", article.getId());
7349
7350 String portletId = PortletProviderUtil.getPortletId(
7351 JournalArticle.class.getName(), PortletProvider.Action.EDIT);
7352
7353 subscriptionSender.setPortletId(portletId);
7354
7355 subscriptionSender.setScopeGroupId(article.getGroupId());
7356 subscriptionSender.setServiceContext(serviceContext);
7357
7358 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
7359
7360 subscriptionSender.flushNotificationsAsync();
7361 }
7362
7363 protected void startWorkflowInstance(
7364 long userId, JournalArticle article, ServiceContext serviceContext)
7365 throws PortalException {
7366
7367 Map<String, Serializable> workflowContext = new HashMap<>();
7368
7369 String portletId = PortletProviderUtil.getPortletId(
7370 JournalArticle.class.getName(), PortletProvider.Action.EDIT);
7371
7372 workflowContext.put(
7373 WorkflowConstants.CONTEXT_URL,
7374 PortalUtil.getControlPanelFullURL(
7375 article.getGroupId(), portletId, null));
7376
7377 WorkflowHandlerRegistryUtil.startWorkflowInstance(
7378 article.getCompanyId(), article.getGroupId(), userId,
7379 JournalArticle.class.getName(), article.getId(), article,
7380 serviceContext, workflowContext);
7381 }
7382
7383 protected void updateDDMFormFieldPredefinedValue(
7384 DDMFormField ddmFormField, String ddmFormFieldValue) {
7385
7386 LocalizedValue predefinedValue = ddmFormField.getPredefinedValue();
7387
7388 for (Locale locale : predefinedValue.getAvailableLocales()) {
7389 predefinedValue.addString(locale, ddmFormFieldValue);
7390 }
7391 }
7392
7393 protected void updateDDMLinks(
7394 long id, long groupId, String ddmStructureKey,
7395 String ddmTemplateKey, boolean incrementVersion)
7396 throws PortalException {
7397
7398 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
7399 PortalUtil.getSiteGroupId(groupId),
7400 classNameLocalService.getClassNameId(JournalArticle.class),
7401 ddmStructureKey, true);
7402
7403 DDMTemplate ddmTemplate = ddmTemplateLocalService.getTemplate(
7404 PortalUtil.getSiteGroupId(groupId),
7405 classNameLocalService.getClassNameId(DDMStructure.class),
7406 ddmTemplateKey, true);
7407
7408 if (incrementVersion) {
7409 ddmStorageLinkLocalService.addStorageLink(
7410 ddmStructure.getClassNameId(), id,
7411 ddmStructure.getStructureId(), new ServiceContext());
7412
7413 ddmTemplateLinkLocalService.addTemplateLink(
7414 classNameLocalService.getClassNameId(JournalArticle.class), id,
7415 ddmTemplate.getTemplateId());
7416 }
7417 else {
7418 DDMStorageLink ddmStorageLink =
7419 ddmStorageLinkLocalService.getClassStorageLink(id);
7420
7421 ddmStorageLink.setStructureId(ddmStructure.getStructureId());
7422
7423 ddmStorageLinkLocalService.updateDDMStorageLink(ddmStorageLink);
7424
7425 ddmTemplateLinkLocalService.updateTemplateLink(
7426 classNameLocalService.getClassNameId(JournalArticle.class), id,
7427 ddmTemplate.getTemplateId());
7428 }
7429 }
7430
7431 protected void updateDDMStructurePredefinedValues(
7432 long ddmStructureId, String content, ServiceContext serviceContext) {
7433
7434 DDMStructure ddmStructure = ddmStructureLocalService.fetchDDMStructure(
7435 ddmStructureId);
7436
7437 if (ddmStructure == null) {
7438 return;
7439 }
7440
7441 DDMForm ddmForm = ddmStructure.getDDMForm();
7442
7443 Map<String, DDMFormField> ddmFormFieldsMap =
7444 ddmStructure.getFullHierarchyDDMFormFieldsMap(true);
7445
7446 Map<String, String> fieldsValuesMap = createFieldsValuesMap(content);
7447
7448 for (Map.Entry<String, String> fieldValue :
7449 fieldsValuesMap.entrySet()) {
7450
7451 String ddmFormFieldName = fieldValue.getKey();
7452 String ddmFormFieldValue = fieldValue.getValue();
7453
7454 updateDDMFormFieldPredefinedValue(
7455 ddmFormFieldsMap.get(ddmFormFieldName), ddmFormFieldValue);
7456 }
7457
7458 ddmStructure.updateDDMForm(ddmForm);
7459
7460 ddmStructureLocalService.updateDDMStructure(ddmStructure);
7461 }
7462
7463 protected void updatePreviousApprovedArticle(JournalArticle article)
7464 throws PortalException {
7465
7466 JournalArticle previousApprovedArticle = getPreviousApprovedArticle(
7467 article);
7468
7469 if (previousApprovedArticle.getVersion() == article.getVersion()) {
7470 assetEntryLocalService.updateVisible(
7471 JournalArticle.class.getName(), article.getResourcePrimKey(),
7472 false);
7473 }
7474 else {
7475 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
7476 JournalArticle.class.getName(), article.getResourcePrimKey(),
7477 previousApprovedArticle.getDisplayDate(),
7478 previousApprovedArticle.getExpirationDate(), true);
7479
7480 assetEntry.setModifiedDate(
7481 previousApprovedArticle.getModifiedDate());
7482 assetEntry.setTitle(previousApprovedArticle.getTitle());
7483
7484 assetEntryPersistence.update(assetEntry);
7485 }
7486 }
7487
7488 protected void updateUrlTitles(
7489 long groupId, String articleId, String urlTitle)
7490 throws PortalException {
7491
7492 JournalArticle firstArticle = journalArticlePersistence.findByG_A_First(
7493 groupId, articleId, new ArticleVersionComparator(false));
7494
7495 if (firstArticle.getUrlTitle().equals(urlTitle)) {
7496 return;
7497 }
7498
7499 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
7500 groupId, articleId);
7501
7502 for (JournalArticle article : articles) {
7503 if (!article.getUrlTitle().equals(urlTitle)) {
7504 article.setUrlTitle(urlTitle);
7505
7506 journalArticlePersistence.update(article);
7507 }
7508 }
7509 }
7510
7511 protected void validate(
7512 long companyId, long groupId, long classNameId,
7513 Map<Locale, String> titleMap, String content,
7514 String ddmStructureKey, String ddmTemplateKey, Date expirationDate,
7515 boolean smallImage, String smallImageURL, File smallImageFile,
7516 byte[] smallImageBytes, ServiceContext serviceContext)
7517 throws PortalException {
7518
7519 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
7520 LocalizationUtil.getDefaultLanguageId(content));
7521
7522 if (!LanguageUtil.isAvailableLocale(groupId, articleDefaultLocale)) {
7523 LocaleException le = new LocaleException(
7524 LocaleException.TYPE_CONTENT,
7525 "The locale " + articleDefaultLocale +
7526 " is not available in site with groupId" + groupId);
7527
7528 le.setSourceAvailableLocales(
7529 Collections.singleton(articleDefaultLocale));
7530 le.setTargetAvailableLocales(
7531 LanguageUtil.getAvailableLocales(groupId));
7532
7533 throw le;
7534 }
7535
7536 if ((classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
7537 (titleMap.isEmpty() ||
7538 Validator.isNull(titleMap.get(articleDefaultLocale)))) {
7539
7540 throw new ArticleTitleException();
7541 }
7542
7543 validateContent(content);
7544
7545 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
7546 PortalUtil.getSiteGroupId(groupId),
7547 classNameLocalService.getClassNameId(JournalArticle.class),
7548 ddmStructureKey, true);
7549
7550 validateDDMStructureFields(ddmStructure, classNameId, content);
7551
7552 if (Validator.isNotNull(ddmTemplateKey)) {
7553 DDMTemplate ddmTemplate = ddmTemplateLocalService.getTemplate(
7554 PortalUtil.getSiteGroupId(groupId),
7555 classNameLocalService.getClassNameId(DDMStructure.class),
7556 ddmTemplateKey, true);
7557
7558 if (ddmTemplate.getClassPK() != ddmStructure.getStructureId()) {
7559 throw new NoSuchTemplateException(
7560 "{templateKey=" + ddmTemplateKey + "}");
7561 }
7562 }
7563 else if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
7564 throw new NoSuchTemplateException();
7565 }
7566
7567 if ((expirationDate != null) && expirationDate.before(new Date()) &&
7568 !ExportImportThreadLocal.isImportInProcess()) {
7569
7570 throw new ArticleExpirationDateException();
7571 }
7572
7573 String[] imageExtensions = PrefsPropsUtil.getStringArray(
7574 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
7575
7576 if (!smallImage || Validator.isNotNull(smallImageURL) ||
7577 (smallImageFile == null) || (smallImageBytes == null)) {
7578
7579 return;
7580 }
7581
7582 String smallImageName = smallImageFile.getName();
7583
7584 if (smallImageName != null) {
7585 boolean validSmallImageExtension = false;
7586
7587 for (String _imageExtension : imageExtensions) {
7588 if (StringPool.STAR.equals(_imageExtension) ||
7589 StringUtil.endsWith(smallImageName, _imageExtension)) {
7590
7591 validSmallImageExtension = true;
7592
7593 break;
7594 }
7595 }
7596
7597 if (!validSmallImageExtension) {
7598 throw new ArticleSmallImageNameException(smallImageName);
7599 }
7600 }
7601
7602 long smallImageMaxSize = PrefsPropsUtil.getLong(
7603 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
7604
7605 if ((smallImageMaxSize > 0) &&
7606 ((smallImageBytes == null) ||
7607 (smallImageBytes.length > smallImageMaxSize))) {
7608
7609 throw new ArticleSmallImageSizeException();
7610 }
7611 }
7612
7613 protected void validate(
7614 long companyId, long groupId, long classNameId, String articleId,
7615 boolean autoArticleId, double version, Map<Locale, String> titleMap,
7616 String content, String ddmStructureKey, String ddmTemplateKey,
7617 Date expirationDate, boolean smallImage, String smallImageURL,
7618 File smallImageFile, byte[] smallImageBytes,
7619 ServiceContext serviceContext)
7620 throws PortalException {
7621
7622 if (!autoArticleId) {
7623 validate(articleId);
7624 }
7625
7626 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
7627 groupId, articleId, version);
7628
7629 if (article != null) {
7630 StringBundler sb = new StringBundler(7);
7631
7632 sb.append("{groupId=");
7633 sb.append(groupId);
7634 sb.append(", articleId=");
7635 sb.append(articleId);
7636 sb.append(", version=");
7637 sb.append(version);
7638 sb.append("}");
7639
7640 throw new DuplicateArticleIdException(sb.toString());
7641 }
7642
7643 validate(
7644 companyId, groupId, classNameId, titleMap, content, ddmStructureKey,
7645 ddmTemplateKey, expirationDate, smallImage, smallImageURL,
7646 smallImageFile, smallImageBytes, serviceContext);
7647 }
7648
7649 protected void validate(String articleId) throws PortalException {
7650 if (Validator.isNull(articleId) ||
7651 (articleId.indexOf(CharPool.COMMA) != -1) ||
7652 (articleId.indexOf(CharPool.SPACE) != -1)) {
7653
7654 throw new ArticleIdException();
7655 }
7656 }
7657
7658 protected void validateContent(String content) throws PortalException {
7659 if (Validator.isNull(content)) {
7660 throw new ArticleContentException("Content is null");
7661 }
7662
7663 try {
7664 SAXReaderUtil.read(content);
7665 }
7666 catch (DocumentException de) {
7667 if (_log.isDebugEnabled()) {
7668 _log.debug("Invalid content:\n" + content);
7669 }
7670
7671 throw new ArticleContentException(
7672 "Unable to read content with an XML parser", de);
7673 }
7674 }
7675
7676 protected void validateDDMStructureFields(
7677 DDMStructure ddmStructure, long classNameId, Fields fields)
7678 throws PortalException {
7679
7680 for (com.liferay.portlet.dynamicdatamapping.storage.Field field :
7681 fields) {
7682
7683 if (!ddmStructure.hasField(field.getName())) {
7684 throw new StorageFieldNameException();
7685 }
7686
7687 if (ddmStructure.getFieldRequired(field.getName()) &&
7688 Validator.isNull(field.getValue()) &&
7689 (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT)) {
7690
7691 throw new StorageFieldRequiredException();
7692 }
7693 }
7694 }
7695
7696 protected void validateDDMStructureFields(
7697 DDMStructure ddmStructure, long classNameId,
7698 ServiceContext serviceContext)
7699 throws PortalException {
7700
7701 Fields fields = DDMUtil.getFields(
7702 ddmStructure.getStructureId(), serviceContext);
7703
7704 validateDDMStructureFields(ddmStructure, classNameId, fields);
7705 }
7706
7707 protected void validateDDMStructureFields(
7708 DDMStructure ddmStructure, long classNameId, String content)
7709 throws PortalException {
7710
7711 Fields fields = DDMXMLUtil.getFields(ddmStructure, content);
7712
7713 validateDDMStructureFields(ddmStructure, classNameId, fields);
7714 }
7715
7716 protected void validateDDMStructureId(
7717 long groupId, long folderId, String ddmStructureKey)
7718 throws PortalException {
7719
7720 int restrictionType = JournalUtil.getRestrictionType(folderId);
7721
7722 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
7723 PortalUtil.getSiteGroupId(groupId),
7724 classNameLocalService.getClassNameId(JournalArticle.class),
7725 ddmStructureKey, true);
7726
7727 List<DDMStructure> folderDDMStructures =
7728 journalFolderLocalService.getDDMStructures(
7729 PortalUtil.getCurrentAndAncestorSiteGroupIds(groupId), folderId,
7730 restrictionType);
7731
7732 for (DDMStructure folderDDMStructure : folderDDMStructures) {
7733 if (folderDDMStructure.getStructureId() ==
7734 ddmStructure.getStructureId()) {
7735
7736 return;
7737 }
7738 }
7739
7740 throw new InvalidDDMStructureException(
7741 "Invalid structure " + ddmStructure.getStructureId() +
7742 " for folder " + folderId);
7743 }
7744
7745 private static final long _JOURNAL_ARTICLE_CHECK_INTERVAL =
7746 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
7747
7748 private static final Log _log = LogFactoryUtil.getLog(
7749 JournalArticleLocalServiceImpl.class);
7750
7751 private Date _previousCheckDate;
7752
7753 }