001
014
015 package com.liferay.portlet.journal.service.impl;
016
017 import com.liferay.portal.LocaleException;
018 import com.liferay.portal.NoSuchImageException;
019 import com.liferay.portal.kernel.dao.orm.QueryDefinition;
020 import com.liferay.portal.kernel.dao.orm.QueryUtil;
021 import com.liferay.portal.kernel.exception.PortalException;
022 import com.liferay.portal.kernel.exception.SystemException;
023 import com.liferay.portal.kernel.json.JSONFactoryUtil;
024 import com.liferay.portal.kernel.json.JSONObject;
025 import com.liferay.portal.kernel.language.LanguageUtil;
026 import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
027 import com.liferay.portal.kernel.log.Log;
028 import com.liferay.portal.kernel.log.LogFactoryUtil;
029 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
030 import com.liferay.portal.kernel.search.Field;
031 import com.liferay.portal.kernel.search.Hits;
032 import com.liferay.portal.kernel.search.Indexable;
033 import com.liferay.portal.kernel.search.IndexableType;
034 import com.liferay.portal.kernel.search.Indexer;
035 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
036 import com.liferay.portal.kernel.search.QueryConfig;
037 import com.liferay.portal.kernel.search.SearchContext;
038 import com.liferay.portal.kernel.search.Sort;
039 import com.liferay.portal.kernel.systemevent.SystemEvent;
040 import com.liferay.portal.kernel.systemevent.SystemEventHierarchyEntryThreadLocal;
041 import com.liferay.portal.kernel.util.ArrayUtil;
042 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
043 import com.liferay.portal.kernel.util.CharPool;
044 import com.liferay.portal.kernel.util.Constants;
045 import com.liferay.portal.kernel.util.ContentTypes;
046 import com.liferay.portal.kernel.util.FileUtil;
047 import com.liferay.portal.kernel.util.GetterUtil;
048 import com.liferay.portal.kernel.util.HtmlUtil;
049 import com.liferay.portal.kernel.util.HttpUtil;
050 import com.liferay.portal.kernel.util.ListUtil;
051 import com.liferay.portal.kernel.util.LocaleUtil;
052 import com.liferay.portal.kernel.util.LocalizationUtil;
053 import com.liferay.portal.kernel.util.MathUtil;
054 import com.liferay.portal.kernel.util.ObjectValuePair;
055 import com.liferay.portal.kernel.util.OrderByComparator;
056 import com.liferay.portal.kernel.util.ParamUtil;
057 import com.liferay.portal.kernel.util.PropsKeys;
058 import com.liferay.portal.kernel.util.StringPool;
059 import com.liferay.portal.kernel.util.StringUtil;
060 import com.liferay.portal.kernel.util.Time;
061 import com.liferay.portal.kernel.util.UnicodeProperties;
062 import com.liferay.portal.kernel.util.Validator;
063 import com.liferay.portal.kernel.workflow.WorkflowConstants;
064 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
065 import com.liferay.portal.kernel.xml.Document;
066 import com.liferay.portal.kernel.xml.DocumentException;
067 import com.liferay.portal.kernel.xml.Element;
068 import com.liferay.portal.kernel.xml.Node;
069 import com.liferay.portal.kernel.xml.SAXReaderUtil;
070 import com.liferay.portal.kernel.xml.XPath;
071 import com.liferay.portal.model.Company;
072 import com.liferay.portal.model.Group;
073 import com.liferay.portal.model.Image;
074 import com.liferay.portal.model.ResourceConstants;
075 import com.liferay.portal.model.SystemEventConstants;
076 import com.liferay.portal.model.User;
077 import com.liferay.portal.service.ServiceContext;
078 import com.liferay.portal.service.ServiceContextUtil;
079 import com.liferay.portal.servlet.filters.cache.CacheUtil;
080 import com.liferay.portal.theme.ThemeDisplay;
081 import com.liferay.portal.util.PortalUtil;
082 import com.liferay.portal.util.PortletKeys;
083 import com.liferay.portal.util.PrefsPropsUtil;
084 import com.liferay.portal.util.PropsValues;
085 import com.liferay.portal.util.SubscriptionSender;
086 import com.liferay.portal.webserver.WebServerServletTokenUtil;
087 import com.liferay.portlet.asset.model.AssetEntry;
088 import com.liferay.portlet.asset.model.AssetLink;
089 import com.liferay.portlet.asset.model.AssetLinkConstants;
090 import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
091 import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
092 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
093 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
094 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
095 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
096 import com.liferay.portlet.journal.ArticleContentException;
097 import com.liferay.portlet.journal.ArticleDisplayDateException;
098 import com.liferay.portlet.journal.ArticleExpirationDateException;
099 import com.liferay.portlet.journal.ArticleIdException;
100 import com.liferay.portlet.journal.ArticleReviewDateException;
101 import com.liferay.portlet.journal.ArticleSmallImageNameException;
102 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
103 import com.liferay.portlet.journal.ArticleTitleException;
104 import com.liferay.portlet.journal.ArticleTypeException;
105 import com.liferay.portlet.journal.ArticleVersionException;
106 import com.liferay.portlet.journal.DuplicateArticleIdException;
107 import com.liferay.portlet.journal.NoSuchArticleException;
108 import com.liferay.portlet.journal.StructureXsdException;
109 import com.liferay.portlet.journal.model.JournalArticle;
110 import com.liferay.portlet.journal.model.JournalArticleConstants;
111 import com.liferay.portlet.journal.model.JournalArticleDisplay;
112 import com.liferay.portlet.journal.model.JournalArticleResource;
113 import com.liferay.portlet.journal.model.JournalFolder;
114 import com.liferay.portlet.journal.model.impl.JournalArticleDisplayImpl;
115 import com.liferay.portlet.journal.service.base.JournalArticleLocalServiceBaseImpl;
116 import com.liferay.portlet.journal.social.JournalActivityKeys;
117 import com.liferay.portlet.journal.util.JournalUtil;
118 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
119 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
120 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
121 import com.liferay.portlet.social.model.SocialActivityConstants;
122 import com.liferay.portlet.trash.model.TrashEntry;
123 import com.liferay.portlet.trash.model.TrashVersion;
124 import com.liferay.portlet.trash.util.TrashUtil;
125
126 import java.io.File;
127 import java.io.IOException;
128 import java.io.Serializable;
129
130 import java.util.ArrayList;
131 import java.util.Calendar;
132 import java.util.Date;
133 import java.util.HashMap;
134 import java.util.HashSet;
135 import java.util.LinkedHashMap;
136 import java.util.List;
137 import java.util.Locale;
138 import java.util.Map;
139 import java.util.Set;
140
141 import javax.portlet.PortletPreferences;
142
143
172 public class JournalArticleLocalServiceImpl
173 extends JournalArticleLocalServiceBaseImpl {
174
175
258 @Indexable(type = IndexableType.REINDEX)
259 @Override
260 public JournalArticle addArticle(
261 long userId, long groupId, long folderId, long classNameId,
262 long classPK, String articleId, boolean autoArticleId,
263 double version, Map<Locale, String> titleMap,
264 Map<Locale, String> descriptionMap, String content, String type,
265 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
266 int displayDateMonth, int displayDateDay, int displayDateYear,
267 int displayDateHour, int displayDateMinute, int expirationDateMonth,
268 int expirationDateDay, int expirationDateYear,
269 int expirationDateHour, int expirationDateMinute,
270 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
271 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
272 boolean neverReview, boolean indexable, boolean smallImage,
273 String smallImageURL, File smallImageFile,
274 Map<String, byte[]> images, String articleURL,
275 ServiceContext serviceContext)
276 throws PortalException, SystemException {
277
278
279
280 User user = userPersistence.findByPrimaryKey(userId);
281 articleId = StringUtil.toUpperCase(articleId.trim());
282
283 Date displayDate = null;
284 Date expirationDate = null;
285 Date reviewDate = null;
286
287 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
288 displayDate = PortalUtil.getDate(
289 displayDateMonth, displayDateDay, displayDateYear,
290 displayDateHour, displayDateMinute, user.getTimeZone(),
291 ArticleDisplayDateException.class);
292
293 if (!neverExpire) {
294 expirationDate = PortalUtil.getDate(
295 expirationDateMonth, expirationDateDay, expirationDateYear,
296 expirationDateHour, expirationDateMinute,
297 user.getTimeZone(), ArticleExpirationDateException.class);
298 }
299
300 if (!neverReview) {
301 reviewDate = PortalUtil.getDate(
302 reviewDateMonth, reviewDateDay, reviewDateYear,
303 reviewDateHour, reviewDateMinute, user.getTimeZone(),
304 ArticleReviewDateException.class);
305 }
306 }
307
308 byte[] smallImageBytes = null;
309
310 try {
311 smallImageBytes = FileUtil.getBytes(smallImageFile);
312 }
313 catch (IOException ioe) {
314 }
315
316 Date now = new Date();
317
318 validate(
319 user.getCompanyId(), groupId, classNameId, articleId, autoArticleId,
320 version, titleMap, content, type, ddmStructureKey, ddmTemplateKey,
321 expirationDate, smallImage, smallImageURL, smallImageFile,
322 smallImageBytes);
323
324 if (autoArticleId) {
325 articleId = String.valueOf(counterLocalService.increment());
326 }
327
328 long id = counterLocalService.increment();
329
330 long resourcePrimKey =
331 journalArticleResourceLocalService.getArticleResourcePrimKey(
332 serviceContext.getUuid(), groupId, articleId);
333
334 JournalArticle article = journalArticlePersistence.create(id);
335
336 Locale locale = LocaleUtil.getSiteDefault();
337
338 String defaultLanguageId = ParamUtil.getString(
339 serviceContext, "defaultLanguageId");
340
341 if (Validator.isNull(defaultLanguageId)) {
342 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
343 }
344
345 if (Validator.isNotNull(defaultLanguageId)) {
346 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
347 }
348
349 String title = titleMap.get(locale);
350
351 content = format(
352 user, groupId, articleId, version, false, content, ddmStructureKey,
353 images);
354
355 article.setResourcePrimKey(resourcePrimKey);
356 article.setGroupId(groupId);
357 article.setCompanyId(user.getCompanyId());
358 article.setUserId(user.getUserId());
359 article.setUserName(user.getFullName());
360 article.setCreateDate(serviceContext.getCreateDate(now));
361 article.setModifiedDate(serviceContext.getModifiedDate(now));
362 article.setFolderId(folderId);
363 article.setClassNameId(classNameId);
364 article.setClassPK(classPK);
365 article.setTreePath(article.buildTreePath());
366 article.setArticleId(articleId);
367 article.setVersion(version);
368 article.setTitleMap(titleMap, locale);
369 article.setUrlTitle(
370 getUniqueUrlTitle(id, articleId, title, null, serviceContext));
371 article.setDescriptionMap(descriptionMap, locale);
372 article.setContent(content);
373 article.setType(type);
374 article.setStructureId(ddmStructureKey);
375 article.setTemplateId(ddmTemplateKey);
376 article.setLayoutUuid(layoutUuid);
377 article.setDisplayDate(displayDate);
378 article.setExpirationDate(expirationDate);
379 article.setReviewDate(reviewDate);
380 article.setIndexable(indexable);
381 article.setSmallImage(smallImage);
382 article.setSmallImageId(counterLocalService.increment());
383 article.setSmallImageURL(smallImageURL);
384
385 if ((expirationDate == null) || expirationDate.after(now)) {
386 article.setStatus(WorkflowConstants.STATUS_DRAFT);
387 }
388 else {
389 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
390 }
391
392 article.setStatusByUserId(userId);
393 article.setStatusDate(serviceContext.getModifiedDate(now));
394 article.setExpandoBridgeAttributes(serviceContext);
395
396 journalArticlePersistence.update(article);
397
398
399
400 if (serviceContext.isAddGroupPermissions() ||
401 serviceContext.isAddGuestPermissions()) {
402
403 addArticleResources(
404 article, serviceContext.isAddGroupPermissions(),
405 serviceContext.isAddGuestPermissions());
406 }
407 else {
408 addArticleResources(
409 article, serviceContext.getGroupPermissions(),
410 serviceContext.getGuestPermissions());
411 }
412
413
414
415 saveImages(
416 smallImage, article.getSmallImageId(), smallImageFile,
417 smallImageBytes);
418
419
420
421 updateAsset(
422 userId, article, serviceContext.getAssetCategoryIds(),
423 serviceContext.getAssetTagNames(),
424 serviceContext.getAssetLinkEntryIds());
425
426
427
428 if (PortalUtil.getClassNameId(DDMStructure.class) == classNameId) {
429 updateDDMStructureXSD(classPK, content, serviceContext);
430 }
431
432
433
434 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
435 mbMessageLocalService.addDiscussionMessage(
436 userId, article.getUserName(), groupId,
437 JournalArticle.class.getName(), resourcePrimKey,
438 WorkflowConstants.ACTION_PUBLISH);
439 }
440
441
442
443 PortletPreferences preferences =
444 ServiceContextUtil.getPortletPreferences(serviceContext);
445
446 sendEmail(
447 article, articleURL, preferences, "requested", serviceContext);
448
449
450
451 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
452 WorkflowHandlerRegistryUtil.startWorkflowInstance(
453 user.getCompanyId(), groupId, userId,
454 JournalArticle.class.getName(), article.getId(), article,
455 serviceContext);
456 }
457 else {
458 updateStatus(
459 userId, article, WorkflowConstants.STATUS_APPROVED, null,
460 new HashMap<String, Serializable>(), serviceContext);
461 }
462
463 return journalArticlePersistence.findByPrimaryKey(article.getId());
464 }
465
466
495 @Override
496 public JournalArticle addArticle(
497 long userId, long groupId, long folderId,
498 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
499 String content, String ddmStructureKey, String ddmTemplateKey,
500 ServiceContext serviceContext)
501 throws PortalException, SystemException {
502
503 Calendar calendar = CalendarFactoryUtil.getCalendar();
504
505 int displayDateMonth = calendar.get(Calendar.MONTH);
506 int displayDateDay = calendar.get(Calendar.DAY_OF_MONTH);
507 int displayDateYear = calendar.get(Calendar.YEAR);
508 int displayDateHour = calendar.get(Calendar.HOUR_OF_DAY);
509 int displayDateMinute = calendar.get(Calendar.MINUTE);
510
511 return journalArticleLocalService.addArticle(
512 userId, groupId, folderId,
513 JournalArticleConstants.CLASSNAME_ID_DEFAULT, 0, StringPool.BLANK,
514 true, 1, titleMap, descriptionMap, content, "general",
515 ddmStructureKey, ddmTemplateKey, null, displayDateMonth,
516 displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
517 0, 0, 0, 0, 0, true, 0, 0, 0, 0, 0, true, true, false, null, null,
518 null, null, serviceContext);
519 }
520
521
531 @Override
532 public void addArticleResources(
533 JournalArticle article, boolean addGroupPermissions,
534 boolean addGuestPermissions)
535 throws PortalException, SystemException {
536
537 resourceLocalService.addResources(
538 article.getCompanyId(), article.getGroupId(), article.getUserId(),
539 JournalArticle.class.getName(), article.getResourcePrimKey(), false,
540 addGroupPermissions, addGuestPermissions);
541 }
542
543
552 @Override
553 public void addArticleResources(
554 JournalArticle article, String[] groupPermissions,
555 String[] guestPermissions)
556 throws PortalException, SystemException {
557
558 resourceLocalService.addModelResources(
559 article.getCompanyId(), article.getGroupId(), article.getUserId(),
560 JournalArticle.class.getName(), article.getResourcePrimKey(),
561 groupPermissions, guestPermissions);
562 }
563
564
574 @Override
575 public void addArticleResources(
576 long groupId, String articleId, boolean addGroupPermissions,
577 boolean addGuestPermissions)
578 throws PortalException, SystemException {
579
580 JournalArticle article = getLatestArticle(groupId, articleId);
581
582 addArticleResources(article, addGroupPermissions, addGuestPermissions);
583 }
584
585
596 @Override
597 public void addArticleResources(
598 long groupId, String articleId, String[] groupPermissions,
599 String[] guestPermissions)
600 throws PortalException, SystemException {
601
602 JournalArticle article = getLatestArticle(groupId, articleId);
603
604 addArticleResources(article, groupPermissions, guestPermissions);
605 }
606
607
620 @Override
621 public JournalArticle checkArticleResourcePrimKey(
622 long groupId, String articleId, double version)
623 throws PortalException, SystemException {
624
625 JournalArticle article = journalArticlePersistence.findByG_A_V(
626 groupId, articleId, version);
627
628 if (article.getResourcePrimKey() > 0) {
629 return article;
630 }
631
632 long resourcePrimKey =
633 journalArticleResourceLocalService.getArticleResourcePrimKey(
634 groupId, articleId);
635
636 article.setResourcePrimKey(resourcePrimKey);
637
638 journalArticlePersistence.update(article);
639
640 return article;
641 }
642
643
650 @Override
651 public void checkArticles() throws PortalException, SystemException {
652 Date now = new Date();
653
654 checkArticlesByExpirationDate(now);
655
656 checkArticlesByReviewDate(now);
657
658 checkArticlesByDisplayDate(now);
659
660 _previousCheckDate = now;
661 }
662
663
675 @Override
676 public void checkNewLine(long groupId, String articleId, double version)
677 throws PortalException, SystemException {
678
679 JournalArticle article = journalArticlePersistence.findByG_A_V(
680 groupId, articleId, version);
681
682 String content = GetterUtil.getString(article.getContent());
683
684 if (content.contains("\\n")) {
685 content = StringUtil.replace(
686 content, new String[] {"\\n", "\\r"},
687 new String[] {"\n", "\r"});
688
689 article.setContent(content);
690
691 journalArticlePersistence.update(article);
692 }
693 }
694
695
708 @Override
709 public void checkStructure(long groupId, String articleId, double version)
710 throws PortalException, SystemException {
711
712 JournalArticle article = journalArticlePersistence.findByG_A_V(
713 groupId, articleId, version);
714
715 if (Validator.isNull(article.getStructureId())) {
716 return;
717 }
718
719 checkStructure(article);
720 }
721
722
738 @Indexable(type = IndexableType.REINDEX)
739 @Override
740 public JournalArticle copyArticle(
741 long userId, long groupId, String oldArticleId, String newArticleId,
742 boolean autoArticleId, double version)
743 throws PortalException, SystemException {
744
745
746
747 User user = userPersistence.findByPrimaryKey(userId);
748 oldArticleId = StringUtil.toUpperCase(oldArticleId.trim());
749 newArticleId = StringUtil.toUpperCase(newArticleId.trim());
750 Date now = new Date();
751
752 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
753 groupId, oldArticleId, version);
754
755 if (autoArticleId) {
756 newArticleId = String.valueOf(counterLocalService.increment());
757 }
758 else {
759 validate(newArticleId);
760
761 if (journalArticlePersistence.countByG_A(
762 groupId, newArticleId) > 0) {
763
764 throw new DuplicateArticleIdException();
765 }
766 }
767
768 long id = counterLocalService.increment();
769
770 long resourcePrimKey =
771 journalArticleResourceLocalService.getArticleResourcePrimKey(
772 groupId, newArticleId);
773
774 JournalArticle newArticle = journalArticlePersistence.create(id);
775
776 newArticle.setResourcePrimKey(resourcePrimKey);
777 newArticle.setGroupId(groupId);
778 newArticle.setCompanyId(user.getCompanyId());
779 newArticle.setUserId(user.getUserId());
780 newArticle.setUserName(user.getFullName());
781 newArticle.setCreateDate(now);
782 newArticle.setModifiedDate(now);
783 newArticle.setFolderId(oldArticle.getFolderId());
784 newArticle.setTreePath(oldArticle.getTreePath());
785 newArticle.setArticleId(newArticleId);
786 newArticle.setVersion(JournalArticleConstants.VERSION_DEFAULT);
787 newArticle.setTitle(oldArticle.getTitle());
788 newArticle.setUrlTitle(
789 getUniqueUrlTitle(
790 id, groupId, newArticleId, oldArticle.getTitleCurrentValue()));
791 newArticle.setDescription(oldArticle.getDescription());
792
793 try {
794 copyArticleImages(oldArticle, newArticle);
795 }
796 catch (Exception e) {
797 newArticle.setContent(oldArticle.getContent());
798 }
799
800 newArticle.setType(oldArticle.getType());
801 newArticle.setStructureId(oldArticle.getStructureId());
802 newArticle.setTemplateId(oldArticle.getTemplateId());
803 newArticle.setLayoutUuid(oldArticle.getLayoutUuid());
804 newArticle.setDisplayDate(oldArticle.getDisplayDate());
805 newArticle.setExpirationDate(oldArticle.getExpirationDate());
806 newArticle.setReviewDate(oldArticle.getReviewDate());
807 newArticle.setIndexable(oldArticle.isIndexable());
808 newArticle.setSmallImage(oldArticle.isSmallImage());
809 newArticle.setSmallImageId(counterLocalService.increment());
810 newArticle.setSmallImageURL(oldArticle.getSmallImageURL());
811
812 if (oldArticle.isPending() ||
813 workflowDefinitionLinkLocalService.hasWorkflowDefinitionLink(
814 user.getCompanyId(), groupId, JournalArticle.class.getName())) {
815
816 newArticle.setStatus(WorkflowConstants.STATUS_DRAFT);
817 }
818 else {
819 newArticle.setStatus(oldArticle.getStatus());
820 }
821
822 newArticle.setExpandoBridgeAttributes(oldArticle);
823
824 journalArticlePersistence.update(newArticle);
825
826
827
828 addArticleResources(newArticle, true, true);
829
830
831
832 if (oldArticle.getSmallImage()) {
833 Image image = imageLocalService.getImage(
834 oldArticle.getSmallImageId());
835
836 byte[] smallImageBytes = image.getTextObj();
837
838 imageLocalService.updateImage(
839 newArticle.getSmallImageId(), smallImageBytes);
840 }
841
842
843
844 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
845 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
846 String[] assetTagNames = assetTagLocalService.getTagNames(
847 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
848
849 updateAsset(userId, newArticle, assetCategoryIds, assetTagNames, null);
850
851 return newArticle;
852 }
853
854
861 @Override
862 @SystemEvent(
863 action = SystemEventConstants.ACTION_SKIP, send = false)
864 public JournalArticle deleteArticle(JournalArticle article)
865 throws PortalException, SystemException {
866
867 return journalArticleLocalService.deleteArticle(
868 article, StringPool.BLANK, null);
869 }
870
871
885 @Indexable(type = IndexableType.DELETE)
886 @Override
887 @SystemEvent(
888 action = SystemEventConstants.ACTION_SKIP, send = false)
889 public JournalArticle deleteArticle(
890 JournalArticle article, String articleURL,
891 ServiceContext serviceContext)
892 throws PortalException, SystemException {
893
894 JournalArticleResource articleResource =
895 journalArticleResourceLocalService.fetchArticleResource(
896 article.getGroupId(), article.getArticleId());
897
898 if (article.isApproved() &&
899 isLatestVersion(
900 article.getGroupId(), article.getArticleId(),
901 article.getVersion(), WorkflowConstants.STATUS_APPROVED)) {
902
903 updatePreviousApprovedArticle(article);
904 }
905
906
907
908 if ((serviceContext != null) && Validator.isNotNull(articleURL)) {
909 PortletPreferences preferences =
910 ServiceContextUtil.getPortletPreferences(serviceContext);
911
912 if ((preferences != null) && !article.isApproved() &&
913 isLatestVersion(
914 article.getGroupId(), article.getArticleId(),
915 article.getVersion())) {
916
917 sendEmail(
918 article, articleURL, preferences, "denied", serviceContext);
919 }
920 }
921
922
923
924 journalArticleImageLocalService.deleteImages(
925 article.getGroupId(), article.getArticleId(), article.getVersion());
926
927
928
929 expandoRowLocalService.deleteRows(article.getId());
930
931
932
933 if (!article.isDraft()) {
934 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
935 article.getCompanyId(), article.getGroupId(),
936 JournalArticle.class.getName(), article.getId());
937 }
938
939 int articlesCount = journalArticlePersistence.countByG_A(
940 article.getGroupId(), article.getArticleId());
941
942 if (articlesCount == 1) {
943
944
945
946 subscriptionLocalService.deleteSubscriptions(
947 article.getCompanyId(), JournalArticle.class.getName(),
948 article.getResourcePrimKey());
949
950
951
952 ratingsStatsLocalService.deleteStats(
953 JournalArticle.class.getName(), article.getResourcePrimKey());
954
955
956
957 mbMessageLocalService.deleteDiscussionMessages(
958 JournalArticle.class.getName(), article.getResourcePrimKey());
959
960
961
962 assetEntryLocalService.deleteEntry(
963 JournalArticle.class.getName(), article.getResourcePrimKey());
964
965
966
967 journalContentSearchLocalService.deleteArticleContentSearches(
968 article.getGroupId(), article.getArticleId());
969
970
971
972 imageLocalService.deleteImage(article.getSmallImageId());
973
974
975
976 trashEntryLocalService.deleteEntry(
977 JournalArticle.class.getName(), article.getResourcePrimKey());
978
979
980
981 resourceLocalService.deleteResource(
982 article.getCompanyId(), JournalArticle.class.getName(),
983 ResourceConstants.SCOPE_INDIVIDUAL,
984 article.getResourcePrimKey());
985
986
987
988 if (articleResource != null) {
989 journalArticleResourceLocalService.deleteJournalArticleResource(
990 articleResource);
991 }
992 }
993
994
995
996 journalArticlePersistence.remove(article);
997
998
999
1000 if (articleResource != null) {
1001 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1002
1003 extraDataJSONObject.put("version", article.getVersion());
1004
1005 systemEventLocalService.addSystemEvent(
1006 0, article.getGroupId(), article.getModelClassName(),
1007 article.getPrimaryKey(), articleResource.getUuid(), null,
1008 SystemEventConstants.TYPE_DELETE,
1009 extraDataJSONObject.toString());
1010 }
1011
1012 return article;
1013 }
1014
1015
1031 @Override
1032 public JournalArticle deleteArticle(
1033 long groupId, String articleId, double version, String articleURL,
1034 ServiceContext serviceContext)
1035 throws PortalException, SystemException {
1036
1037 JournalArticle article = journalArticlePersistence.findByG_A_V(
1038 groupId, articleId, version);
1039
1040 return journalArticleLocalService.deleteArticle(
1041 article, articleURL, serviceContext);
1042 }
1043
1044
1057 @Override
1058 public void deleteArticle(
1059 long groupId, String articleId, ServiceContext serviceContext)
1060 throws PortalException, SystemException {
1061
1062 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1063
1064 JournalArticleResource articleResource =
1065 journalArticleResourceLocalService.fetchArticleResource(
1066 groupId, articleId);
1067
1068 try {
1069 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1070 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1071 new ArticleVersionComparator(true));
1072
1073 for (JournalArticle article : articles) {
1074 journalArticleLocalService.deleteArticle(
1075 article, null, serviceContext);
1076 }
1077 }
1078 finally {
1079 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1080 }
1081
1082 if (articleResource != null) {
1083 systemEventLocalService.addSystemEvent(
1084 0, groupId, JournalArticle.class.getName(),
1085 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1086 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1087 }
1088 }
1089
1090
1097 @Override
1098 public void deleteArticles(long groupId)
1099 throws PortalException, SystemException {
1100
1101 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1102
1103 List<JournalArticleResource> articleResources =
1104 new ArrayList<JournalArticleResource>();
1105
1106 try {
1107 JournalArticleResource articleResource = null;
1108
1109 for (JournalArticle article :
1110 journalArticlePersistence.findByGroupId(groupId)) {
1111
1112 if ((articleResource == null) ||
1113 (articleResource.getPrimaryKey() !=
1114 article.getResourcePrimKey())) {
1115
1116 articleResource =
1117 journalArticleResourceLocalService.getArticleResource(
1118 article.getResourcePrimKey());
1119
1120 articleResources.add(articleResource);
1121 }
1122
1123 journalArticleLocalService.deleteArticle(article, null, null);
1124 }
1125 }
1126 finally {
1127 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1128 }
1129
1130 for (JournalArticleResource articleResource : articleResources) {
1131 systemEventLocalService.addSystemEvent(
1132 0, groupId, JournalArticle.class.getName(),
1133 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1134 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1135 }
1136 }
1137
1138
1147 @Override
1148 public void deleteArticles(long groupId, long folderId)
1149 throws PortalException, SystemException {
1150
1151 deleteArticles(groupId, folderId, true);
1152 }
1153
1154
1165 @Override
1166 public void deleteArticles(
1167 long groupId, long folderId, boolean includeTrashedEntries)
1168 throws PortalException, SystemException {
1169
1170 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1171
1172 List<JournalArticleResource> articleResources =
1173 new ArrayList<JournalArticleResource>();
1174
1175 try {
1176 JournalArticleResource articleResource = null;
1177
1178 for (JournalArticle article :
1179 journalArticlePersistence.findByG_F(groupId, folderId)) {
1180
1181 if ((articleResource == null) ||
1182 (articleResource.getPrimaryKey() !=
1183 article.getResourcePrimKey())) {
1184
1185 articleResource =
1186 journalArticleResourceLocalService.getArticleResource(
1187 article.getResourcePrimKey());
1188
1189 articleResources.add(articleResource);
1190 }
1191
1192 if (includeTrashedEntries || !article.isInTrash()) {
1193 journalArticleLocalService.deleteArticle(
1194 article, null, null);
1195 }
1196 else {
1197 articleResources.remove(articleResource);
1198 }
1199 }
1200 }
1201 finally {
1202 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1203 }
1204
1205 for (JournalArticleResource articleResource : articleResources) {
1206 systemEventLocalService.addSystemEvent(
1207 0, groupId, JournalArticle.class.getName(),
1208 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1209 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1210 }
1211 }
1212
1213
1222 @Override
1223 public void deleteLayoutArticleReferences(long groupId, String layoutUuid)
1224 throws SystemException {
1225
1226 List<JournalArticle> articles = journalArticlePersistence.findByG_L(
1227 groupId, layoutUuid);
1228
1229 for (JournalArticle article : articles) {
1230 article.setLayoutUuid(StringPool.BLANK);
1231
1232 journalArticlePersistence.update(article);
1233 }
1234 }
1235
1236
1259 @Indexable(type = IndexableType.REINDEX)
1260 @Override
1261 public JournalArticle expireArticle(
1262 long userId, long groupId, String articleId, double version,
1263 String articleURL, ServiceContext serviceContext)
1264 throws PortalException, SystemException {
1265
1266 return updateStatus(
1267 userId, groupId, articleId, version,
1268 WorkflowConstants.STATUS_EXPIRED, articleURL,
1269 new HashMap<String, Serializable>(), serviceContext);
1270 }
1271
1272
1295 @Override
1296 public void expireArticle(
1297 long userId, long groupId, String articleId, String articleURL,
1298 ServiceContext serviceContext)
1299 throws PortalException, SystemException {
1300
1301 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
1302 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1303 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1304 new ArticleVersionComparator(true));
1305
1306 for (JournalArticle article : articles) {
1307 journalArticleLocalService.expireArticle(
1308 userId, groupId, article.getArticleId(),
1309 article.getVersion(), articleURL, serviceContext);
1310 }
1311 }
1312 else {
1313 JournalArticle article = getLatestArticle(
1314 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1315
1316 journalArticleLocalService.expireArticle(
1317 userId, groupId, article.getArticleId(), article.getVersion(),
1318 articleURL, serviceContext);
1319 }
1320 }
1321
1322 @Override
1323 public JournalArticle fetchArticle(
1324 long groupId, String articleId, double version)
1325 throws SystemException {
1326
1327 return journalArticlePersistence.fetchByG_A_V(
1328 groupId, articleId, version);
1329 }
1330
1331 @Override
1332 public JournalArticle fetchLatestArticle(
1333 long resourcePrimKey, int status, boolean preferApproved)
1334 throws SystemException {
1335
1336 JournalArticle article = null;
1337
1338 OrderByComparator orderByComparator = new ArticleVersionComparator();
1339
1340 if (status == WorkflowConstants.STATUS_ANY) {
1341 if (preferApproved) {
1342 article = journalArticlePersistence.fetchByR_ST_First(
1343 resourcePrimKey, WorkflowConstants.STATUS_APPROVED,
1344 orderByComparator);
1345 }
1346
1347 if (article == null) {
1348 article =
1349 journalArticlePersistence.fetchByResourcePrimKey_First(
1350 resourcePrimKey, orderByComparator);
1351 }
1352 }
1353 else {
1354 article = journalArticlePersistence.fetchByR_ST_First(
1355 resourcePrimKey, status, orderByComparator);
1356 }
1357
1358 return article;
1359 }
1360
1361 @Override
1362 public JournalArticle fetchLatestArticle(
1363 long groupId, String articleId, int status)
1364 throws SystemException {
1365
1366 OrderByComparator orderByComparator = new ArticleVersionComparator();
1367
1368 if (status == WorkflowConstants.STATUS_ANY) {
1369 return journalArticlePersistence.fetchByG_A_First(
1370 groupId, articleId, orderByComparator);
1371 }
1372
1373 return journalArticlePersistence.fetchByG_A_ST_First(
1374 groupId, articleId, status, orderByComparator);
1375 }
1376
1377 @Override
1378 public JournalArticle fetchLatestIndexableArticle(long resourcePrimKey)
1379 throws SystemException {
1380
1381 OrderByComparator orderByComparator = new ArticleVersionComparator();
1382
1383 int[] statuses = new int[] {
1384 WorkflowConstants.STATUS_APPROVED, WorkflowConstants.STATUS_IN_TRASH
1385 };
1386
1387 List<JournalArticle> articles =
1388 journalArticlePersistence.findByR_I_S(
1389 resourcePrimKey, true, statuses, 0, 1, orderByComparator);
1390
1391 if (articles.isEmpty()) {
1392 return null;
1393 }
1394
1395 return articles.get(0);
1396 }
1397
1398
1407 @Override
1408 public JournalArticle getArticle(long id)
1409 throws PortalException, SystemException {
1410
1411 return journalArticlePersistence.findByPrimaryKey(id);
1412 }
1413
1414
1426 @Override
1427 public JournalArticle getArticle(long groupId, String articleId)
1428 throws PortalException, SystemException {
1429
1430
1431
1432
1433 try {
1434 return getLatestArticle(
1435 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1436 }
1437 catch (NoSuchArticleException nsae) {
1438 return getLatestArticle(
1439 groupId, articleId, WorkflowConstants.STATUS_ANY);
1440 }
1441 }
1442
1443
1455 @Override
1456 public JournalArticle getArticle(
1457 long groupId, String articleId, double version)
1458 throws PortalException, SystemException {
1459
1460 return journalArticlePersistence.findByG_A_V(
1461 groupId, articleId, version);
1462 }
1463
1464
1482 @Override
1483 public JournalArticle getArticle(
1484 long groupId, String className, long classPK)
1485 throws PortalException, SystemException {
1486
1487 long classNameId = PortalUtil.getClassNameId(className);
1488
1489 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1490 groupId, classNameId, classPK);
1491
1492 if (articles.isEmpty()) {
1493 throw new NoSuchArticleException(
1494 "No approved JournalArticle exists with the key {groupId=" +
1495 groupId + ", className=" + className + ", classPK=" +
1496 classPK + "}");
1497 }
1498
1499 return articles.get(0);
1500 }
1501
1502
1513 @Override
1514 public JournalArticle getArticleByUrlTitle(long groupId, String urlTitle)
1515 throws PortalException, SystemException {
1516
1517
1518
1519
1520 try {
1521 return getLatestArticleByUrlTitle(
1522 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
1523 }
1524 catch (NoSuchArticleException nsae) {
1525 return getLatestArticleByUrlTitle(
1526 groupId, urlTitle, WorkflowConstants.STATUS_PENDING);
1527 }
1528 }
1529
1530
1547 @Override
1548 public String getArticleContent(
1549 JournalArticle article, String ddmTemplateKey, String viewMode,
1550 String languageId, ThemeDisplay themeDisplay)
1551 throws PortalException, SystemException {
1552
1553 JournalArticleDisplay articleDisplay = getArticleDisplay(
1554 article, ddmTemplateKey, viewMode, languageId, 1, null,
1555 themeDisplay);
1556
1557 if (articleDisplay == null) {
1558 return StringPool.BLANK;
1559 }
1560 else {
1561 return articleDisplay.getContent();
1562 }
1563 }
1564
1565
1584 @Override
1585 public String getArticleContent(
1586 long groupId, String articleId, double version, String viewMode,
1587 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1588 throws PortalException, SystemException {
1589
1590 JournalArticleDisplay articleDisplay = getArticleDisplay(
1591 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
1592 themeDisplay);
1593
1594 if (articleDisplay == null) {
1595 return StringPool.BLANK;
1596 }
1597 else {
1598 return articleDisplay.getContent();
1599 }
1600 }
1601
1602
1616 @Override
1617 public String getArticleContent(
1618 long groupId, String articleId, double version, String viewMode,
1619 String languageId, ThemeDisplay themeDisplay)
1620 throws PortalException, SystemException {
1621
1622 return getArticleContent(
1623 groupId, articleId, version, viewMode, null, languageId,
1624 themeDisplay);
1625 }
1626
1627
1645 @Override
1646 public String getArticleContent(
1647 long groupId, String articleId, String viewMode,
1648 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1649 throws PortalException, SystemException {
1650
1651 JournalArticleDisplay articleDisplay = getArticleDisplay(
1652 groupId, articleId, ddmTemplateKey, viewMode, languageId,
1653 themeDisplay);
1654
1655 return articleDisplay.getContent();
1656 }
1657
1658
1671 @Override
1672 public String getArticleContent(
1673 long groupId, String articleId, String viewMode, String languageId,
1674 ThemeDisplay themeDisplay)
1675 throws PortalException, SystemException {
1676
1677 return getArticleContent(
1678 groupId, articleId, viewMode, null, languageId, themeDisplay);
1679 }
1680
1681
1705 @Override
1706 public JournalArticleDisplay getArticleDisplay(
1707 JournalArticle article, String ddmTemplateKey, String viewMode,
1708 String languageId, int page, String xmlRequest,
1709 ThemeDisplay themeDisplay)
1710 throws PortalException, SystemException {
1711
1712 String content = null;
1713
1714 if (page < 1) {
1715 page = 1;
1716 }
1717
1718 int numberOfPages = 1;
1719 boolean paginate = false;
1720 boolean pageFlow = false;
1721
1722 boolean cacheable = true;
1723
1724 if (Validator.isNull(xmlRequest)) {
1725 xmlRequest = "<request />";
1726 }
1727
1728 Map<String, String> tokens = JournalUtil.getTokens(
1729 article.getGroupId(), themeDisplay, xmlRequest);
1730
1731 if ((themeDisplay == null) && xmlRequest.equals("<request />")) {
1732 tokens.put("company_id", String.valueOf(article.getCompanyId()));
1733
1734 Group companyGroup = groupLocalService.getCompanyGroup(
1735 article.getCompanyId());
1736
1737 tokens.put(
1738 "article_group_id", String.valueOf(article.getGroupId()));
1739 tokens.put(
1740 "company_group_id", String.valueOf(companyGroup.getGroupId()));
1741
1742
1743
1744 tokens.put("group_id", String.valueOf(article.getGroupId()));
1745 }
1746
1747 tokens.put(
1748 "article_resource_pk",
1749 String.valueOf(article.getResourcePrimKey()));
1750
1751 String defaultDDMTemplateKey = article.getTemplateId();
1752
1753 if (article.isTemplateDriven()) {
1754 if (Validator.isNull(ddmTemplateKey)) {
1755 ddmTemplateKey = defaultDDMTemplateKey;
1756 }
1757
1758 tokens.put("structure_id", article.getStructureId());
1759 tokens.put("template_id", ddmTemplateKey);
1760 }
1761
1762 String xml = article.getContent();
1763
1764 try {
1765 Document document = null;
1766
1767 Element rootElement = null;
1768
1769 if (article.isTemplateDriven()) {
1770 document = SAXReaderUtil.read(xml);
1771
1772 rootElement = document.getRootElement();
1773
1774 Document requestDocument = SAXReaderUtil.read(xmlRequest);
1775
1776 List<Element> pages = rootElement.elements("page");
1777
1778 if (!pages.isEmpty()) {
1779 pageFlow = true;
1780
1781 String targetPage = requestDocument.valueOf(
1782 "/request/parameters/parameter[name='targetPage']/" +
1783 "value");
1784
1785 Element pageElement = null;
1786
1787 if (Validator.isNotNull(targetPage)) {
1788 targetPage = HtmlUtil.escapeXPathAttribute(targetPage);
1789
1790 XPath xPathSelector = SAXReaderUtil.createXPath(
1791 "/root/page[@id = " + targetPage + "]");
1792
1793 pageElement = (Element)xPathSelector.selectSingleNode(
1794 document);
1795 }
1796
1797 if (pageElement != null) {
1798 document = SAXReaderUtil.createDocument(pageElement);
1799
1800 rootElement = document.getRootElement();
1801
1802 numberOfPages = pages.size();
1803 }
1804 else {
1805 if (page > pages.size()) {
1806 page = 1;
1807 }
1808
1809 pageElement = pages.get(page - 1);
1810
1811 document = SAXReaderUtil.createDocument(pageElement);
1812
1813 rootElement = document.getRootElement();
1814
1815 numberOfPages = pages.size();
1816 paginate = true;
1817 }
1818 }
1819
1820 rootElement.add(requestDocument.getRootElement().createCopy());
1821
1822 JournalUtil.addAllReservedEls(
1823 rootElement, tokens, article, languageId, themeDisplay);
1824
1825 xml = DDMXMLUtil.formatXML(document);
1826 }
1827 }
1828 catch (DocumentException de) {
1829 throw new SystemException(de);
1830 }
1831
1832 try {
1833 if (_log.isDebugEnabled()) {
1834 _log.debug(
1835 "Transforming " + article.getArticleId() + " " +
1836 article.getVersion() + " " + languageId);
1837 }
1838
1839 String script = null;
1840 String langType = null;
1841
1842 if (article.isTemplateDriven()) {
1843
1844
1845
1846
1847
1848
1849
1850 DDMTemplate ddmTemplate = null;
1851
1852 try {
1853 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1854 article.getGroupId(),
1855 PortalUtil.getClassNameId(DDMStructure.class),
1856 ddmTemplateKey);
1857 }
1858 catch (NoSuchTemplateException nste1) {
1859 try {
1860 Group companyGroup = groupLocalService.getCompanyGroup(
1861 article.getCompanyId());
1862
1863 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1864 companyGroup.getGroupId(),
1865 PortalUtil.getClassNameId(DDMStructure.class),
1866 ddmTemplateKey);
1867
1868 tokens.put(
1869 "company_group_id",
1870 String.valueOf(companyGroup.getGroupId()));
1871 }
1872 catch (NoSuchTemplateException nste2) {
1873 if (!defaultDDMTemplateKey.equals(ddmTemplateKey)) {
1874 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1875 article.getGroupId(),
1876 PortalUtil.getClassNameId(DDMStructure.class),
1877 defaultDDMTemplateKey);
1878 }
1879 else {
1880 throw nste1;
1881 }
1882 }
1883 }
1884
1885 script = ddmTemplate.getScript();
1886 langType = ddmTemplate.getLanguage();
1887 cacheable = ddmTemplate.isCacheable();
1888 }
1889
1890 content = JournalUtil.transform(
1891 themeDisplay, tokens, viewMode, languageId, xml, script,
1892 langType);
1893
1894 if (!pageFlow) {
1895 String[] pieces = StringUtil.split(
1896 content, PropsValues.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
1897
1898 if (pieces.length > 1) {
1899 if (page > pieces.length) {
1900 page = 1;
1901 }
1902
1903 content = pieces[page - 1];
1904 numberOfPages = pieces.length;
1905 paginate = true;
1906 }
1907 }
1908 }
1909 catch (Exception e) {
1910 throw new SystemException(e);
1911 }
1912
1913 return new JournalArticleDisplayImpl(
1914 article.getCompanyId(), article.getId(),
1915 article.getResourcePrimKey(), article.getGroupId(),
1916 article.getUserId(), article.getArticleId(), article.getVersion(),
1917 article.getTitle(languageId), article.getUrlTitle(),
1918 article.getDescription(languageId),
1919 article.getAvailableLanguageIds(), content, article.getType(),
1920 article.getStructureId(), ddmTemplateKey, article.isSmallImage(),
1921 article.getSmallImageId(), article.getSmallImageURL(),
1922 numberOfPages, page, paginate, cacheable);
1923 }
1924
1925
1952 @Override
1953 public JournalArticleDisplay getArticleDisplay(
1954 long groupId, String articleId, double version,
1955 String ddmTemplateKey, String viewMode, String languageId, int page,
1956 String xmlRequest, ThemeDisplay themeDisplay)
1957 throws PortalException, SystemException {
1958
1959 Date now = new Date();
1960
1961 JournalArticle article = journalArticlePersistence.findByG_A_V(
1962 groupId, articleId, version);
1963
1964 if (article.isExpired()) {
1965 Date expirationDate = article.getExpirationDate();
1966
1967 if ((expirationDate != null) && expirationDate.before(now)) {
1968 return null;
1969 }
1970 }
1971
1972 Date displayDate = article.getDisplayDate();
1973
1974 if (displayDate.after(now)) {
1975 return null;
1976 }
1977
1978 return getArticleDisplay(
1979 article, ddmTemplateKey, viewMode, languageId, page, xmlRequest,
1980 themeDisplay);
1981 }
1982
1983
2007 @Override
2008 public JournalArticleDisplay getArticleDisplay(
2009 long groupId, String articleId, double version,
2010 String ddmTemplateKey, String viewMode, String languageId,
2011 ThemeDisplay themeDisplay)
2012 throws PortalException, SystemException {
2013
2014 return getArticleDisplay(
2015 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
2016 1, null, themeDisplay);
2017 }
2018
2019
2041 @Override
2042 public JournalArticleDisplay getArticleDisplay(
2043 long groupId, String articleId, String viewMode, String languageId,
2044 int page, String xmlRequest, ThemeDisplay themeDisplay)
2045 throws PortalException, SystemException {
2046
2047 return getArticleDisplay(
2048 groupId, articleId, null, viewMode, languageId, page, xmlRequest,
2049 themeDisplay);
2050 }
2051
2052
2079 @Override
2080 public JournalArticleDisplay getArticleDisplay(
2081 long groupId, String articleId, String ddmTemplateKey,
2082 String viewMode, String languageId, int page, String xmlRequest,
2083 ThemeDisplay themeDisplay)
2084 throws PortalException, SystemException {
2085
2086 JournalArticle article = getDisplayArticle(groupId, articleId);
2087
2088 return getArticleDisplay(
2089 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2090 languageId, page, xmlRequest, themeDisplay);
2091 }
2092
2093
2116 @Override
2117 public JournalArticleDisplay getArticleDisplay(
2118 long groupId, String articleId, String ddmTemplateKey,
2119 String viewMode, String languageId, ThemeDisplay themeDisplay)
2120 throws PortalException, SystemException {
2121
2122 JournalArticle article = getDisplayArticle(groupId, articleId);
2123
2124 return getArticleDisplay(
2125 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2126 languageId, themeDisplay);
2127 }
2128
2129
2147 @Override
2148 public JournalArticleDisplay getArticleDisplay(
2149 long groupId, String articleId, String viewMode, String languageId,
2150 ThemeDisplay themeDisplay)
2151 throws PortalException, SystemException {
2152
2153 return getArticleDisplay(
2154 groupId, articleId, null, viewMode, languageId, themeDisplay);
2155 }
2156
2157
2163 @Override
2164 public List<JournalArticle> getArticles() throws SystemException {
2165 return journalArticlePersistence.findAll();
2166 }
2167
2168
2175 @Override
2176 public List<JournalArticle> getArticles(long groupId)
2177 throws SystemException {
2178
2179 return journalArticlePersistence.findByGroupId(groupId);
2180 }
2181
2182
2202 @Override
2203 public List<JournalArticle> getArticles(long groupId, int start, int end)
2204 throws SystemException {
2205
2206 return journalArticlePersistence.findByGroupId(groupId, start, end);
2207 }
2208
2209
2232 @Override
2233 public List<JournalArticle> getArticles(
2234 long groupId, int start, int end, OrderByComparator obc)
2235 throws SystemException {
2236
2237 return journalArticlePersistence.findByGroupId(
2238 groupId, start, end, obc);
2239 }
2240
2241
2249 @Override
2250 public List<JournalArticle> getArticles(long groupId, long folderId)
2251 throws SystemException {
2252
2253 return journalArticlePersistence.findByG_F(groupId, folderId);
2254 }
2255
2256
2278 @Override
2279 public List<JournalArticle> getArticles(
2280 long groupId, long folderId, int start, int end)
2281 throws SystemException {
2282
2283 return journalArticlePersistence.findByG_F(
2284 groupId, folderId, start, end);
2285 }
2286
2287
2312 @Override
2313 public List<JournalArticle> getArticles(
2314 long groupId, long folderId, int start, int end,
2315 OrderByComparator orderByComparator)
2316 throws SystemException {
2317
2318 return journalArticlePersistence.findByG_F(
2319 groupId, folderId, start, end, orderByComparator);
2320 }
2321
2322
2330 @Override
2331 public List<JournalArticle> getArticles(long groupId, String articleId)
2332 throws SystemException {
2333
2334 return journalArticlePersistence.findByG_A(groupId, articleId);
2335 }
2336
2337 @Override
2338 public List<JournalArticle> getArticlesByResourcePrimKey(
2339 long resourcePrimKey)
2340 throws SystemException {
2341
2342 return journalArticlePersistence.findByResourcePrimKey(resourcePrimKey);
2343 }
2344
2345
2353 @Override
2354 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId)
2355 throws SystemException {
2356
2357 return journalArticlePersistence.findBySmallImageId(smallImageId);
2358 }
2359
2360
2367 @Override
2368 public int getArticlesCount(long groupId) throws SystemException {
2369 return journalArticlePersistence.countByGroupId(groupId);
2370 }
2371
2372
2380 @Override
2381 public int getArticlesCount(long groupId, long folderId)
2382 throws SystemException {
2383
2384 return journalArticlePersistence.countByG_F(groupId, folderId);
2385 }
2386
2387
2412 @Override
2413 public List<JournalArticle> getCompanyArticles(
2414 long companyId, double version, int status, int start, int end)
2415 throws SystemException {
2416
2417 if (status == WorkflowConstants.STATUS_ANY) {
2418 return journalArticlePersistence.findByC_V(
2419 companyId, version, start, end, new ArticleIDComparator(true));
2420 }
2421 else {
2422 return journalArticlePersistence.findByC_V_ST(
2423 companyId, version, status, start, end,
2424 new ArticleIDComparator(true));
2425 }
2426 }
2427
2428
2452 @Override
2453 public List<JournalArticle> getCompanyArticles(
2454 long companyId, int status, int start, int end)
2455 throws SystemException {
2456
2457 if (status == WorkflowConstants.STATUS_ANY) {
2458 return journalArticlePersistence.findByCompanyId(
2459 companyId, start, end, new ArticleIDComparator(true));
2460 }
2461 else {
2462 return journalArticlePersistence.findByC_ST(
2463 companyId, status, start, end, new ArticleIDComparator(true));
2464 }
2465 }
2466
2467
2492 @Override
2493 public int getCompanyArticlesCount(
2494 long companyId, double version, int status, int start, int end)
2495 throws SystemException {
2496
2497 if (status == WorkflowConstants.STATUS_ANY) {
2498 return journalArticlePersistence.countByC_V(companyId, version);
2499 }
2500 else {
2501 return journalArticlePersistence.countByC_V_ST(
2502 companyId, version, status);
2503 }
2504 }
2505
2506
2517 @Override
2518 public int getCompanyArticlesCount(long companyId, int status)
2519 throws SystemException {
2520
2521 if (status == WorkflowConstants.STATUS_ANY) {
2522 return journalArticlePersistence.countByCompanyId(companyId);
2523 }
2524 else {
2525 return journalArticlePersistence.countByC_ST(companyId, status);
2526 }
2527 }
2528
2529
2542 @Override
2543 public JournalArticle getDisplayArticle(long groupId, String articleId)
2544 throws PortalException, SystemException {
2545
2546 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
2547 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
2548
2549 if (articles.isEmpty()) {
2550 throw new NoSuchArticleException(
2551 "No approved JournalArticle exists with the key {groupId=" +
2552 groupId + ", " + "articleId=" + articleId + "}");
2553 }
2554
2555 Date now = new Date();
2556
2557 for (int i = 0; i < articles.size(); i++) {
2558 JournalArticle article = articles.get(i);
2559
2560 Date displayDate = article.getDisplayDate();
2561 Date expirationDate = article.getExpirationDate();
2562
2563 if (((displayDate == null) || displayDate.before(now)) &&
2564 ((expirationDate == null) || expirationDate.after(now))) {
2565
2566 return article;
2567 }
2568 }
2569
2570 return articles.get(0);
2571 }
2572
2573
2586 @Override
2587 public JournalArticle getDisplayArticleByUrlTitle(
2588 long groupId, String urlTitle)
2589 throws PortalException, SystemException {
2590
2591 List<JournalArticle> articles = null;
2592
2593 OrderByComparator orderByComparator = new ArticleVersionComparator();
2594
2595 articles = journalArticlePersistence.findByG_UT_ST(
2596 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED,
2597 QueryUtil.ALL_POS, QueryUtil.ALL_POS, orderByComparator);
2598
2599 if (articles.isEmpty()) {
2600 throw new NoSuchArticleException(
2601 "No JournalArticle exists with the key {groupId=" + groupId +
2602 ", urlTitle=" + urlTitle + "}");
2603 }
2604
2605 Date now = new Date();
2606
2607 for (JournalArticle article : articles) {
2608 Date displayDate = article.getDisplayDate();
2609 Date expirationDate = article.getExpirationDate();
2610
2611 if (((displayDate != null) && displayDate.before(now)) &&
2612 ((expirationDate == null) || expirationDate.after(now)) ) {
2613
2614 return article;
2615 }
2616 }
2617
2618 return articles.get(0);
2619 }
2620
2621
2632 @Override
2633 public JournalArticle getLatestArticle(long resourcePrimKey)
2634 throws PortalException, SystemException {
2635
2636 return getLatestArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);
2637 }
2638
2639
2654 @Override
2655 public JournalArticle getLatestArticle(long resourcePrimKey, int status)
2656 throws PortalException, SystemException {
2657
2658 return getLatestArticle(resourcePrimKey, status, true);
2659 }
2660
2661
2681 @Override
2682 public JournalArticle getLatestArticle(
2683 long resourcePrimKey, int status, boolean preferApproved)
2684 throws PortalException, SystemException {
2685
2686 List<JournalArticle> articles = null;
2687
2688 OrderByComparator orderByComparator = new ArticleVersionComparator();
2689
2690 if (status == WorkflowConstants.STATUS_ANY) {
2691 if (preferApproved) {
2692 articles = journalArticlePersistence.findByR_ST(
2693 resourcePrimKey, WorkflowConstants.STATUS_APPROVED, 0, 1,
2694 orderByComparator);
2695 }
2696
2697 if ((articles == null) || (articles.size() == 0)) {
2698 articles = journalArticlePersistence.findByResourcePrimKey(
2699 resourcePrimKey, 0, 1, orderByComparator);
2700 }
2701 }
2702 else {
2703 articles = journalArticlePersistence.findByR_ST(
2704 resourcePrimKey, status, 0, 1, orderByComparator);
2705 }
2706
2707 if (articles.isEmpty()) {
2708 throw new NoSuchArticleException(
2709 "No JournalArticle exists with the key {resourcePrimKey=" +
2710 resourcePrimKey + "}");
2711 }
2712
2713 return articles.get(0);
2714 }
2715
2716
2726 @Override
2727 public JournalArticle getLatestArticle(long groupId, String articleId)
2728 throws PortalException, SystemException {
2729
2730 return getLatestArticle(
2731 groupId, articleId, WorkflowConstants.STATUS_ANY);
2732 }
2733
2734
2748 @Override
2749 public JournalArticle getLatestArticle(
2750 long groupId, String articleId, int status)
2751 throws PortalException, SystemException {
2752
2753 List<JournalArticle> articles = null;
2754
2755 OrderByComparator orderByComparator = new ArticleVersionComparator();
2756
2757 if (status == WorkflowConstants.STATUS_ANY) {
2758 articles = journalArticlePersistence.findByG_A(
2759 groupId, articleId, 0, 1, orderByComparator);
2760 }
2761 else {
2762 articles = journalArticlePersistence.findByG_A_ST(
2763 groupId, articleId, status, 0, 1, orderByComparator);
2764 }
2765
2766 if (articles.isEmpty()) {
2767 throw new NoSuchArticleException(
2768 "No JournalArticle exists with the key {groupId=" + groupId +
2769 ", articleId=" + articleId + ", status=" + status + "}");
2770 }
2771
2772 return articles.get(0);
2773 }
2774
2775
2793 @Override
2794 public JournalArticle getLatestArticle(
2795 long groupId, String className, long classPK)
2796 throws PortalException, SystemException {
2797
2798 long classNameId = PortalUtil.getClassNameId(className);
2799
2800 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
2801 groupId, classNameId, classPK, 0, 1,
2802 new ArticleVersionComparator());
2803
2804 if (articles.isEmpty()) {
2805 throw new NoSuchArticleException(
2806 "No JournalArticle exists with the key {groupId=" + groupId +
2807 ", className=" + className + ", classPK =" + classPK + "}");
2808 }
2809
2810 return articles.get(0);
2811 }
2812
2813
2827 @Override
2828 public JournalArticle getLatestArticleByUrlTitle(
2829 long groupId, String urlTitle, int status)
2830 throws PortalException, SystemException {
2831
2832 List<JournalArticle> articles = null;
2833
2834 OrderByComparator orderByComparator = new ArticleVersionComparator();
2835
2836 if (status == WorkflowConstants.STATUS_ANY) {
2837 articles = journalArticlePersistence.findByG_UT(
2838 groupId, urlTitle, 0, 1, orderByComparator);
2839 }
2840 else {
2841 articles = journalArticlePersistence.findByG_UT_ST(
2842 groupId, urlTitle, status, 0, 1, orderByComparator);
2843 }
2844
2845 if (articles.isEmpty()) {
2846 throw new NoSuchArticleException(
2847 "No JournalArticle exists with the key {groupId=" + groupId +
2848 ", urlTitle=" + urlTitle + ", status=" + status + "}");
2849 }
2850
2851 return articles.get(0);
2852 }
2853
2854
2865 @Override
2866 public double getLatestVersion(long groupId, String articleId)
2867 throws PortalException, SystemException {
2868
2869 JournalArticle article = getLatestArticle(groupId, articleId);
2870
2871 return article.getVersion();
2872 }
2873
2874
2888 @Override
2889 public double getLatestVersion(long groupId, String articleId, int status)
2890 throws PortalException, SystemException {
2891
2892 JournalArticle article = getLatestArticle(groupId, articleId, status);
2893
2894 return article.getVersion();
2895 }
2896
2897
2905 @Override
2906 public int getNotInTrashArticlesCount(long groupId, long folderId)
2907 throws SystemException {
2908
2909 QueryDefinition queryDefinition = new QueryDefinition(
2910 WorkflowConstants.STATUS_ANY);
2911
2912 List<Long> folderIds = new ArrayList<Long>();
2913
2914 folderIds.add(folderId);
2915
2916 return journalArticleFinder.countByG_F(
2917 groupId, folderIds, queryDefinition);
2918 }
2919
2920
2930 @Override
2931 public List<JournalArticle> getStructureArticles(
2932 long groupId, String ddmStructureKey)
2933 throws SystemException {
2934
2935 return journalArticlePersistence.findByG_S(groupId, ddmStructureKey);
2936 }
2937
2938
2963 @Override
2964 public List<JournalArticle> getStructureArticles(
2965 long groupId, String ddmStructureKey, int start, int end,
2966 OrderByComparator obc)
2967 throws SystemException {
2968
2969 return journalArticlePersistence.findByG_S(
2970 groupId, ddmStructureKey, start, end, obc);
2971 }
2972
2973 @Override
2974 public List<JournalArticle> getStructureArticles(String[] ddmStructureKeys)
2975 throws SystemException {
2976
2977 return journalArticlePersistence.findByStructureId(ddmStructureKeys);
2978 }
2979
2980
2990 @Override
2991 public int getStructureArticlesCount(long groupId, String ddmStructureKey)
2992 throws SystemException {
2993
2994 return journalArticlePersistence.countByG_S(groupId, ddmStructureKey);
2995 }
2996
2997
3008 @Override
3009 public List<JournalArticle> getTemplateArticles(
3010 long groupId, String ddmTemplateKey)
3011 throws SystemException {
3012
3013 return journalArticlePersistence.findByG_T(groupId, ddmTemplateKey);
3014 }
3015
3016
3043 @Override
3044 public List<JournalArticle> getTemplateArticles(
3045 long groupId, String ddmTemplateKey, int start, int end,
3046 OrderByComparator obc)
3047 throws SystemException {
3048
3049 return journalArticlePersistence.findByG_T(
3050 groupId, ddmTemplateKey, start, end, obc);
3051 }
3052
3053
3065 @Override
3066 public int getTemplateArticlesCount(long groupId, String ddmTemplateKey)
3067 throws SystemException {
3068
3069 return journalArticlePersistence.countByG_T(groupId, ddmTemplateKey);
3070 }
3071
3072 @Override
3073 public String getUniqueUrlTitle(
3074 long groupId, String articleId, String urlTitle)
3075 throws PortalException, SystemException {
3076
3077 for (int i = 1;; i++) {
3078 JournalArticle article = null;
3079
3080 try {
3081 article = getArticleByUrlTitle(groupId, urlTitle);
3082 }
3083 catch (NoSuchArticleException nsae) {
3084 }
3085
3086 if ((article == null) || articleId.equals(article.getArticleId())) {
3087 break;
3088 }
3089 else {
3090 String suffix = StringPool.DASH + i;
3091
3092 String prefix = urlTitle;
3093
3094 if (urlTitle.length() > suffix.length()) {
3095 prefix = urlTitle.substring(
3096 0, urlTitle.length() - suffix.length());
3097 }
3098
3099 urlTitle = prefix + suffix;
3100 }
3101 }
3102
3103 return urlTitle;
3104 }
3105
3106
3115 @Override
3116 public boolean hasArticle(long groupId, String articleId)
3117 throws SystemException {
3118
3119 try {
3120 getArticle(groupId, articleId);
3121
3122 return true;
3123 }
3124 catch (PortalException pe) {
3125 return false;
3126 }
3127 }
3128
3129
3142 @Override
3143 public boolean isLatestVersion(
3144 long groupId, String articleId, double version)
3145 throws PortalException, SystemException {
3146
3147 if (getLatestVersion(groupId, articleId) == version) {
3148 return true;
3149 }
3150 else {
3151 return false;
3152 }
3153 }
3154
3155
3171 @Override
3172 public boolean isLatestVersion(
3173 long groupId, String articleId, double version, int status)
3174 throws PortalException, SystemException {
3175
3176 if (getLatestVersion(groupId, articleId, status) == version) {
3177 return true;
3178 }
3179 else {
3180 return false;
3181 }
3182 }
3183
3184
3197 @Indexable(type = IndexableType.REINDEX)
3198 @Override
3199 public JournalArticle moveArticle(
3200 long groupId, String articleId, long newFolderId)
3201 throws PortalException, SystemException {
3202
3203 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3204 groupId, articleId);
3205
3206 for (JournalArticle article : articles) {
3207 article.setFolderId(newFolderId);
3208 article.setTreePath(article.buildTreePath());
3209
3210 journalArticlePersistence.update(article);
3211 }
3212
3213 return getArticle(groupId, articleId);
3214 }
3215
3216
3239 @Indexable(type = IndexableType.REINDEX)
3240 @Override
3241 public JournalArticle moveArticleFromTrash(
3242 long userId, long groupId, JournalArticle article, long newFolderId,
3243 ServiceContext serviceContext)
3244 throws PortalException, SystemException {
3245
3246 if (article.isInTrash()) {
3247 restoreArticleFromTrash(userId, article);
3248 }
3249 else {
3250 updateStatus(
3251 userId, article, article.getStatus(), null,
3252 new HashMap<String, Serializable>(), serviceContext);
3253 }
3254
3255 return moveArticle(groupId, article.getArticleId(), newFolderId);
3256 }
3257
3258
3271 @Indexable(type = IndexableType.REINDEX)
3272 @Override
3273 public JournalArticle moveArticleToTrash(
3274 long userId, JournalArticle article)
3275 throws PortalException, SystemException {
3276
3277 int oldStatus = article.getStatus();
3278
3279 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3280 article.setStatus(WorkflowConstants.STATUS_DRAFT);
3281
3282 journalArticlePersistence.update(article);
3283 }
3284
3285 List<JournalArticle> articleVersions =
3286 journalArticlePersistence.findByG_A(
3287 article.getGroupId(), article.getArticleId());
3288
3289 articleVersions = ListUtil.sort(
3290 articleVersions, new ArticleVersionComparator());
3291
3292 Map<String, Serializable> workflowContext =
3293 new HashMap<String, Serializable>();
3294
3295 workflowContext.put("articleVersions", (Serializable)articleVersions);
3296
3297 article = updateStatus(
3298 userId, article.getId(), WorkflowConstants.STATUS_IN_TRASH,
3299 workflowContext, new ServiceContext());
3300
3301 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3302 JournalArticle.class.getName(), article.getResourcePrimKey());
3303
3304 String trashArticleId = TrashUtil.getTrashTitle(
3305 trashEntry.getEntryId());
3306
3307 if (!articleVersions.isEmpty()) {
3308 for (JournalArticle articleVersion : articleVersions) {
3309 articleVersion.setArticleId(trashArticleId);
3310
3311 journalArticlePersistence.update(articleVersion);
3312 }
3313 }
3314
3315 JournalArticleResource articleResource =
3316 journalArticleResourcePersistence.fetchByPrimaryKey(
3317 article.getResourcePrimKey());
3318
3319 articleResource.setArticleId(trashArticleId);
3320
3321 journalArticleResourcePersistence.update(articleResource);
3322
3323 article.setArticleId(trashArticleId);
3324
3325 article = journalArticlePersistence.update(article);
3326
3327 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3328
3329 extraDataJSONObject.put("title", article.getTitle());
3330
3331 socialActivityLocalService.addActivity(
3332 userId, article.getGroupId(), JournalArticle.class.getName(),
3333 article.getResourcePrimKey(),
3334 SocialActivityConstants.TYPE_MOVE_TO_TRASH,
3335 extraDataJSONObject.toString(), 0);
3336
3337 if (!articleVersions.isEmpty()) {
3338 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3339 JournalArticle.class);
3340
3341 for (JournalArticle articleVersion : articleVersions) {
3342 indexer.reindex(articleVersion);
3343 }
3344 }
3345
3346 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3347 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
3348 article.getCompanyId(), article.getGroupId(),
3349 JournalArticle.class.getName(), article.getId());
3350 }
3351
3352 return article;
3353 }
3354
3355
3369 @Override
3370 public JournalArticle moveArticleToTrash(
3371 long userId, long groupId, String articleId)
3372 throws PortalException, SystemException {
3373
3374 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3375 groupId, articleId, 0, 1, new ArticleVersionComparator());
3376
3377 if (!articles.isEmpty()) {
3378 return journalArticleLocalService.moveArticleToTrash(
3379 userId, articles.get(0));
3380 }
3381
3382 return null;
3383 }
3384
3385 @Override
3386 public void rebuildTree(long companyId)
3387 throws PortalException, SystemException {
3388
3389 List<JournalArticle> articles = journalArticlePersistence.findByC_NotST(
3390 companyId, WorkflowConstants.STATUS_IN_TRASH);
3391
3392 for (JournalArticle article : articles) {
3393 if (article.isInTrashContainer()) {
3394 continue;
3395 }
3396
3397 article.setTreePath(article.buildTreePath());
3398
3399 journalArticlePersistence.update(article);
3400 }
3401 }
3402
3403
3416 @Indexable(type = IndexableType.REINDEX)
3417 @Override
3418 public JournalArticle removeArticleLocale(
3419 long groupId, String articleId, double version, String languageId)
3420 throws PortalException, SystemException {
3421
3422 JournalArticle article = journalArticlePersistence.findByG_A_V(
3423 groupId, articleId, version);
3424
3425 String title = article.getTitle();
3426
3427 title = LocalizationUtil.removeLocalization(
3428 title, "static-content", languageId, true);
3429
3430 article.setTitle(title);
3431
3432 String description = article.getDescription();
3433
3434 description = LocalizationUtil.removeLocalization(
3435 description, "static-content", languageId, true);
3436
3437 article.setDescription(description);
3438
3439 String content = article.getContent();
3440
3441 if (article.isTemplateDriven()) {
3442 content = JournalUtil.removeArticleLocale(content, languageId);
3443 }
3444 else {
3445 content = LocalizationUtil.removeLocalization(
3446 content, "static-content", languageId, true);
3447 }
3448
3449 article.setContent(content);
3450
3451 journalArticlePersistence.update(article);
3452
3453 return article;
3454 }
3455
3456
3468 @Indexable(type = IndexableType.REINDEX)
3469 @Override
3470 public JournalArticle restoreArticleFromTrash(
3471 long userId, JournalArticle article)
3472 throws PortalException, SystemException {
3473
3474 String trashArticleId = TrashUtil.getOriginalTitle(
3475 article.getArticleId());
3476
3477 List<JournalArticle> articleVersions =
3478 journalArticlePersistence.findByG_A(
3479 article.getGroupId(), article.getArticleId());
3480
3481 if (!articleVersions.isEmpty()) {
3482 for (JournalArticle articleVersion : articleVersions) {
3483 articleVersion.setArticleId(trashArticleId);
3484
3485 journalArticlePersistence.update(articleVersion);
3486 }
3487 }
3488
3489 article.setArticleId(trashArticleId);
3490
3491 journalArticlePersistence.update(article);
3492
3493 JournalArticleResource articleResource =
3494 journalArticleResourcePersistence.fetchByPrimaryKey(
3495 article.getResourcePrimKey());
3496
3497 articleResource.setArticleId(trashArticleId);
3498
3499 journalArticleResourcePersistence.update(articleResource);
3500
3501 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3502 JournalArticle.class.getName(), article.getResourcePrimKey());
3503
3504 Map<String, Serializable> workflowContext =
3505 new HashMap<String, Serializable>();
3506
3507 List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
3508 trashEntry.getEntryId());
3509
3510 workflowContext.put("trashVersions", (Serializable)trashVersions);
3511
3512 ServiceContext serviceContext = new ServiceContext();
3513
3514 serviceContext.setScopeGroupId(article.getGroupId());
3515
3516 updateStatus(
3517 userId, article, trashEntry.getStatus(), null, workflowContext,
3518 serviceContext);
3519
3520 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3521
3522 extraDataJSONObject.put("title", article.getTitle());
3523
3524 socialActivityLocalService.addActivity(
3525 userId, article.getGroupId(), JournalArticle.class.getName(),
3526 article.getResourcePrimKey(),
3527 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
3528 extraDataJSONObject.toString(), 0);
3529
3530 if (!articleVersions.isEmpty()) {
3531 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3532 JournalArticle.class);
3533
3534 for (JournalArticle articleVersion : articleVersions) {
3535 indexer.reindex(articleVersion);
3536 }
3537 }
3538
3539 return article;
3540 }
3541
3542
3604 @Override
3605 public List<JournalArticle> search(
3606 long companyId, long groupId, List<Long> folderIds,
3607 long classNameId, String keywords, Double version, String type,
3608 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3609 Date displayDateLT, int status, Date reviewDate, int start, int end,
3610 OrderByComparator obc)
3611 throws SystemException {
3612
3613 return journalArticleFinder.findByKeywords(
3614 companyId, groupId, folderIds, classNameId, keywords, version, type,
3615 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
3616 status, reviewDate, start, end, obc);
3617 }
3618
3619
3688 @Override
3689 public List<JournalArticle> search(
3690 long companyId, long groupId, List<Long> folderIds,
3691 long classNameId, String articleId, Double version, String title,
3692 String description, String content, String type,
3693 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3694 Date displayDateLT, int status, Date reviewDate,
3695 boolean andOperator, int start, int end, OrderByComparator obc)
3696 throws SystemException {
3697
3698 QueryDefinition queryDefinition = new QueryDefinition(
3699 status, start, end, obc);
3700
3701 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3702 companyId, groupId, folderIds, classNameId, articleId, version,
3703 title, description, content, type, ddmStructureKey, ddmTemplateKey,
3704 displayDateGT, displayDateLT, reviewDate, andOperator,
3705 queryDefinition);
3706 }
3707
3708
3774 @Override
3775 public List<JournalArticle> search(
3776 long companyId, long groupId, List<Long> folderIds,
3777 long classNameId, String articleId, Double version, String title,
3778 String description, String content, String type,
3779 String[] ddmStructureKeys, String[] ddmTemplateKeys,
3780 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
3781 boolean andOperator, int start, int end, OrderByComparator obc)
3782 throws SystemException {
3783
3784 QueryDefinition queryDefinition = new QueryDefinition(
3785 status, start, end, obc);
3786
3787 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3788 companyId, groupId, folderIds, classNameId, articleId, version,
3789 title, description, content, type, ddmStructureKeys,
3790 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
3791 andOperator, queryDefinition);
3792 }
3793
3794
3841 @Override
3842 public Hits search(
3843 long companyId, long groupId, List<Long> folderIds,
3844 long classNameId, String ddmStructureKey, String ddmTemplateKey,
3845 String keywords, LinkedHashMap<String, Object> params, int start,
3846 int end, Sort sort)
3847 throws SystemException {
3848
3849 String articleId = null;
3850 String title = null;
3851 String description = null;
3852 String content = null;
3853 boolean andOperator = false;
3854
3855 if (Validator.isNotNull(keywords)) {
3856 articleId = keywords;
3857 title = keywords;
3858 description = keywords;
3859 content = keywords;
3860 }
3861 else {
3862 andOperator = true;
3863 }
3864
3865 String status = String.valueOf(WorkflowConstants.STATUS_ANY);
3866
3867 if (params != null) {
3868 params.put("keywords", keywords);
3869 }
3870
3871 return search(
3872 companyId, groupId, folderIds, classNameId, articleId, title,
3873 description, content, null, status, ddmStructureKey, ddmTemplateKey,
3874 params, andOperator, start, end, sort);
3875 }
3876
3877
3938 @Override
3939 public Hits search(
3940 long companyId, long groupId, List<Long> folderIds,
3941 long classNameId, String articleId, String title,
3942 String description, String content, String type, String status,
3943 String ddmStructureKey, String ddmTemplateKey,
3944 LinkedHashMap<String, Object> params, boolean andSearch, int start,
3945 int end, Sort sort)
3946 throws SystemException {
3947
3948 try {
3949 SearchContext searchContext = new SearchContext();
3950
3951 searchContext.setAndSearch(andSearch);
3952
3953 Map<String, Serializable> attributes =
3954 new HashMap<String, Serializable>();
3955
3956 attributes.put(Field.CLASS_NAME_ID, classNameId);
3957 attributes.put(Field.CONTENT, content);
3958 attributes.put(Field.DESCRIPTION, description);
3959 attributes.put(Field.STATUS, status);
3960 attributes.put(Field.TITLE, title);
3961 attributes.put(Field.TYPE, type);
3962 attributes.put("articleId", articleId);
3963 attributes.put("ddmStructureKey", ddmStructureKey);
3964 attributes.put("ddmTemplateKey", ddmTemplateKey);
3965 attributes.put("params", params);
3966
3967 searchContext.setAttributes(attributes);
3968
3969 searchContext.setCompanyId(companyId);
3970 searchContext.setEnd(end);
3971 searchContext.setFolderIds(folderIds);
3972 searchContext.setGroupIds(new long[] {groupId});
3973 searchContext.setIncludeDiscussions(
3974 GetterUtil.getBoolean(params.get("includeDiscussions")));
3975
3976 if (params != null) {
3977 String keywords = (String)params.remove("keywords");
3978
3979 if (Validator.isNotNull(keywords)) {
3980 searchContext.setKeywords(keywords);
3981 }
3982 }
3983
3984 QueryConfig queryConfig = new QueryConfig();
3985
3986 queryConfig.setHighlightEnabled(false);
3987 queryConfig.setScoreEnabled(false);
3988
3989 searchContext.setQueryConfig(queryConfig);
3990
3991 if (sort != null) {
3992 searchContext.setSorts(sort);
3993 }
3994
3995 searchContext.setStart(start);
3996
3997 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3998 JournalArticle.class);
3999
4000 return indexer.search(searchContext);
4001 }
4002 catch (Exception e) {
4003 throw new SystemException(e);
4004 }
4005 }
4006
4007 @Override
4008 public Hits search(
4009 long groupId, long userId, long creatorUserId, int status,
4010 int start, int end)
4011 throws PortalException, SystemException {
4012
4013 Indexer indexer = IndexerRegistryUtil.getIndexer(
4014 JournalArticle.class.getName());
4015
4016 SearchContext searchContext = new SearchContext();
4017
4018 searchContext.setAttribute(Field.STATUS, status);
4019
4020 searchContext.setAttribute("paginationType", "none");
4021
4022 if (creatorUserId > 0) {
4023 searchContext.setAttribute(
4024 Field.USER_ID, String.valueOf(creatorUserId));
4025 }
4026
4027 Group group = groupLocalService.getGroup(groupId);
4028
4029 searchContext.setCompanyId(group.getCompanyId());
4030
4031 searchContext.setEnd(end);
4032 searchContext.setGroupIds(new long[] {groupId});
4033 searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true));
4034 searchContext.setStart(start);
4035 searchContext.setUserId(userId);
4036
4037 return indexer.search(searchContext);
4038 }
4039
4040
4084 @Override
4085 public int searchCount(
4086 long companyId, long groupId, List<Long> folderIds,
4087 long classNameId, String keywords, Double version, String type,
4088 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4089 Date displayDateLT, int status, Date reviewDate)
4090 throws SystemException {
4091
4092 return journalArticleFinder.countByKeywords(
4093 companyId, groupId, folderIds, classNameId, keywords, version, type,
4094 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
4095 status, reviewDate);
4096 }
4097
4098
4148 @Override
4149 public int searchCount(
4150 long companyId, long groupId, List<Long> folderIds,
4151 long classNameId, String articleId, Double version, String title,
4152 String description, String content, String type,
4153 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4154 Date displayDateLT, int status, Date reviewDate,
4155 boolean andOperator)
4156 throws SystemException {
4157
4158 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4159 companyId, groupId, folderIds, classNameId, articleId, version,
4160 title, description, content, type, ddmStructureKey, ddmTemplateKey,
4161 displayDateGT, displayDateLT, reviewDate, andOperator,
4162 new QueryDefinition(status));
4163 }
4164
4165
4215 @Override
4216 public int searchCount(
4217 long companyId, long groupId, List<Long> folderIds,
4218 long classNameId, String articleId, Double version, String title,
4219 String description, String content, String type,
4220 String[] ddmStructureKeys, String[] ddmTemplateKeys,
4221 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4222 boolean andOperator)
4223 throws SystemException {
4224
4225 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4226 companyId, groupId, folderIds, classNameId, articleId, version,
4227 title, description, content, type, ddmStructureKeys,
4228 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
4229 andOperator, new QueryDefinition(status));
4230 }
4231
4232
4242 @Override
4243 public void subscribe(long userId, long groupId)
4244 throws PortalException, SystemException {
4245
4246 subscriptionLocalService.addSubscription(
4247 userId, groupId, JournalArticle.class.getName(), groupId);
4248 }
4249
4250
4260 @Override
4261 public void unsubscribe(long userId, long groupId)
4262 throws PortalException, SystemException {
4263
4264 subscriptionLocalService.deleteSubscription(
4265 userId, JournalArticle.class.getName(), groupId);
4266 }
4267
4268
4302 @Override
4303 public JournalArticle updateArticle(
4304 long userId, long groupId, long folderId, String articleId,
4305 double version, Map<Locale, String> titleMap,
4306 Map<Locale, String> descriptionMap, String content,
4307 String layoutUuid, ServiceContext serviceContext)
4308 throws PortalException, SystemException {
4309
4310 User user = userPersistence.findByPrimaryKey(userId);
4311
4312 JournalArticle article = journalArticlePersistence.findByG_A_V(
4313 groupId, articleId, version);
4314
4315 Date displayDate = article.getDisplayDate();
4316
4317 int displayDateMonth = 0;
4318 int displayDateDay = 0;
4319 int displayDateYear = 0;
4320 int displayDateHour = 0;
4321 int displayDateMinute = 0;
4322
4323 if (displayDate != null) {
4324 Calendar displayCal = CalendarFactoryUtil.getCalendar(
4325 user.getTimeZone());
4326
4327 displayCal.setTime(displayDate);
4328
4329 displayDateMonth = displayCal.get(Calendar.MONTH);
4330 displayDateDay = displayCal.get(Calendar.DATE);
4331 displayDateYear = displayCal.get(Calendar.YEAR);
4332 displayDateHour = displayCal.get(Calendar.HOUR);
4333 displayDateMinute = displayCal.get(Calendar.MINUTE);
4334
4335 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
4336 displayDateHour += 12;
4337 }
4338 }
4339
4340 Date expirationDate = article.getExpirationDate();
4341
4342 int expirationDateMonth = 0;
4343 int expirationDateDay = 0;
4344 int expirationDateYear = 0;
4345 int expirationDateHour = 0;
4346 int expirationDateMinute = 0;
4347 boolean neverExpire = true;
4348
4349 if (expirationDate != null) {
4350 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
4351 user.getTimeZone());
4352
4353 expirationCal.setTime(expirationDate);
4354
4355 expirationDateMonth = expirationCal.get(Calendar.MONTH);
4356 expirationDateDay = expirationCal.get(Calendar.DATE);
4357 expirationDateYear = expirationCal.get(Calendar.YEAR);
4358 expirationDateHour = expirationCal.get(Calendar.HOUR);
4359 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
4360 neverExpire = false;
4361
4362 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
4363 expirationDateHour += 12;
4364 }
4365 }
4366
4367 Date reviewDate = article.getReviewDate();
4368
4369 int reviewDateMonth = 0;
4370 int reviewDateDay = 0;
4371 int reviewDateYear = 0;
4372 int reviewDateHour = 0;
4373 int reviewDateMinute = 0;
4374 boolean neverReview = true;
4375
4376 if (reviewDate != null) {
4377 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
4378 user.getTimeZone());
4379
4380 reviewCal.setTime(reviewDate);
4381
4382 reviewDateMonth = reviewCal.get(Calendar.MONTH);
4383 reviewDateDay = reviewCal.get(Calendar.DATE);
4384 reviewDateYear = reviewCal.get(Calendar.YEAR);
4385 reviewDateHour = reviewCal.get(Calendar.HOUR);
4386 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
4387 neverReview = false;
4388
4389 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
4390 reviewDateHour += 12;
4391 }
4392 }
4393
4394 return journalArticleLocalService.updateArticle(
4395 userId, groupId, folderId, articleId, version, titleMap,
4396 descriptionMap, content, article.getType(),
4397 article.getStructureId(), article.getTemplateId(), layoutUuid,
4398 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
4399 displayDateMinute, expirationDateMonth, expirationDateDay,
4400 expirationDateYear, expirationDateHour, expirationDateMinute,
4401 neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
4402 reviewDateHour, reviewDateMinute, neverReview,
4403 article.getIndexable(), article.isSmallImage(),
4404 article.getSmallImageURL(), null, null, null, serviceContext);
4405 }
4406
4407
4494 @Indexable(type = IndexableType.REINDEX)
4495 @Override
4496 public JournalArticle updateArticle(
4497 long userId, long groupId, long folderId, String articleId,
4498 double version, Map<Locale, String> titleMap,
4499 Map<Locale, String> descriptionMap, String content, String type,
4500 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
4501 int displayDateMonth, int displayDateDay, int displayDateYear,
4502 int displayDateHour, int displayDateMinute, int expirationDateMonth,
4503 int expirationDateDay, int expirationDateYear,
4504 int expirationDateHour, int expirationDateMinute,
4505 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
4506 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
4507 boolean neverReview, boolean indexable, boolean smallImage,
4508 String smallImageURL, File smallImageFile,
4509 Map<String, byte[]> images, String articleURL,
4510 ServiceContext serviceContext)
4511 throws PortalException, SystemException {
4512
4513
4514
4515 User user = userPersistence.findByPrimaryKey(userId);
4516 articleId = StringUtil.toUpperCase(articleId.trim());
4517
4518 byte[] smallImageBytes = null;
4519
4520 try {
4521 smallImageBytes = FileUtil.getBytes(smallImageFile);
4522 }
4523 catch (IOException ioe) {
4524 }
4525
4526 JournalArticle latestArticle = getLatestArticle(
4527 groupId, articleId, WorkflowConstants.STATUS_ANY);
4528
4529 JournalArticle article = latestArticle;
4530
4531 boolean imported = ExportImportThreadLocal.isImportInProcess();
4532
4533 double latestVersion = latestArticle.getVersion();
4534
4535 boolean addNewVersion = false;
4536
4537 if (imported) {
4538 if (latestVersion > version) {
4539 JournalArticle existingArticle =
4540 journalArticlePersistence.fetchByG_A_V(
4541 groupId, articleId, version);
4542
4543 if (existingArticle != null) {
4544 article = existingArticle;
4545 }
4546 else {
4547 addNewVersion = true;
4548 }
4549 }
4550 else if (latestVersion < version) {
4551 addNewVersion = true;
4552 }
4553 }
4554 else {
4555 if ((version > 0) && (version != latestVersion)) {
4556 throw new ArticleVersionException();
4557 }
4558
4559 serviceContext.validateModifiedDate(
4560 latestArticle, ArticleVersionException.class);
4561
4562 if (latestArticle.isApproved() || latestArticle.isExpired() ||
4563 latestArticle.isScheduled()) {
4564
4565 addNewVersion = true;
4566
4567 version = MathUtil.format(latestVersion + 0.1, 1, 1);
4568 }
4569 }
4570
4571 Date displayDate = null;
4572 Date expirationDate = null;
4573 Date reviewDate = null;
4574
4575 if (article.getClassNameId() ==
4576 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
4577
4578 displayDate = PortalUtil.getDate(
4579 displayDateMonth, displayDateDay, displayDateYear,
4580 displayDateHour, displayDateMinute, user.getTimeZone(),
4581 ArticleDisplayDateException.class);
4582
4583 if (!neverExpire) {
4584 expirationDate = PortalUtil.getDate(
4585 expirationDateMonth, expirationDateDay, expirationDateYear,
4586 expirationDateHour, expirationDateMinute,
4587 user.getTimeZone(), ArticleExpirationDateException.class);
4588 }
4589
4590 if (!neverReview) {
4591 reviewDate = PortalUtil.getDate(
4592 reviewDateMonth, reviewDateDay, reviewDateYear,
4593 reviewDateHour, reviewDateMinute, user.getTimeZone(),
4594 ArticleReviewDateException.class);
4595 }
4596 }
4597
4598 Date now = new Date();
4599
4600 boolean expired = false;
4601
4602 if ((expirationDate != null) && expirationDate.before(now)) {
4603 expired = true;
4604 }
4605
4606 validate(
4607 user.getCompanyId(), groupId, latestArticle.getClassNameId(),
4608 titleMap, content, type, ddmStructureKey, ddmTemplateKey,
4609 expirationDate, smallImage, smallImageURL, smallImageFile,
4610 smallImageBytes);
4611
4612 if (addNewVersion) {
4613 long id = counterLocalService.increment();
4614
4615 article = journalArticlePersistence.create(id);
4616
4617 article.setResourcePrimKey(latestArticle.getResourcePrimKey());
4618 article.setGroupId(latestArticle.getGroupId());
4619 article.setCompanyId(latestArticle.getCompanyId());
4620 article.setUserId(user.getUserId());
4621 article.setUserName(user.getFullName());
4622 article.setCreateDate(serviceContext.getModifiedDate(now));
4623 article.setClassNameId(latestArticle.getClassNameId());
4624 article.setClassPK(latestArticle.getClassPK());
4625 article.setArticleId(articleId);
4626 article.setVersion(version);
4627 article.setSmallImageId(latestArticle.getSmallImageId());
4628 }
4629
4630 Locale locale = LocaleUtil.getSiteDefault();
4631
4632 String defaultLanguageId = ParamUtil.getString(
4633 serviceContext, "defaultLanguageId");
4634
4635 if (Validator.isNull(defaultLanguageId)) {
4636 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
4637 }
4638
4639 if (Validator.isNotNull(defaultLanguageId)) {
4640 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
4641 }
4642
4643 String title = titleMap.get(locale);
4644
4645 content = format(
4646 user, groupId, articleId, article.getVersion(), addNewVersion,
4647 content, ddmStructureKey, images);
4648
4649 article.setModifiedDate(serviceContext.getModifiedDate(now));
4650 article.setFolderId(folderId);
4651 article.setTreePath(article.buildTreePath());
4652 article.setTitleMap(titleMap, locale);
4653 article.setUrlTitle(
4654 getUniqueUrlTitle(
4655 article.getId(), article.getArticleId(), title,
4656 latestArticle.getUrlTitle(), serviceContext));
4657 article.setDescriptionMap(descriptionMap, locale);
4658 article.setContent(content);
4659 article.setType(type);
4660 article.setStructureId(ddmStructureKey);
4661 article.setTemplateId(ddmTemplateKey);
4662 article.setLayoutUuid(layoutUuid);
4663 article.setDisplayDate(displayDate);
4664 article.setExpirationDate(expirationDate);
4665 article.setReviewDate(reviewDate);
4666 article.setIndexable(indexable);
4667 article.setSmallImage(smallImage);
4668
4669 if (smallImage) {
4670 if ((smallImageFile != null) && (smallImageBytes != null)) {
4671 article.setSmallImageId(counterLocalService.increment());
4672 }
4673 }
4674 else {
4675 article.setSmallImageId(0);
4676 }
4677
4678 article.setSmallImageURL(smallImageURL);
4679
4680 if (latestArticle.isPending()) {
4681 article.setStatus(latestArticle.getStatus());
4682 }
4683 else if (!expired) {
4684 article.setStatus(WorkflowConstants.STATUS_DRAFT);
4685 }
4686 else {
4687 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
4688 }
4689
4690 article.setExpandoBridgeAttributes(serviceContext);
4691
4692 journalArticlePersistence.update(article);
4693
4694
4695
4696 updateAsset(
4697 userId, article, serviceContext.getAssetCategoryIds(),
4698 serviceContext.getAssetTagNames(),
4699 serviceContext.getAssetLinkEntryIds());
4700
4701
4702
4703 if (PortalUtil.getClassNameId(DDMStructure.class) ==
4704 article.getClassNameId()) {
4705
4706 updateDDMStructureXSD(
4707 article.getClassPK(), content, serviceContext);
4708 }
4709
4710
4711
4712 saveImages(
4713 smallImage, article.getSmallImageId(), smallImageFile,
4714 smallImageBytes);
4715
4716
4717
4718 PortletPreferences preferences =
4719 ServiceContextUtil.getPortletPreferences(serviceContext);
4720
4721
4722
4723 if (expired && imported) {
4724 updateStatus(
4725 userId, article, article.getStatus(), articleURL,
4726 new HashMap<String, Serializable>(), serviceContext);
4727 }
4728
4729 if (serviceContext.getWorkflowAction() ==
4730 WorkflowConstants.ACTION_PUBLISH) {
4731
4732 sendEmail(
4733 article, articleURL, preferences, "requested", serviceContext);
4734
4735 WorkflowHandlerRegistryUtil.startWorkflowInstance(
4736 user.getCompanyId(), groupId, userId,
4737 JournalArticle.class.getName(), article.getId(), article,
4738 serviceContext);
4739 }
4740
4741 return journalArticlePersistence.findByPrimaryKey(article.getId());
4742 }
4743
4744
4773 @Override
4774 public JournalArticle updateArticle(
4775 long userId, long groupId, long folderId, String articleId,
4776 double version, String content, ServiceContext serviceContext)
4777 throws PortalException, SystemException {
4778
4779 JournalArticle article = journalArticlePersistence.findByG_A_V(
4780 groupId, articleId, version);
4781
4782 return journalArticleLocalService.updateArticle(
4783 userId, groupId, folderId, articleId, version,
4784 article.getTitleMap(), article.getDescriptionMap(), content,
4785 article.getLayoutUuid(), serviceContext);
4786 }
4787
4788
4793 @Override
4794 public JournalArticle updateArticleTranslation(
4795 long groupId, String articleId, double version, Locale locale,
4796 String title, String description, String content,
4797 Map<String, byte[]> images)
4798 throws PortalException, SystemException {
4799
4800 return journalArticleLocalService.updateArticleTranslation(
4801 groupId, articleId, version, locale, title, description, content,
4802 images, null);
4803 }
4804
4805
4827 @Indexable(type = IndexableType.REINDEX)
4828 @Override
4829 public JournalArticle updateArticleTranslation(
4830 long groupId, String articleId, double version, Locale locale,
4831 String title, String description, String content,
4832 Map<String, byte[]> images, ServiceContext serviceContext)
4833 throws PortalException, SystemException {
4834
4835 validateContent(content);
4836
4837 JournalArticle oldArticle = getLatestArticle(
4838 groupId, articleId, WorkflowConstants.STATUS_ANY);
4839
4840 double oldVersion = oldArticle.getVersion();
4841
4842 if ((version > 0) && (version != oldVersion)) {
4843 throw new ArticleVersionException();
4844 }
4845
4846 boolean incrementVersion = false;
4847
4848 if (oldArticle.isApproved() || oldArticle.isExpired()) {
4849 incrementVersion = true;
4850 }
4851
4852 if (serviceContext != null) {
4853 serviceContext.validateModifiedDate(
4854 oldArticle, ArticleVersionException.class);
4855 }
4856
4857 JournalArticle article = null;
4858
4859 User user = userPersistence.findByPrimaryKey(oldArticle.getUserId());
4860
4861 if (incrementVersion) {
4862 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
4863
4864 long id = counterLocalService.increment();
4865
4866 article = journalArticlePersistence.create(id);
4867
4868 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
4869 article.setGroupId(oldArticle.getGroupId());
4870 article.setCompanyId(oldArticle.getCompanyId());
4871 article.setUserId(oldArticle.getUserId());
4872 article.setUserName(user.getFullName());
4873 article.setCreateDate(new Date());
4874 article.setModifiedDate(new Date());
4875 article.setClassNameId(oldArticle.getClassNameId());
4876 article.setClassPK(oldArticle.getClassPK());
4877 article.setArticleId(articleId);
4878 article.setVersion(newVersion);
4879 article.setTitleMap(oldArticle.getTitleMap());
4880 article.setUrlTitle(
4881 getUniqueUrlTitle(
4882 id, articleId, title, oldArticle.getUrlTitle(),
4883 serviceContext));
4884 article.setDescriptionMap(oldArticle.getDescriptionMap());
4885 article.setType(oldArticle.getType());
4886 article.setStructureId(oldArticle.getStructureId());
4887 article.setTemplateId(oldArticle.getTemplateId());
4888 article.setLayoutUuid(oldArticle.getLayoutUuid());
4889 article.setDisplayDate(oldArticle.getDisplayDate());
4890 article.setExpirationDate(oldArticle.getExpirationDate());
4891 article.setReviewDate(oldArticle.getReviewDate());
4892 article.setIndexable(oldArticle.getIndexable());
4893 article.setSmallImage(oldArticle.getSmallImage());
4894 article.setSmallImageId(oldArticle.getSmallImageId());
4895
4896 if (article.getSmallImageId() == 0) {
4897 article.setSmallImageId(counterLocalService.increment());
4898 }
4899
4900 article.setSmallImageURL(oldArticle.getSmallImageURL());
4901
4902 article.setStatus(WorkflowConstants.STATUS_DRAFT);
4903 article.setStatusDate(new Date());
4904 }
4905 else {
4906 article = oldArticle;
4907 }
4908
4909 Map<Locale, String> titleMap = article.getTitleMap();
4910
4911 titleMap.put(locale, title);
4912
4913 article.setTitleMap(titleMap);
4914
4915 Map<Locale, String> descriptionMap = article.getDescriptionMap();
4916
4917 descriptionMap.put(locale, description);
4918
4919 article.setDescriptionMap(descriptionMap);
4920
4921 content = format(
4922 user, groupId, articleId, article.getVersion(),
4923 !oldArticle.isDraft(), content, oldArticle.getStructureId(),
4924 images);
4925
4926 article.setContent(content);
4927
4928 journalArticlePersistence.update(article);
4929
4930 return article;
4931 }
4932
4933
4946 @Override
4947 public void updateAsset(
4948 long userId, JournalArticle article, long[] assetCategoryIds,
4949 String[] assetTagNames, long[] assetLinkEntryIds)
4950 throws PortalException, SystemException {
4951
4952 boolean visible = article.isApproved();
4953
4954 if (article.getClassNameId() !=
4955 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
4956
4957 visible = false;
4958 }
4959
4960 boolean addDraftAssetEntry = false;
4961
4962 if (!article.isApproved() &&
4963 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
4964
4965 int approvedArticlesCount = journalArticlePersistence.countByG_A_ST(
4966 article.getGroupId(), article.getArticleId(),
4967 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
4968
4969 if (approvedArticlesCount > 0) {
4970 addDraftAssetEntry = true;
4971 }
4972 }
4973
4974 AssetEntry assetEntry = null;
4975
4976 if (addDraftAssetEntry) {
4977 assetEntry = assetEntryLocalService.updateEntry(
4978 userId, article.getGroupId(), article.getCreateDate(),
4979 article.getModifiedDate(), JournalArticle.class.getName(),
4980 article.getPrimaryKey(), article.getUuid(),
4981 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
4982 null, null, null, ContentTypes.TEXT_HTML, article.getTitle(),
4983 article.getDescription(), article.getDescription(), null,
4984 article.getLayoutUuid(), 0, 0, null, false);
4985 }
4986 else {
4987 JournalArticleResource journalArticleResource =
4988 journalArticleResourceLocalService.getArticleResource(
4989 article.getResourcePrimKey());
4990
4991 assetEntry = assetEntryLocalService.updateEntry(
4992 userId, article.getGroupId(), article.getCreateDate(),
4993 article.getModifiedDate(), JournalArticle.class.getName(),
4994 journalArticleResource.getResourcePrimKey(),
4995 journalArticleResource.getUuid(), getClassTypeId(article),
4996 assetCategoryIds, assetTagNames, visible, null, null, null,
4997 ContentTypes.TEXT_HTML, article.getTitle(),
4998 article.getDescription(), article.getDescription(), null,
4999 article.getLayoutUuid(), 0, 0, null, false);
5000 }
5001
5002 assetLinkLocalService.updateLinks(
5003 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5004 AssetLinkConstants.TYPE_RELATED);
5005 }
5006
5007
5022 @Indexable(type = IndexableType.REINDEX)
5023 @Override
5024 public JournalArticle updateContent(
5025 long groupId, String articleId, double version, String content)
5026 throws PortalException, SystemException {
5027
5028 JournalArticle article = journalArticlePersistence.findByG_A_V(
5029 groupId, articleId, version);
5030
5031 article.setContent(content);
5032
5033 journalArticlePersistence.update(article);
5034
5035 return article;
5036 }
5037
5038
5061 @Indexable(type = IndexableType.REINDEX)
5062 @Override
5063 public JournalArticle updateStatus(
5064 long userId, JournalArticle article, int status, String articleURL,
5065 Map<String, Serializable> workflowContext,
5066 ServiceContext serviceContext)
5067 throws PortalException, SystemException {
5068
5069
5070
5071 User user = userPersistence.findByPrimaryKey(userId);
5072 Date now = new Date();
5073
5074 if ((status == WorkflowConstants.STATUS_APPROVED) &&
5075 (article.getClassNameId() ==
5076 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5077 (article.getDisplayDate() != null) &&
5078 now.before(article.getDisplayDate())) {
5079
5080 status = WorkflowConstants.STATUS_SCHEDULED;
5081 }
5082
5083 int oldStatus = article.getStatus();
5084
5085 int oldArticleVersionStatus = WorkflowConstants.STATUS_ANY;
5086
5087 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
5088 new ArrayList<ObjectValuePair<Long, Integer>>();
5089
5090 List<JournalArticle> articleVersions =
5091 (List<JournalArticle>)workflowContext.get("articleVersions");
5092
5093 if ((articleVersions != null) && !articleVersions.isEmpty()) {
5094 JournalArticle oldArticleVersion = articleVersions.get(0);
5095
5096 oldArticleVersionStatus = oldArticleVersion.getStatus();
5097
5098 articleVersionStatusOVPs = getArticleVersionStatuses(
5099 articleVersions);
5100 }
5101
5102 article.setModifiedDate(serviceContext.getModifiedDate(now));
5103
5104 boolean neverExpire = false;
5105
5106 if (status == WorkflowConstants.STATUS_APPROVED) {
5107 Date expirationDate = article.getExpirationDate();
5108
5109 if ((expirationDate != null) && expirationDate.before(now)) {
5110 neverExpire = true;
5111
5112 article.setExpirationDate(null);
5113 }
5114 }
5115
5116 if (status == WorkflowConstants.STATUS_EXPIRED) {
5117 article.setExpirationDate(now);
5118 }
5119
5120 article.setStatus(status);
5121 article.setStatusByUserId(user.getUserId());
5122 article.setStatusByUserName(user.getFullName());
5123 article.setStatusDate(serviceContext.getModifiedDate(now));
5124
5125 journalArticlePersistence.update(article);
5126
5127 if (hasModifiedLatestApprovedVersion(
5128 article.getGroupId(), article.getArticleId(),
5129 article.getVersion())) {
5130
5131 if (status == WorkflowConstants.STATUS_APPROVED) {
5132 updateUrlTitles(
5133 article.getGroupId(), article.getArticleId(),
5134 article.getUrlTitle());
5135
5136
5137
5138 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
5139 (article.getVersion() !=
5140 JournalArticleConstants.VERSION_DEFAULT)) {
5141
5142 AssetEntry draftAssetEntry =
5143 assetEntryLocalService.fetchEntry(
5144 JournalArticle.class.getName(),
5145 article.getPrimaryKey());
5146
5147 if (draftAssetEntry != null) {
5148 long[] assetCategoryIds =
5149 draftAssetEntry.getCategoryIds();
5150 String[] assetTagNames = draftAssetEntry.getTagNames();
5151
5152 List<AssetLink> assetLinks =
5153 assetLinkLocalService.getDirectLinks(
5154 draftAssetEntry.getEntryId(),
5155 AssetLinkConstants.TYPE_RELATED);
5156
5157 long[] assetLinkEntryIds = StringUtil.split(
5158 ListUtil.toString(
5159 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
5160
5161 AssetEntry assetEntry =
5162 assetEntryLocalService.updateEntry(
5163 userId, article.getGroupId(),
5164 article.getCreateDate(),
5165 article.getModifiedDate(),
5166 JournalArticle.class.getName(),
5167 article.getResourcePrimKey(), article.getUuid(),
5168 getClassTypeId(article), assetCategoryIds,
5169 assetTagNames, false, null, null, null,
5170 ContentTypes.TEXT_HTML, article.getTitle(),
5171 article.getDescription(),
5172 article.getDescription(), null,
5173 article.getLayoutUuid(), 0, 0, null, false);
5174
5175 assetLinkLocalService.updateLinks(
5176 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5177 AssetLinkConstants.TYPE_RELATED);
5178
5179 SystemEventHierarchyEntryThreadLocal.push(
5180 JournalArticle.class);
5181
5182 try {
5183 assetEntryLocalService.deleteEntry(
5184 JournalArticle.class.getName(),
5185 article.getPrimaryKey());
5186 }
5187 finally {
5188 SystemEventHierarchyEntryThreadLocal.pop(
5189 JournalArticle.class);
5190 }
5191 }
5192 }
5193
5194 if (article.getClassNameId() ==
5195 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5196
5197
5198
5199
5200 Date[] dateInterval = getDateInterval(
5201 article.getGroupId(), article.getArticleId(),
5202 article.getDisplayDate(), article.getExpirationDate());
5203
5204 Date displayDate = dateInterval[0];
5205 Date expirationDate = dateInterval[1];
5206
5207 if (neverExpire) {
5208 expirationDate = null;
5209 }
5210
5211 assetEntryLocalService.updateEntry(
5212 JournalArticle.class.getName(),
5213 article.getResourcePrimKey(), displayDate,
5214 expirationDate, true);
5215 }
5216
5217
5218
5219 JSONObject extraDataJSONObject =
5220 JSONFactoryUtil.createJSONObject();
5221
5222 extraDataJSONObject.put("title", article.getTitle());
5223
5224 if (serviceContext.isCommandUpdate()) {
5225 socialActivityLocalService.addActivity(
5226 user.getUserId(), article.getGroupId(),
5227 JournalArticle.class.getName(),
5228 article.getResourcePrimKey(),
5229 JournalActivityKeys.UPDATE_ARTICLE,
5230 extraDataJSONObject.toString(), 0);
5231 }
5232 else {
5233 socialActivityLocalService.addUniqueActivity(
5234 user.getUserId(), article.getGroupId(),
5235 JournalArticle.class.getName(),
5236 article.getResourcePrimKey(),
5237 JournalActivityKeys.ADD_ARTICLE,
5238 extraDataJSONObject.toString(), 0);
5239 }
5240 }
5241 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
5242 updatePreviousApprovedArticle(article);
5243 }
5244 }
5245
5246 if (oldStatus == WorkflowConstants.STATUS_IN_TRASH) {
5247
5248
5249
5250 List<TrashVersion> trashVersions =
5251 (List<TrashVersion>)workflowContext.get("trashVersions");
5252
5253 for (TrashVersion trashVersion : trashVersions) {
5254 JournalArticle trashArticleVersion =
5255 journalArticlePersistence.findByPrimaryKey(
5256 trashVersion.getClassPK());
5257
5258 trashArticleVersion.setStatus(trashVersion.getStatus());
5259
5260 journalArticlePersistence.update(trashArticleVersion);
5261 }
5262
5263 trashEntryLocalService.deleteEntry(
5264 JournalArticle.class.getName(), article.getResourcePrimKey());
5265 }
5266 else if (status == WorkflowConstants.STATUS_IN_TRASH) {
5267 assetEntryLocalService.updateVisible(
5268 JournalArticle.class.getName(), article.getResourcePrimKey(),
5269 false);
5270
5271
5272
5273 for (JournalArticle articleVersion : articleVersions) {
5274 articleVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
5275
5276 journalArticlePersistence.update(articleVersion);
5277 }
5278
5279 JournalArticleResource articleResource =
5280 journalArticleResourceLocalService.getArticleResource(
5281 article.getResourcePrimKey());
5282
5283 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
5284
5285 typeSettingsProperties.put("title", article.getArticleId());
5286
5287 trashEntryLocalService.addTrashEntry(
5288 userId, article.getGroupId(), JournalArticle.class.getName(),
5289 article.getResourcePrimKey(), articleResource.getUuid(), null,
5290 oldArticleVersionStatus, articleVersionStatusOVPs,
5291 typeSettingsProperties);
5292 }
5293
5294 if ((article.getClassNameId() ==
5295 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5296 (oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
5297 (status != WorkflowConstants.STATUS_IN_TRASH)) {
5298
5299
5300
5301 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
5302 ((status == WorkflowConstants.STATUS_APPROVED) ||
5303 (status == WorkflowConstants.STATUS_DENIED))) {
5304
5305 String msg = "granted";
5306
5307 if (status == WorkflowConstants.STATUS_DENIED) {
5308 msg = "denied";
5309 }
5310
5311 try {
5312 PortletPreferences preferences =
5313 ServiceContextUtil.getPortletPreferences(
5314 serviceContext);
5315
5316 sendEmail(
5317 article, articleURL, preferences, msg, serviceContext);
5318 }
5319 catch (Exception e) {
5320 _log.error(
5321 "Unable to send email to notify the change of status " +
5322 " to " + msg + " for article " + article.getId() +
5323 ": " + e.getMessage());
5324 }
5325 }
5326
5327
5328
5329 notifySubscribers(article, serviceContext);
5330 }
5331
5332 return article;
5333 }
5334
5335
5356 @Override
5357 public JournalArticle updateStatus(
5358 long userId, long classPK, int status,
5359 Map<String, Serializable> workflowContext,
5360 ServiceContext serviceContext)
5361 throws PortalException, SystemException {
5362
5363 JournalArticle article = getArticle(classPK);
5364
5365 return journalArticleLocalService.updateStatus(
5366 userId, article, status, null, workflowContext, serviceContext);
5367 }
5368
5369
5391 @Override
5392 public JournalArticle updateStatus(
5393 long userId, long groupId, String articleId, double version,
5394 int status, String articleURL,
5395 Map<String, Serializable> workflowContext,
5396 ServiceContext serviceContext)
5397 throws PortalException, SystemException {
5398
5399 JournalArticle article = journalArticlePersistence.findByG_A_V(
5400 groupId, articleId, version);
5401
5402 return journalArticleLocalService.updateStatus(
5403 userId, article, status, articleURL, workflowContext,
5404 serviceContext);
5405 }
5406
5407
5422 @Override
5423 public void updateTemplateId(
5424 long groupId, long classNameId, String oldDDMTemplateKey,
5425 String newDDMTemplateKey)
5426 throws SystemException {
5427
5428 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
5429 groupId, classNameId, oldDDMTemplateKey);
5430
5431 for (JournalArticle article : articles) {
5432 article.setTemplateId(newDDMTemplateKey);
5433
5434 journalArticlePersistence.update(article);
5435 }
5436 }
5437
5438 protected void checkArticlesByDisplayDate(Date displayDate)
5439 throws PortalException, SystemException {
5440
5441 List<JournalArticle> articles = journalArticlePersistence.findByLtD_S(
5442 displayDate, WorkflowConstants.STATUS_SCHEDULED);
5443
5444 for (JournalArticle article : articles) {
5445 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5446 JournalArticle.class);
5447
5448 indexer.reindex(article);
5449
5450 ServiceContext serviceContext = new ServiceContext();
5451
5452 serviceContext.setCommand(Constants.UPDATE);
5453
5454 String layoutFullURL = PortalUtil.getLayoutFullURL(
5455 article.getGroupId(), PortletKeys.JOURNAL);
5456
5457 serviceContext.setLayoutFullURL(layoutFullURL);
5458
5459 serviceContext.setScopeGroupId(article.getGroupId());
5460
5461 updateStatus(
5462 article.getUserId(), article, WorkflowConstants.STATUS_APPROVED,
5463 null, new HashMap<String, Serializable>(), serviceContext);
5464 }
5465 }
5466
5467 protected void checkArticlesByExpirationDate(Date expirationDate)
5468 throws PortalException, SystemException {
5469
5470 List<JournalArticle> articles =
5471 journalArticleFinder.findByExpirationDate(
5472 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
5473 new Date(
5474 expirationDate.getTime() + _JOURNAL_ARTICLE_CHECK_INTERVAL),
5475 new QueryDefinition(WorkflowConstants.STATUS_APPROVED));
5476
5477 if (_log.isDebugEnabled()) {
5478 _log.debug("Expiring " + articles.size() + " articles");
5479 }
5480
5481 Set<Long> companyIds = new HashSet<Long>();
5482
5483 for (JournalArticle article : articles) {
5484 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
5485 List<JournalArticle> currentArticles =
5486 journalArticlePersistence.findByG_A(
5487 article.getGroupId(), article.getArticleId(),
5488 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
5489 new ArticleVersionComparator(true));
5490
5491 for (JournalArticle currentArticle : currentArticles) {
5492 currentArticle.setExpirationDate(
5493 article.getExpirationDate());
5494 currentArticle.setStatus(WorkflowConstants.STATUS_EXPIRED);
5495
5496 journalArticlePersistence.update(currentArticle);
5497 }
5498 }
5499 else {
5500 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5501
5502 journalArticlePersistence.update(article);
5503 }
5504
5505 updatePreviousApprovedArticle(article);
5506
5507 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5508 JournalArticle.class);
5509
5510 indexer.reindex(article);
5511
5512 JournalContentUtil.clearCache(
5513 article.getGroupId(), article.getArticleId(),
5514 article.getTemplateId());
5515
5516 companyIds.add(article.getCompanyId());
5517 }
5518
5519 for (long companyId : companyIds) {
5520 CacheUtil.clearCache(companyId);
5521 }
5522
5523 if (_previousCheckDate == null) {
5524 _previousCheckDate = new Date(
5525 expirationDate.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL);
5526 }
5527 }
5528
5529 protected void checkArticlesByReviewDate(Date reviewDate)
5530 throws PortalException, SystemException {
5531
5532 List<JournalArticle> articles = journalArticleFinder.findByReviewDate(
5533 JournalArticleConstants.CLASSNAME_ID_DEFAULT, reviewDate,
5534 _previousCheckDate);
5535
5536 if (_log.isDebugEnabled()) {
5537 _log.debug(
5538 "Sending review notifications for " + articles.size() +
5539 " articles");
5540 }
5541
5542 for (JournalArticle article : articles) {
5543 String articleURL = StringPool.BLANK;
5544
5545 long ownerId = article.getGroupId();
5546 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
5547 long plid = PortletKeys.PREFS_PLID_SHARED;
5548 String portletId = PortletKeys.JOURNAL;
5549
5550 PortletPreferences preferences =
5551 portletPreferencesLocalService.getPreferences(
5552 article.getCompanyId(), ownerId, ownerType, plid,
5553 portletId);
5554
5555 sendEmail(
5556 article, articleURL, preferences, "review",
5557 new ServiceContext());
5558 }
5559 }
5560
5561 protected void checkStructure(Document contentDoc, Element root)
5562 throws PortalException {
5563
5564 for (Element el : root.elements()) {
5565 checkStructureField(el, contentDoc);
5566
5567 checkStructure(contentDoc, el);
5568 }
5569 }
5570
5571 protected void checkStructure(JournalArticle article)
5572 throws PortalException, SystemException {
5573
5574 Group companyGroup = groupLocalService.getCompanyGroup(
5575 article.getCompanyId());
5576
5577 DDMStructure structure = null;
5578
5579 try {
5580 structure = ddmStructurePersistence.findByG_C_S(
5581 article.getGroupId(),
5582 PortalUtil.getClassNameId(JournalArticle.class),
5583 article.getStructureId());
5584 }
5585 catch (NoSuchStructureException nsse) {
5586 structure = ddmStructurePersistence.findByG_C_S(
5587 companyGroup.getGroupId(),
5588 PortalUtil.getClassNameId(JournalArticle.class),
5589 article.getStructureId());
5590 }
5591
5592 String content = GetterUtil.getString(article.getContent());
5593
5594 try {
5595 Document contentDocument = SAXReaderUtil.read(content);
5596 Document xsdDocument = SAXReaderUtil.read(structure.getXsd());
5597
5598 checkStructure(contentDocument, xsdDocument.getRootElement());
5599 }
5600 catch (DocumentException de) {
5601 throw new SystemException(de);
5602 }
5603 catch (StructureXsdException sxsde) {
5604 long groupId = article.getGroupId();
5605 String articleId = article.getArticleId();
5606 double version = article.getVersion();
5607
5608 if (_log.isWarnEnabled()) {
5609 _log.warn(
5610 "Article {groupId=" + groupId + ", articleId=" +
5611 articleId + ", version=" + version +
5612 "} has content that does not match its " +
5613 "structure: " + sxsde.getMessage());
5614 }
5615 }
5616 }
5617
5618 protected void checkStructureField(Element el, Document contentDoc)
5619 throws PortalException {
5620
5621 StringBuilder elPath = new StringBuilder();
5622
5623 elPath.append(el.attributeValue("name"));
5624
5625 Element elParent = el.getParent();
5626
5627 while (true) {
5628 if ((elParent == null) || elParent.getName().equals("root")) {
5629 break;
5630 }
5631
5632 elPath.insert(
5633 0, elParent.attributeValue("name") + StringPool.COMMA);
5634
5635 elParent = elParent.getParent();
5636 }
5637
5638 String[] elPathNames = StringUtil.split(elPath.toString());
5639
5640 Element contentEl = contentDoc.getRootElement();
5641
5642 for (String _elPathName : elPathNames) {
5643 boolean foundEl = false;
5644
5645 for (Element tempEl : contentEl.elements()) {
5646 if (_elPathName.equals(
5647 tempEl.attributeValue("name", StringPool.BLANK))) {
5648
5649 contentEl = tempEl;
5650 foundEl = true;
5651
5652 break;
5653 }
5654 }
5655
5656 if (!foundEl) {
5657 String elType = contentEl.attributeValue(
5658 "type", StringPool.BLANK);
5659
5660 if (!elType.equals("list") && !elType.equals("multi-list")) {
5661 throw new StructureXsdException(elPath.toString());
5662 }
5663
5664 break;
5665 }
5666 }
5667 }
5668
5669 protected void copyArticleImages(
5670 JournalArticle oldArticle, JournalArticle newArticle)
5671 throws Exception {
5672
5673 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
5674
5675 XPath xPathSelector = SAXReaderUtil.createXPath(
5676 "
5677
5678 List<Node> imageNodes = xPathSelector.selectNodes(contentDoc);
5679
5680 for (Node imageNode : imageNodes) {
5681 Element imageEl = (Element)imageNode;
5682
5683 String instanceId = imageEl.attributeValue("instance-id");
5684 String name = imageEl.attributeValue("name");
5685
5686 List<Element> dynamicContentEls = imageEl.elements(
5687 "dynamic-content");
5688
5689 for (Element dynamicContentEl : dynamicContentEls) {
5690 long imageId = GetterUtil.getLong(
5691 dynamicContentEl.attributeValue("id"));
5692 String languageId = dynamicContentEl.attributeValue(
5693 "language-id");
5694
5695 Image oldImage = null;
5696
5697 try {
5698 oldImage = imageLocalService.getImage(imageId);
5699 }
5700 catch (NoSuchImageException nsie) {
5701 continue;
5702 }
5703
5704 imageId = journalArticleImageLocalService.getArticleImageId(
5705 newArticle.getGroupId(), newArticle.getArticleId(),
5706 newArticle.getVersion(), instanceId, name, languageId);
5707
5708 imageLocalService.updateImage(imageId, oldImage.getTextObj());
5709
5710 String elContent =
5711 "/image/journal/article?img_id=" + imageId + "&t=" +
5712 WebServerServletTokenUtil.getToken(imageId);
5713
5714 dynamicContentEl.setText(elContent);
5715 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
5716 }
5717 }
5718
5719 newArticle.setContent(contentDoc.formattedString());
5720 }
5721
5722 protected void format(
5723 User user, long groupId, String articleId, double version,
5724 boolean incrementVersion, Element root, Map<String, byte[]> images)
5725 throws PortalException, SystemException {
5726
5727 for (Element element : root.elements()) {
5728 String elInstanceId = element.attributeValue(
5729 "instance-id", StringPool.BLANK);
5730 String elType = element.attributeValue("type", StringPool.BLANK);
5731
5732 if (elType.equals("image")) {
5733 String elName = element.attributeValue(
5734 "name", StringPool.BLANK);
5735 String elIndex = element.attributeValue(
5736 "index", StringPool.BLANK);
5737
5738 String name = elName + "_" + elIndex;
5739
5740 formatImage(
5741 groupId, articleId, version, incrementVersion, element,
5742 elInstanceId, name, images);
5743 }
5744 else if (elType.equals("text_area") || elType.equals("text") ||
5745 elType.equals("text_box")) {
5746
5747 List<Element> dynamicContentElements = element.elements(
5748 "dynamic-content");
5749
5750 for (Element dynamicContentElement : dynamicContentElements) {
5751 String dynamicContent = dynamicContentElement.getText();
5752
5753 if (Validator.isNotNull(dynamicContent)) {
5754 String contentType = ContentTypes.TEXT_PLAIN;
5755
5756 if (elType.equals("text_area")) {
5757 contentType = ContentTypes.TEXT_HTML;
5758 }
5759
5760 dynamicContent = SanitizerUtil.sanitize(
5761 user.getCompanyId(), groupId, user.getUserId(),
5762 JournalArticle.class.getName(), 0, contentType,
5763 dynamicContent);
5764
5765 dynamicContentElement.clearContent();
5766
5767 dynamicContentElement.addCDATA(dynamicContent);
5768 }
5769 }
5770 }
5771
5772 format(
5773 user, groupId, articleId, version, incrementVersion, element,
5774 images);
5775 }
5776 }
5777
5778 protected String format(
5779 User user, long groupId, String articleId, double version,
5780 boolean incrementVersion, String content, String ddmStructureKey,
5781 Map<String, byte[]> images)
5782 throws PortalException, SystemException {
5783
5784 Document document = null;
5785
5786 try {
5787 document = SAXReaderUtil.read(content);
5788
5789 Element rootElement = document.getRootElement();
5790
5791 if (Validator.isNotNull(ddmStructureKey)) {
5792 format(
5793 user, groupId, articleId, version, incrementVersion,
5794 rootElement, images);
5795 }
5796 else {
5797 List<Element> staticContentElements = rootElement.elements(
5798 "static-content");
5799
5800 for (Element staticContentElement : staticContentElements) {
5801 String staticContent = staticContentElement.getText();
5802
5803 staticContent = SanitizerUtil.sanitize(
5804 user.getCompanyId(), groupId, user.getUserId(),
5805 JournalArticle.class.getName(), 0,
5806 ContentTypes.TEXT_HTML, staticContent);
5807
5808 staticContentElement.clearContent();
5809
5810 staticContentElement.addCDATA(staticContent);
5811 }
5812 }
5813
5814 content = DDMXMLUtil.formatXML(document);
5815 }
5816 catch (DocumentException de) {
5817 _log.error(de, de);
5818 }
5819
5820 content = HtmlUtil.replaceMsWordCharacters(content);
5821
5822 return content;
5823 }
5824
5825 protected void formatImage(
5826 long groupId, String articleId, double version,
5827 boolean incrementVersion, Element el, String elInstanceId,
5828 String elName, Map<String, byte[]> images)
5829 throws PortalException, SystemException {
5830
5831 List<Element> imageContents = el.elements("dynamic-content");
5832
5833 for (Element dynamicContent : imageContents) {
5834 String elLanguage = dynamicContent.attributeValue(
5835 "language-id", StringPool.BLANK);
5836
5837 if (!elLanguage.equals(StringPool.BLANK)) {
5838 elLanguage = "_" + elLanguage;
5839 }
5840
5841 long imageId = journalArticleImageLocalService.getArticleImageId(
5842 groupId, articleId, version, elInstanceId, elName, elLanguage);
5843
5844 if (dynamicContent.getText().equals("delete") ||
5845 Validator.isNull(dynamicContent.getText())) {
5846
5847 dynamicContent.setText(StringPool.BLANK);
5848
5849 imageLocalService.deleteImage(imageId);
5850
5851 String defaultElLanguage = "";
5852
5853 if (Validator.isNull(elLanguage)) {
5854 defaultElLanguage =
5855 "_" +
5856 LocaleUtil.toLanguageId(
5857 LocaleUtil.getSiteDefault());
5858 }
5859
5860 long defaultImageId =
5861 journalArticleImageLocalService.getArticleImageId(
5862 groupId, articleId, version, elInstanceId, elName,
5863 defaultElLanguage);
5864
5865 imageLocalService.deleteImage(defaultImageId);
5866
5867 continue;
5868 }
5869
5870 String elContent =
5871 "/image/journal/article?img_id=" + imageId + "&t=" +
5872 WebServerServletTokenUtil.getToken(imageId);
5873
5874 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
5875
5876 if (ArrayUtil.isNotEmpty(bytes)) {
5877 dynamicContent.setText(elContent);
5878 dynamicContent.addAttribute("id", String.valueOf(imageId));
5879
5880 imageLocalService.updateImage(imageId, bytes);
5881
5882 continue;
5883 }
5884
5885 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
5886 incrementVersion) {
5887
5888 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
5889
5890 long oldImageId = 0;
5891
5892 if ((oldVersion >= 1) && incrementVersion) {
5893 oldImageId =
5894 journalArticleImageLocalService.getArticleImageId(
5895 groupId, articleId, oldVersion, elInstanceId,
5896 elName, elLanguage);
5897 }
5898
5899 Image oldImage = null;
5900
5901 if (oldImageId > 0) {
5902 oldImage = imageLocalService.getImage(oldImageId);
5903 }
5904
5905 if (oldImage != null) {
5906 dynamicContent.setText(elContent);
5907 dynamicContent.addAttribute("id", String.valueOf(imageId));
5908
5909 bytes = oldImage.getTextObj();
5910
5911 imageLocalService.updateImage(imageId, bytes);
5912 }
5913 else if (dynamicContent.getText().equals("update")) {
5914 dynamicContent.setText(StringPool.BLANK);
5915 }
5916
5917 continue;
5918 }
5919
5920 Image image = imageLocalService.getImage(imageId);
5921
5922 if (image != null) {
5923 dynamicContent.setText(elContent);
5924 dynamicContent.addAttribute("id", String.valueOf(imageId));
5925
5926 continue;
5927 }
5928 else if (dynamicContent.getText().equals("update")) {
5929 dynamicContent.setText(StringPool.BLANK);
5930
5931 continue;
5932 }
5933
5934 long contentImageId = GetterUtil.getLong(
5935 HttpUtil.getParameter(dynamicContent.getText(), "img_id"));
5936
5937 if (contentImageId <= 0) {
5938 contentImageId = GetterUtil.getLong(
5939 HttpUtil.getParameter(
5940 dynamicContent.getText(), "img_id", false));
5941 }
5942
5943 if (contentImageId > 0) {
5944 image = imageLocalService.getImage(contentImageId);
5945
5946 if (image != null) {
5947 dynamicContent.addAttribute(
5948 "id", String.valueOf(contentImageId));
5949
5950 continue;
5951 }
5952 }
5953
5954 String defaultElLanguage = "";
5955
5956 if (Validator.isNull(elLanguage)) {
5957 defaultElLanguage =
5958 "_" + LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
5959 }
5960
5961 long defaultImageId =
5962 journalArticleImageLocalService.getArticleImageId(
5963 groupId, articleId, version, elInstanceId, elName,
5964 defaultElLanguage);
5965
5966 Image defaultImage = imageLocalService.getImage(defaultImageId);
5967
5968 if (defaultImage != null) {
5969 dynamicContent.setText(elContent);
5970 dynamicContent.addAttribute(
5971 "id", String.valueOf(defaultImageId));
5972
5973 bytes = defaultImage.getTextObj();
5974
5975 imageLocalService.updateImage(defaultImageId, bytes);
5976
5977 continue;
5978 }
5979
5980 if (Validator.isNotNull(elLanguage)) {
5981 dynamicContent.setText(StringPool.BLANK);
5982 }
5983 }
5984 }
5985
5986 protected List<ObjectValuePair<Long, Integer>> getArticleVersionStatuses(
5987 List<JournalArticle> articles) {
5988
5989 List<ObjectValuePair<Long, Integer>> dlArticleVersionStatusOVPs =
5990 new ArrayList<ObjectValuePair<Long, Integer>>(articles.size());
5991
5992 for (JournalArticle article : articles) {
5993 int status = article.getStatus();
5994
5995 if (status == WorkflowConstants.STATUS_PENDING) {
5996 status = WorkflowConstants.STATUS_DRAFT;
5997 }
5998
5999 ObjectValuePair<Long, Integer> dlFileVersionStatusOVP =
6000 new ObjectValuePair<Long, Integer>(article.getId(), status);
6001
6002 dlArticleVersionStatusOVPs.add(dlFileVersionStatusOVP);
6003 }
6004
6005 return dlArticleVersionStatusOVPs;
6006 }
6007
6008 protected long getClassTypeId(JournalArticle article) {
6009 long classTypeId = 0;
6010
6011 try {
6012 long classNameId = PortalUtil.getClassNameId(JournalArticle.class);
6013
6014 DDMStructure ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6015 article.getGroupId(), classNameId, article.getStructureId());
6016
6017 if (ddmStructure == null) {
6018 Group companyGroup = groupLocalService.getCompanyGroup(
6019 article.getCompanyId());
6020
6021 ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6022 companyGroup.getGroupId(), classNameId,
6023 article.getStructureId());
6024 }
6025
6026 if (ddmStructure != null) {
6027 classTypeId = ddmStructure.getStructureId();
6028 }
6029 }
6030 catch (Exception e) {
6031 _log.error(e, e);
6032 }
6033
6034 return classTypeId;
6035 }
6036
6037 protected Date[] getDateInterval(
6038 long groupId, String articleId, Date earliestDisplayDate,
6039 Date latestExpirationDate)
6040 throws SystemException {
6041
6042 Date[] dateInterval = new Date[2];
6043
6044 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
6045 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6046
6047 boolean expiringArticle = true;
6048
6049 if (latestExpirationDate == null) {
6050 expiringArticle = false;
6051 }
6052
6053 for (JournalArticle article : articles) {
6054 if ((earliestDisplayDate == null) ||
6055 ((article.getDisplayDate() != null) &&
6056 earliestDisplayDate.after(article.getDisplayDate()))) {
6057
6058 earliestDisplayDate = article.getDisplayDate();
6059 }
6060
6061 if (expiringArticle &&
6062 ((latestExpirationDate == null) ||
6063 ((article.getExpirationDate() != null) &&
6064 latestExpirationDate.before(article.getExpirationDate())))) {
6065
6066 latestExpirationDate = article.getExpirationDate();
6067 }
6068
6069 if (expiringArticle && (article.getExpirationDate() == null) &&
6070 (latestExpirationDate != null)) {
6071
6072 expiringArticle = false;
6073 }
6074 }
6075
6076 dateInterval[0] = earliestDisplayDate;
6077 dateInterval[1] = latestExpirationDate;
6078
6079 return dateInterval;
6080 }
6081
6082 protected String getUniqueUrlTitle(
6083 long id, long groupId, String articleId, String title)
6084 throws PortalException, SystemException {
6085
6086 String urlTitle = JournalUtil.getUrlTitle(id, title);
6087
6088 return getUniqueUrlTitle(groupId, articleId, urlTitle);
6089 }
6090
6091 protected String getUniqueUrlTitle(
6092 long id, String articleId, String title, String oldUrlTitle,
6093 ServiceContext serviceContext)
6094 throws PortalException, SystemException {
6095
6096 String serviceContextUrlTitle = ParamUtil.getString(
6097 serviceContext, "urlTitle");
6098
6099 String urlTitle = null;
6100
6101 if (Validator.isNotNull(serviceContextUrlTitle)) {
6102 urlTitle = JournalUtil.getUrlTitle(id, serviceContextUrlTitle);
6103 }
6104 else if (Validator.isNotNull(oldUrlTitle)) {
6105 return oldUrlTitle;
6106 }
6107 else {
6108 urlTitle = getUniqueUrlTitle(
6109 id, serviceContext.getScopeGroupId(), articleId, title);
6110 }
6111
6112 JournalArticle urlTitleArticle = null;
6113
6114 try {
6115 urlTitleArticle = getArticleByUrlTitle(
6116 serviceContext.getScopeGroupId(), urlTitle);
6117 }
6118 catch (NoSuchArticleException nsae) {
6119 }
6120
6121 if ((urlTitleArticle != null) &&
6122 !Validator.equals(
6123 urlTitleArticle.getArticleId(), articleId)) {
6124
6125 urlTitle = getUniqueUrlTitle(
6126 id, serviceContext.getScopeGroupId(), articleId, urlTitle);
6127 }
6128
6129 return urlTitle;
6130 }
6131
6132 protected boolean hasModifiedLatestApprovedVersion(
6133 long groupId, String articleId, double version)
6134 throws PortalException, SystemException {
6135
6136 double latestApprovedVersion;
6137
6138 try {
6139 latestApprovedVersion = getLatestVersion(
6140 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6141
6142 if (version >= latestApprovedVersion) {
6143 return true;
6144 }
6145 else {
6146 return false;
6147 }
6148 }
6149 catch (NoSuchArticleException nsae) {
6150 return true;
6151 }
6152 }
6153
6154 protected void notifySubscribers(
6155 JournalArticle article, ServiceContext serviceContext)
6156 throws PortalException, SystemException {
6157
6158 if (!article.isApproved()) {
6159 return;
6160 }
6161
6162 String articleURL = PortalUtil.getControlPanelFullURL(
6163 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
6164
6165 if (Validator.isNull(articleURL)) {
6166 return;
6167 }
6168
6169 PortletPreferences preferences =
6170 ServiceContextUtil.getPortletPreferences(serviceContext);
6171
6172 if (preferences == null) {
6173 long ownerId = article.getGroupId();
6174 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
6175 long plid = PortletKeys.PREFS_PLID_SHARED;
6176 String portletId = PortletKeys.JOURNAL;
6177 String defaultPreferences = null;
6178
6179 preferences = portletPreferencesLocalService.getPreferences(
6180 article.getCompanyId(), ownerId, ownerType, plid, portletId,
6181 defaultPreferences);
6182 }
6183
6184 if ((article.getVersion() == 1.0) &&
6185 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
6186 }
6187 else if ((article.getVersion() != 1.0) &&
6188 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
6189 }
6190 else {
6191 return;
6192 }
6193
6194 String fromName = JournalUtil.getEmailFromName(
6195 preferences, article.getCompanyId());
6196 String fromAddress = JournalUtil.getEmailFromAddress(
6197 preferences, article.getCompanyId());
6198
6199 String subject = null;
6200 String body = null;
6201
6202 if (article.getVersion() == 1.0) {
6203 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
6204 body = JournalUtil.getEmailArticleAddedBody(preferences);
6205 }
6206 else {
6207 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
6208 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
6209 }
6210
6211 SubscriptionSender subscriptionSender = new SubscriptionSender();
6212
6213 subscriptionSender.setBody(body);
6214 subscriptionSender.setCompanyId(article.getCompanyId());
6215 subscriptionSender.setContextAttributes(
6216 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6217 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6218 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
6219 subscriptionSender.setContextUserPrefix("ARTICLE");
6220 subscriptionSender.setFrom(fromAddress, fromName);
6221 subscriptionSender.setHtmlFormat(true);
6222 subscriptionSender.setMailId("journal_article", article.getId());
6223 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6224 subscriptionSender.setReplyToAddress(fromAddress);
6225 subscriptionSender.setScopeGroupId(article.getGroupId());
6226 subscriptionSender.setServiceContext(serviceContext);
6227 subscriptionSender.setSubject(subject);
6228 subscriptionSender.setUserId(article.getUserId());
6229
6230 subscriptionSender.addPersistedSubscribers(
6231 JournalArticle.class.getName(), article.getResourcePrimKey());
6232
6233 JournalFolder folder = article.getFolder();
6234
6235 List<Long> folderIds = new ArrayList<Long>();
6236
6237 if (folder != null) {
6238 folderIds.add(folder.getFolderId());
6239
6240 folderIds.addAll(folder.getAncestorFolderIds());
6241 }
6242
6243 for (long curFolderId : folderIds) {
6244 subscriptionSender.addPersistedSubscribers(
6245 JournalFolder.class.getName(), curFolderId);
6246 }
6247
6248 subscriptionSender.addPersistedSubscribers(
6249 JournalFolder.class.getName(), article.getGroupId());
6250
6251 subscriptionSender.flushNotificationsAsync();
6252 }
6253
6254 protected void saveImages(
6255 boolean smallImage, long smallImageId, File smallImageFile,
6256 byte[] smallImageBytes)
6257 throws PortalException, SystemException {
6258
6259 if (smallImage) {
6260 if ((smallImageFile != null) && (smallImageBytes != null)) {
6261 imageLocalService.updateImage(smallImageId, smallImageBytes);
6262 }
6263 }
6264 else {
6265 imageLocalService.deleteImage(smallImageId);
6266 }
6267 }
6268
6269 protected void sendEmail(
6270 JournalArticle article, String articleURL,
6271 PortletPreferences preferences, String emailType,
6272 ServiceContext serviceContext)
6273 throws PortalException, SystemException {
6274
6275 if (preferences == null) {
6276 return;
6277 }
6278 else if (emailType.equals("denied") &&
6279 JournalUtil.getEmailArticleApprovalDeniedEnabled(
6280 preferences)) {
6281 }
6282 else if (emailType.equals("granted") &&
6283 JournalUtil.getEmailArticleApprovalGrantedEnabled(
6284 preferences)) {
6285 }
6286 else if (emailType.equals("requested") &&
6287 JournalUtil.getEmailArticleApprovalRequestedEnabled(
6288 preferences)) {
6289 }
6290 else if (emailType.equals("review") &&
6291 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
6292 }
6293 else {
6294 return;
6295 }
6296
6297 Company company = companyPersistence.findByPrimaryKey(
6298 article.getCompanyId());
6299
6300 User user = userPersistence.findByPrimaryKey(article.getUserId());
6301
6302 articleURL +=
6303 "&groupId=" + article.getGroupId() + "&articleId=" +
6304 article.getArticleId() + "&version=" + article.getVersion();
6305
6306 String fromName = JournalUtil.getEmailFromName(
6307 preferences, article.getCompanyId());
6308 String fromAddress = JournalUtil.getEmailFromAddress(
6309 preferences, article.getCompanyId());
6310
6311 String toName = user.getFullName();
6312 String toAddress = user.getEmailAddress();
6313
6314 if (emailType.equals("requested") || emailType.equals("review")) {
6315 String tempToName = fromName;
6316 String tempToAddress = fromAddress;
6317
6318 fromName = toName;
6319 fromAddress = toAddress;
6320
6321 toName = tempToName;
6322 toAddress = tempToAddress;
6323 }
6324
6325 String subject = null;
6326 String body = null;
6327
6328 if (emailType.equals("denied")) {
6329 subject = JournalUtil.getEmailArticleApprovalDeniedSubject(
6330 preferences);
6331 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
6332 }
6333 else if (emailType.equals("granted")) {
6334 subject = JournalUtil.getEmailArticleApprovalGrantedSubject(
6335 preferences);
6336 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
6337 }
6338 else if (emailType.equals("requested")) {
6339 subject = JournalUtil.getEmailArticleApprovalRequestedSubject(
6340 preferences);
6341 body = JournalUtil.getEmailArticleApprovalRequestedBody(
6342 preferences);
6343 }
6344 else if (emailType.equals("review")) {
6345 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
6346 body = JournalUtil.getEmailArticleReviewBody(preferences);
6347 }
6348
6349 SubscriptionSender subscriptionSender = new SubscriptionSender();
6350
6351 subscriptionSender.setBody(body);
6352 subscriptionSender.setCompanyId(company.getCompanyId());
6353 subscriptionSender.setContextAttributes(
6354 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6355 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6356 articleURL, "[$ARTICLE_USER_NAME$]", article.getUserName(),
6357 "[$ARTICLE_VERSION$]", article.getVersion());
6358 subscriptionSender.setContextUserPrefix("ARTICLE");
6359 subscriptionSender.setFrom(fromAddress, fromName);
6360 subscriptionSender.setHtmlFormat(true);
6361 subscriptionSender.setMailId("journal_article", article.getId());
6362 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6363 subscriptionSender.setScopeGroupId(article.getGroupId());
6364 subscriptionSender.setServiceContext(serviceContext);
6365 subscriptionSender.setSubject(subject);
6366 subscriptionSender.setUserId(article.getUserId());
6367
6368 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
6369
6370 subscriptionSender.flushNotificationsAsync();
6371 }
6372
6373 protected void updateDDMStructureXSD(
6374 long ddmStructureId, String content, ServiceContext serviceContext)
6375 throws PortalException, SystemException {
6376
6377 try {
6378 Document document = SAXReaderUtil.read(content);
6379
6380 Element rootElement = document.getRootElement();
6381
6382 List<Element> elements = rootElement.elements();
6383
6384 for (Element element : elements) {
6385 String fieldName = element.attributeValue(
6386 "name", StringPool.BLANK);
6387
6388 List<Element> dynamicContentElements = element.elements(
6389 "dynamic-content");
6390
6391 for (Element dynamicContentElement : dynamicContentElements) {
6392 String value = dynamicContentElement.getText();
6393
6394 ddmStructureLocalService.updateXSDFieldMetadata(
6395 ddmStructureId, fieldName,
6396 FieldConstants.PREDEFINED_VALUE, value, serviceContext);
6397 }
6398 }
6399 }
6400 catch (DocumentException de) {
6401 throw new SystemException(de);
6402 }
6403 }
6404
6405 protected void updatePreviousApprovedArticle(JournalArticle article)
6406 throws PortalException, SystemException {
6407
6408 List<JournalArticle> approvedArticles =
6409 journalArticlePersistence.findByG_A_ST(
6410 article.getGroupId(), article.getArticleId(),
6411 WorkflowConstants.STATUS_APPROVED, 0, 2);
6412
6413 if (approvedArticles.isEmpty() ||
6414 ((approvedArticles.size() == 1) &&
6415 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
6416
6417 assetEntryLocalService.updateVisible(
6418 JournalArticle.class.getName(), article.getResourcePrimKey(),
6419 false);
6420 }
6421 else {
6422 JournalArticle previousApprovedArticle = approvedArticles.get(0);
6423
6424 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
6425 previousApprovedArticle = approvedArticles.get(1);
6426 }
6427
6428 Date[] dateInterval = getDateInterval(
6429 previousApprovedArticle.getGroupId(),
6430 previousApprovedArticle.getArticleId(),
6431 previousApprovedArticle.getDisplayDate(),
6432 previousApprovedArticle.getExpirationDate());
6433
6434 Date displayDate = dateInterval[0];
6435 Date expirationDate = dateInterval[1];
6436
6437 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
6438 JournalArticle.class.getName(), article.getResourcePrimKey(),
6439 displayDate, expirationDate, true);
6440
6441 assetEntry.setModifiedDate(
6442 previousApprovedArticle.getModifiedDate());
6443
6444 assetEntryPersistence.update(assetEntry);
6445 }
6446 }
6447
6448 protected void updateUrlTitles(
6449 long groupId, String articleId, String urlTitle)
6450 throws SystemException {
6451
6452 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
6453 groupId, articleId);
6454
6455 for (JournalArticle article : articles) {
6456 if (!article.getUrlTitle().equals(urlTitle)) {
6457 article.setUrlTitle(urlTitle);
6458
6459 journalArticlePersistence.update(article);
6460 }
6461 }
6462 }
6463
6464 protected void validate(
6465 long companyId, long groupId, long classNameId,
6466 Map<Locale, String> titleMap, String content, String type,
6467 String ddmStructureKey, String ddmTemplateKey, Date expirationDate,
6468 boolean smallImage, String smallImageURL, File smallImageFile,
6469 byte[] smallImageBytes)
6470 throws PortalException, SystemException {
6471
6472 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
6473 LocalizationUtil.getDefaultLanguageId(content));
6474
6475 Locale[] availableLocales = LanguageUtil.getAvailableLocales(groupId);
6476
6477 if (!ArrayUtil.contains(availableLocales, articleDefaultLocale)) {
6478 LocaleException le = new LocaleException(
6479 LocaleException.TYPE_CONTENT,
6480 "The locale " + articleDefaultLocale +
6481 " is not available in site with groupId" + groupId);
6482
6483 Locale[] sourceAvailableLocales = {articleDefaultLocale};
6484
6485 le.setSourceAvailableLocales(sourceAvailableLocales);
6486 le.setTargetAvailableLocales(availableLocales);
6487
6488 throw le;
6489 }
6490
6491 if ((classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
6492 (titleMap.isEmpty() ||
6493 Validator.isNull(titleMap.get(articleDefaultLocale)))) {
6494
6495 throw new ArticleTitleException();
6496 }
6497 else if (Validator.isNull(type)) {
6498 throw new ArticleTypeException();
6499 }
6500
6501 validateContent(content);
6502
6503 if (Validator.isNotNull(ddmStructureKey)) {
6504 Group companyGroup = groupLocalService.getCompanyGroup(companyId);
6505
6506 DDMStructure ddmStructure = null;
6507
6508 try {
6509 ddmStructure = ddmStructurePersistence.findByG_C_S(
6510 groupId, PortalUtil.getClassNameId(JournalArticle.class),
6511 ddmStructureKey);
6512 }
6513 catch (NoSuchStructureException nsse) {
6514 ddmStructure = ddmStructurePersistence.findByG_C_S(
6515 companyGroup.getGroupId(),
6516 PortalUtil.getClassNameId(JournalArticle.class),
6517 ddmStructureKey);
6518 }
6519
6520 DDMTemplate ddmTemplate = null;
6521
6522 if (Validator.isNotNull(ddmTemplateKey)) {
6523 try {
6524 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
6525 groupId, PortalUtil.getClassNameId(DDMStructure.class),
6526 ddmTemplateKey);
6527 }
6528 catch (NoSuchTemplateException nste) {
6529 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
6530 companyGroup.getGroupId(),
6531 PortalUtil.getClassNameId(DDMStructure.class),
6532 ddmTemplateKey);
6533 }
6534
6535 if (ddmTemplate.getClassPK() != ddmStructure.getStructureId()) {
6536 throw new NoSuchTemplateException();
6537 }
6538 }
6539 else if (classNameId ==
6540 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
6541
6542 throw new NoSuchTemplateException();
6543 }
6544 }
6545
6546 if ((expirationDate != null) && expirationDate.before(new Date()) &&
6547 !ExportImportThreadLocal.isImportInProcess()) {
6548
6549 throw new ArticleExpirationDateException();
6550 }
6551
6552 String[] imageExtensions = PrefsPropsUtil.getStringArray(
6553 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
6554
6555 if (!smallImage || Validator.isNotNull(smallImageURL) ||
6556 (smallImageFile == null) || (smallImageBytes == null)) {
6557
6558 return;
6559 }
6560
6561 String smallImageName = smallImageFile.getName();
6562
6563 if (smallImageName != null) {
6564 boolean validSmallImageExtension = false;
6565
6566 for (String _imageExtension : imageExtensions) {
6567 if (StringPool.STAR.equals(_imageExtension) ||
6568 StringUtil.endsWith(smallImageName, _imageExtension)) {
6569
6570 validSmallImageExtension = true;
6571
6572 break;
6573 }
6574 }
6575
6576 if (!validSmallImageExtension) {
6577 throw new ArticleSmallImageNameException(smallImageName);
6578 }
6579 }
6580
6581 long smallImageMaxSize = PrefsPropsUtil.getLong(
6582 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
6583
6584 if ((smallImageMaxSize > 0) &&
6585 ((smallImageBytes == null) ||
6586 (smallImageBytes.length > smallImageMaxSize))) {
6587
6588 throw new ArticleSmallImageSizeException();
6589 }
6590 }
6591
6592 protected void validate(
6593 long companyId, long groupId, long classNameId, String articleId,
6594 boolean autoArticleId, double version, Map<Locale, String> titleMap,
6595 String content, String type, String ddmStructureKey,
6596 String ddmTemplateKey, Date expirationDate, boolean smallImage,
6597 String smallImageURL, File smallImageFile, byte[] smallImageBytes)
6598 throws PortalException, SystemException {
6599
6600 if (!autoArticleId) {
6601 validate(articleId);
6602 }
6603
6604 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
6605 groupId, articleId, version);
6606
6607 if (article != null) {
6608 throw new DuplicateArticleIdException();
6609 }
6610
6611 validate(
6612 companyId, groupId, classNameId, titleMap, content, type,
6613 ddmStructureKey, ddmTemplateKey, expirationDate, smallImage,
6614 smallImageURL, smallImageFile, smallImageBytes);
6615 }
6616
6617 protected void validate(String articleId) throws PortalException {
6618 if (Validator.isNull(articleId) ||
6619 (articleId.indexOf(CharPool.SPACE) != -1)) {
6620
6621 throw new ArticleIdException();
6622 }
6623 }
6624
6625 protected void validateContent(String content) throws PortalException {
6626 if (Validator.isNull(content)) {
6627 throw new ArticleContentException("Content is null");
6628 }
6629
6630 try {
6631 SAXReaderUtil.read(content);
6632 }
6633 catch (DocumentException de) {
6634 if (_log.isDebugEnabled()) {
6635 _log.debug("Invalid content:\n" + content);
6636 }
6637
6638 throw new ArticleContentException(
6639 "Unable to read content with an XML parser", de);
6640 }
6641 }
6642
6643 private static final long _JOURNAL_ARTICLE_CHECK_INTERVAL =
6644 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
6645
6646 private static Log _log = LogFactoryUtil.getLog(
6647 JournalArticleLocalServiceImpl.class);
6648
6649 private Date _previousCheckDate;
6650
6651 }