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 PortalUtil.getSiteGroupId(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 PortalUtil.getSiteGroupId(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 TrashEntry trashEntry = article.getTrashEntry();
3247
3248 if (trashEntry.isTrashEntry(
3249 JournalArticle.class, article.getResourcePrimKey())) {
3250
3251 restoreArticleFromTrash(userId, article);
3252 }
3253 else {
3254
3255
3256
3257 TrashVersion trashVersion =
3258 trashVersionLocalService.fetchVersion(
3259 trashEntry.getEntryId(), JournalArticle.class.getName(),
3260 article.getResourcePrimKey());
3261
3262 int status = WorkflowConstants.STATUS_APPROVED;
3263
3264 if (trashVersion != null) {
3265 status = trashVersion.getStatus();
3266 }
3267
3268 updateStatus(
3269 userId, article, status, null,
3270 new HashMap<String, Serializable>(), serviceContext);
3271
3272
3273
3274 if (trashVersion != null) {
3275 trashVersionLocalService.deleteTrashVersion(trashVersion);
3276 }
3277 }
3278
3279 return moveArticle(groupId, article.getArticleId(), newFolderId);
3280 }
3281
3282
3295 @Indexable(type = IndexableType.REINDEX)
3296 @Override
3297 public JournalArticle moveArticleToTrash(
3298 long userId, JournalArticle article)
3299 throws PortalException, SystemException {
3300
3301
3302
3303 int oldStatus = article.getStatus();
3304
3305 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3306 article.setStatus(WorkflowConstants.STATUS_DRAFT);
3307
3308 journalArticlePersistence.update(article);
3309 }
3310
3311 List<JournalArticle> articleVersions =
3312 journalArticlePersistence.findByG_A(
3313 article.getGroupId(), article.getArticleId());
3314
3315 articleVersions = ListUtil.sort(
3316 articleVersions, new ArticleVersionComparator());
3317
3318 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
3319 new ArrayList<ObjectValuePair<Long, Integer>>();
3320
3321 if ((articleVersions != null) && !articleVersions.isEmpty()) {
3322 articleVersionStatusOVPs = getArticleVersionStatuses(
3323 articleVersions);
3324 }
3325
3326 article = updateStatus(
3327 userId, article.getId(), WorkflowConstants.STATUS_IN_TRASH,
3328 new HashMap<String, Serializable>(), new ServiceContext());
3329
3330
3331
3332 for (JournalArticle articleVersion : articleVersions) {
3333 articleVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
3334
3335 journalArticlePersistence.update(articleVersion);
3336 }
3337
3338 JournalArticleResource articleResource =
3339 journalArticleResourceLocalService.getArticleResource(
3340 article.getResourcePrimKey());
3341
3342 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
3343
3344 typeSettingsProperties.put("title", article.getArticleId());
3345
3346 TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
3347 userId, article.getGroupId(), JournalArticle.class.getName(),
3348 article.getResourcePrimKey(), articleResource.getUuid(), null,
3349 oldStatus, articleVersionStatusOVPs, typeSettingsProperties);
3350
3351 String trashArticleId = TrashUtil.getTrashTitle(
3352 trashEntry.getEntryId());
3353
3354 if (!articleVersions.isEmpty()) {
3355 for (JournalArticle articleVersion : articleVersions) {
3356 articleVersion.setArticleId(trashArticleId);
3357
3358 journalArticlePersistence.update(articleVersion);
3359 }
3360 }
3361
3362 articleResource.setArticleId(trashArticleId);
3363
3364 journalArticleResourcePersistence.update(articleResource);
3365
3366 article.setArticleId(trashArticleId);
3367
3368 article = journalArticlePersistence.update(article);
3369
3370
3371
3372 assetEntryLocalService.updateVisible(
3373 JournalArticle.class.getName(), article.getResourcePrimKey(),
3374 false);
3375
3376
3377
3378 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3379
3380 extraDataJSONObject.put("title", article.getTitle());
3381
3382 socialActivityLocalService.addActivity(
3383 userId, article.getGroupId(), JournalArticle.class.getName(),
3384 article.getResourcePrimKey(),
3385 SocialActivityConstants.TYPE_MOVE_TO_TRASH,
3386 extraDataJSONObject.toString(), 0);
3387
3388 if (!articleVersions.isEmpty()) {
3389 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3390 JournalArticle.class);
3391
3392 for (JournalArticle articleVersion : articleVersions) {
3393 indexer.reindex(articleVersion);
3394 }
3395 }
3396
3397 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3398 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
3399 article.getCompanyId(), article.getGroupId(),
3400 JournalArticle.class.getName(), article.getId());
3401 }
3402
3403 return article;
3404 }
3405
3406
3420 @Override
3421 public JournalArticle moveArticleToTrash(
3422 long userId, long groupId, String articleId)
3423 throws PortalException, SystemException {
3424
3425 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3426 groupId, articleId, 0, 1, new ArticleVersionComparator());
3427
3428 if (!articles.isEmpty()) {
3429 return journalArticleLocalService.moveArticleToTrash(
3430 userId, articles.get(0));
3431 }
3432
3433 return null;
3434 }
3435
3436 @Override
3437 public void rebuildTree(long companyId)
3438 throws PortalException, SystemException {
3439
3440 List<JournalArticle> articles = journalArticlePersistence.findByC_NotST(
3441 companyId, WorkflowConstants.STATUS_IN_TRASH);
3442
3443 for (JournalArticle article : articles) {
3444 article.setTreePath(article.buildTreePath());
3445
3446 journalArticlePersistence.update(article);
3447 }
3448 }
3449
3450
3463 @Indexable(type = IndexableType.REINDEX)
3464 @Override
3465 public JournalArticle removeArticleLocale(
3466 long groupId, String articleId, double version, String languageId)
3467 throws PortalException, SystemException {
3468
3469 JournalArticle article = journalArticlePersistence.findByG_A_V(
3470 groupId, articleId, version);
3471
3472 String title = article.getTitle();
3473
3474 title = LocalizationUtil.removeLocalization(
3475 title, "static-content", languageId, true);
3476
3477 article.setTitle(title);
3478
3479 String description = article.getDescription();
3480
3481 description = LocalizationUtil.removeLocalization(
3482 description, "static-content", languageId, true);
3483
3484 article.setDescription(description);
3485
3486 String content = article.getContent();
3487
3488 if (article.isTemplateDriven()) {
3489 content = JournalUtil.removeArticleLocale(content, languageId);
3490 }
3491 else {
3492 content = LocalizationUtil.removeLocalization(
3493 content, "static-content", languageId, true);
3494 }
3495
3496 article.setContent(content);
3497
3498 journalArticlePersistence.update(article);
3499
3500 return article;
3501 }
3502
3503
3515 @Indexable(type = IndexableType.REINDEX)
3516 @Override
3517 public JournalArticle restoreArticleFromTrash(
3518 long userId, JournalArticle article)
3519 throws PortalException, SystemException {
3520
3521
3522
3523 String trashArticleId = TrashUtil.getOriginalTitle(
3524 article.getArticleId());
3525
3526 List<JournalArticle> articleVersions =
3527 journalArticlePersistence.findByG_A(
3528 article.getGroupId(), article.getArticleId());
3529
3530 if (!articleVersions.isEmpty()) {
3531 for (JournalArticle articleVersion : articleVersions) {
3532 articleVersion.setArticleId(trashArticleId);
3533
3534 journalArticlePersistence.update(articleVersion);
3535 }
3536 }
3537
3538 article.setArticleId(trashArticleId);
3539
3540 journalArticlePersistence.update(article);
3541
3542 JournalArticleResource articleResource =
3543 journalArticleResourcePersistence.fetchByPrimaryKey(
3544 article.getResourcePrimKey());
3545
3546 articleResource.setArticleId(trashArticleId);
3547
3548 journalArticleResourcePersistence.update(articleResource);
3549
3550 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3551 JournalArticle.class.getName(), article.getResourcePrimKey());
3552
3553 ServiceContext serviceContext = new ServiceContext();
3554
3555 serviceContext.setScopeGroupId(article.getGroupId());
3556
3557 updateStatus(
3558 userId, article, trashEntry.getStatus(), null,
3559 new HashMap<String, Serializable>(), serviceContext);
3560
3561
3562
3563 List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
3564 trashEntry.getEntryId());
3565
3566 for (TrashVersion trashVersion : trashVersions) {
3567 JournalArticle trashArticleVersion =
3568 journalArticlePersistence.findByPrimaryKey(
3569 trashVersion.getClassPK());
3570
3571 trashArticleVersion.setStatus(trashVersion.getStatus());
3572
3573 journalArticlePersistence.update(trashArticleVersion);
3574 }
3575
3576 trashEntryLocalService.deleteEntry(
3577 JournalArticle.class.getName(), article.getResourcePrimKey());
3578
3579
3580
3581 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3582
3583 extraDataJSONObject.put("title", article.getTitle());
3584
3585 socialActivityLocalService.addActivity(
3586 userId, article.getGroupId(), JournalArticle.class.getName(),
3587 article.getResourcePrimKey(),
3588 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
3589 extraDataJSONObject.toString(), 0);
3590
3591 if (!articleVersions.isEmpty()) {
3592 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3593 JournalArticle.class);
3594
3595 for (JournalArticle articleVersion : articleVersions) {
3596 indexer.reindex(articleVersion);
3597 }
3598 }
3599
3600 return article;
3601 }
3602
3603
3665 @Override
3666 public List<JournalArticle> search(
3667 long companyId, long groupId, List<Long> folderIds,
3668 long classNameId, String keywords, Double version, String type,
3669 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3670 Date displayDateLT, int status, Date reviewDate, int start, int end,
3671 OrderByComparator obc)
3672 throws SystemException {
3673
3674 return journalArticleFinder.findByKeywords(
3675 companyId, groupId, folderIds, classNameId, keywords, version, type,
3676 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
3677 status, reviewDate, start, end, obc);
3678 }
3679
3680
3749 @Override
3750 public List<JournalArticle> search(
3751 long companyId, long groupId, List<Long> folderIds,
3752 long classNameId, String articleId, Double version, String title,
3753 String description, String content, String type,
3754 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3755 Date displayDateLT, int status, Date reviewDate,
3756 boolean andOperator, int start, int end, OrderByComparator obc)
3757 throws SystemException {
3758
3759 QueryDefinition queryDefinition = new QueryDefinition(
3760 status, start, end, obc);
3761
3762 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3763 companyId, groupId, folderIds, classNameId, articleId, version,
3764 title, description, content, type, ddmStructureKey, ddmTemplateKey,
3765 displayDateGT, displayDateLT, reviewDate, andOperator,
3766 queryDefinition);
3767 }
3768
3769
3835 @Override
3836 public List<JournalArticle> search(
3837 long companyId, long groupId, List<Long> folderIds,
3838 long classNameId, String articleId, Double version, String title,
3839 String description, String content, String type,
3840 String[] ddmStructureKeys, String[] ddmTemplateKeys,
3841 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
3842 boolean andOperator, int start, int end, OrderByComparator obc)
3843 throws SystemException {
3844
3845 QueryDefinition queryDefinition = new QueryDefinition(
3846 status, start, end, obc);
3847
3848 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3849 companyId, groupId, folderIds, classNameId, articleId, version,
3850 title, description, content, type, ddmStructureKeys,
3851 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
3852 andOperator, queryDefinition);
3853 }
3854
3855
3902 @Override
3903 public Hits search(
3904 long companyId, long groupId, List<Long> folderIds,
3905 long classNameId, String ddmStructureKey, String ddmTemplateKey,
3906 String keywords, LinkedHashMap<String, Object> params, int start,
3907 int end, Sort sort)
3908 throws SystemException {
3909
3910 String articleId = null;
3911 String title = null;
3912 String description = null;
3913 String content = null;
3914 boolean andOperator = false;
3915
3916 if (Validator.isNotNull(keywords)) {
3917 articleId = keywords;
3918 title = keywords;
3919 description = keywords;
3920 content = keywords;
3921 }
3922 else {
3923 andOperator = true;
3924 }
3925
3926 String status = String.valueOf(WorkflowConstants.STATUS_ANY);
3927
3928 if (params != null) {
3929 params.put("keywords", keywords);
3930 }
3931
3932 return search(
3933 companyId, groupId, folderIds, classNameId, articleId, title,
3934 description, content, null, status, ddmStructureKey, ddmTemplateKey,
3935 params, andOperator, start, end, sort);
3936 }
3937
3938
3999 @Override
4000 public Hits search(
4001 long companyId, long groupId, List<Long> folderIds,
4002 long classNameId, String articleId, String title,
4003 String description, String content, String type, String status,
4004 String ddmStructureKey, String ddmTemplateKey,
4005 LinkedHashMap<String, Object> params, boolean andSearch, int start,
4006 int end, Sort sort)
4007 throws SystemException {
4008
4009 try {
4010 SearchContext searchContext = new SearchContext();
4011
4012 searchContext.setAndSearch(andSearch);
4013
4014 Map<String, Serializable> attributes =
4015 new HashMap<String, Serializable>();
4016
4017 attributes.put(Field.CLASS_NAME_ID, classNameId);
4018 attributes.put(Field.CONTENT, content);
4019 attributes.put(Field.DESCRIPTION, description);
4020 attributes.put(Field.STATUS, status);
4021 attributes.put(Field.TITLE, title);
4022 attributes.put(Field.TYPE, type);
4023 attributes.put("articleId", articleId);
4024 attributes.put("ddmStructureKey", ddmStructureKey);
4025 attributes.put("ddmTemplateKey", ddmTemplateKey);
4026 attributes.put("params", params);
4027
4028 searchContext.setAttributes(attributes);
4029
4030 searchContext.setCompanyId(companyId);
4031 searchContext.setEnd(end);
4032 searchContext.setFolderIds(folderIds);
4033 searchContext.setGroupIds(new long[] {groupId});
4034 searchContext.setIncludeDiscussions(
4035 GetterUtil.getBoolean(params.get("includeDiscussions")));
4036
4037 if (params != null) {
4038 String keywords = (String)params.remove("keywords");
4039
4040 if (Validator.isNotNull(keywords)) {
4041 searchContext.setKeywords(keywords);
4042 }
4043 }
4044
4045 QueryConfig queryConfig = new QueryConfig();
4046
4047 queryConfig.setHighlightEnabled(false);
4048 queryConfig.setScoreEnabled(false);
4049
4050 searchContext.setQueryConfig(queryConfig);
4051
4052 if (sort != null) {
4053 searchContext.setSorts(sort);
4054 }
4055
4056 searchContext.setStart(start);
4057
4058 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
4059 JournalArticle.class);
4060
4061 return indexer.search(searchContext);
4062 }
4063 catch (Exception e) {
4064 throw new SystemException(e);
4065 }
4066 }
4067
4068 @Override
4069 public Hits search(
4070 long groupId, long userId, long creatorUserId, int status,
4071 int start, int end)
4072 throws PortalException, SystemException {
4073
4074 Indexer indexer = IndexerRegistryUtil.getIndexer(
4075 JournalArticle.class.getName());
4076
4077 SearchContext searchContext = new SearchContext();
4078
4079 searchContext.setAttribute(Field.STATUS, status);
4080
4081 searchContext.setAttribute("paginationType", "none");
4082
4083 if (creatorUserId > 0) {
4084 searchContext.setAttribute(
4085 Field.USER_ID, String.valueOf(creatorUserId));
4086 }
4087
4088 Group group = groupLocalService.getGroup(groupId);
4089
4090 searchContext.setCompanyId(group.getCompanyId());
4091
4092 searchContext.setEnd(end);
4093 searchContext.setGroupIds(new long[] {groupId});
4094 searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true));
4095 searchContext.setStart(start);
4096 searchContext.setUserId(userId);
4097
4098 return indexer.search(searchContext);
4099 }
4100
4101
4145 @Override
4146 public int searchCount(
4147 long companyId, long groupId, List<Long> folderIds,
4148 long classNameId, String keywords, Double version, String type,
4149 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4150 Date displayDateLT, int status, Date reviewDate)
4151 throws SystemException {
4152
4153 return journalArticleFinder.countByKeywords(
4154 companyId, groupId, folderIds, classNameId, keywords, version, type,
4155 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
4156 status, reviewDate);
4157 }
4158
4159
4209 @Override
4210 public int searchCount(
4211 long companyId, long groupId, List<Long> folderIds,
4212 long classNameId, String articleId, Double version, String title,
4213 String description, String content, String type,
4214 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4215 Date displayDateLT, int status, Date reviewDate,
4216 boolean andOperator)
4217 throws SystemException {
4218
4219 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4220 companyId, groupId, folderIds, classNameId, articleId, version,
4221 title, description, content, type, ddmStructureKey, ddmTemplateKey,
4222 displayDateGT, displayDateLT, reviewDate, andOperator,
4223 new QueryDefinition(status));
4224 }
4225
4226
4276 @Override
4277 public int searchCount(
4278 long companyId, long groupId, List<Long> folderIds,
4279 long classNameId, String articleId, Double version, String title,
4280 String description, String content, String type,
4281 String[] ddmStructureKeys, String[] ddmTemplateKeys,
4282 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4283 boolean andOperator)
4284 throws SystemException {
4285
4286 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4287 companyId, groupId, folderIds, classNameId, articleId, version,
4288 title, description, content, type, ddmStructureKeys,
4289 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
4290 andOperator, new QueryDefinition(status));
4291 }
4292
4293
4303 @Override
4304 public void subscribe(long userId, long groupId)
4305 throws PortalException, SystemException {
4306
4307 subscriptionLocalService.addSubscription(
4308 userId, groupId, JournalArticle.class.getName(), groupId);
4309 }
4310
4311
4321 @Override
4322 public void unsubscribe(long userId, long groupId)
4323 throws PortalException, SystemException {
4324
4325 subscriptionLocalService.deleteSubscription(
4326 userId, JournalArticle.class.getName(), groupId);
4327 }
4328
4329
4363 @Override
4364 public JournalArticle updateArticle(
4365 long userId, long groupId, long folderId, String articleId,
4366 double version, Map<Locale, String> titleMap,
4367 Map<Locale, String> descriptionMap, String content,
4368 String layoutUuid, ServiceContext serviceContext)
4369 throws PortalException, SystemException {
4370
4371 User user = userPersistence.findByPrimaryKey(userId);
4372
4373 JournalArticle article = journalArticlePersistence.findByG_A_V(
4374 groupId, articleId, version);
4375
4376 Date displayDate = article.getDisplayDate();
4377
4378 int displayDateMonth = 0;
4379 int displayDateDay = 0;
4380 int displayDateYear = 0;
4381 int displayDateHour = 0;
4382 int displayDateMinute = 0;
4383
4384 if (displayDate != null) {
4385 Calendar displayCal = CalendarFactoryUtil.getCalendar(
4386 user.getTimeZone());
4387
4388 displayCal.setTime(displayDate);
4389
4390 displayDateMonth = displayCal.get(Calendar.MONTH);
4391 displayDateDay = displayCal.get(Calendar.DATE);
4392 displayDateYear = displayCal.get(Calendar.YEAR);
4393 displayDateHour = displayCal.get(Calendar.HOUR);
4394 displayDateMinute = displayCal.get(Calendar.MINUTE);
4395
4396 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
4397 displayDateHour += 12;
4398 }
4399 }
4400
4401 Date expirationDate = article.getExpirationDate();
4402
4403 int expirationDateMonth = 0;
4404 int expirationDateDay = 0;
4405 int expirationDateYear = 0;
4406 int expirationDateHour = 0;
4407 int expirationDateMinute = 0;
4408 boolean neverExpire = true;
4409
4410 if (expirationDate != null) {
4411 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
4412 user.getTimeZone());
4413
4414 expirationCal.setTime(expirationDate);
4415
4416 expirationDateMonth = expirationCal.get(Calendar.MONTH);
4417 expirationDateDay = expirationCal.get(Calendar.DATE);
4418 expirationDateYear = expirationCal.get(Calendar.YEAR);
4419 expirationDateHour = expirationCal.get(Calendar.HOUR);
4420 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
4421 neverExpire = false;
4422
4423 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
4424 expirationDateHour += 12;
4425 }
4426 }
4427
4428 Date reviewDate = article.getReviewDate();
4429
4430 int reviewDateMonth = 0;
4431 int reviewDateDay = 0;
4432 int reviewDateYear = 0;
4433 int reviewDateHour = 0;
4434 int reviewDateMinute = 0;
4435 boolean neverReview = true;
4436
4437 if (reviewDate != null) {
4438 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
4439 user.getTimeZone());
4440
4441 reviewCal.setTime(reviewDate);
4442
4443 reviewDateMonth = reviewCal.get(Calendar.MONTH);
4444 reviewDateDay = reviewCal.get(Calendar.DATE);
4445 reviewDateYear = reviewCal.get(Calendar.YEAR);
4446 reviewDateHour = reviewCal.get(Calendar.HOUR);
4447 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
4448 neverReview = false;
4449
4450 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
4451 reviewDateHour += 12;
4452 }
4453 }
4454
4455 return journalArticleLocalService.updateArticle(
4456 userId, groupId, folderId, articleId, version, titleMap,
4457 descriptionMap, content, article.getType(),
4458 article.getStructureId(), article.getTemplateId(), layoutUuid,
4459 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
4460 displayDateMinute, expirationDateMonth, expirationDateDay,
4461 expirationDateYear, expirationDateHour, expirationDateMinute,
4462 neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
4463 reviewDateHour, reviewDateMinute, neverReview,
4464 article.getIndexable(), article.isSmallImage(),
4465 article.getSmallImageURL(), null, null, null, serviceContext);
4466 }
4467
4468
4555 @Indexable(type = IndexableType.REINDEX)
4556 @Override
4557 public JournalArticle updateArticle(
4558 long userId, long groupId, long folderId, String articleId,
4559 double version, Map<Locale, String> titleMap,
4560 Map<Locale, String> descriptionMap, String content, String type,
4561 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
4562 int displayDateMonth, int displayDateDay, int displayDateYear,
4563 int displayDateHour, int displayDateMinute, int expirationDateMonth,
4564 int expirationDateDay, int expirationDateYear,
4565 int expirationDateHour, int expirationDateMinute,
4566 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
4567 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
4568 boolean neverReview, boolean indexable, boolean smallImage,
4569 String smallImageURL, File smallImageFile,
4570 Map<String, byte[]> images, String articleURL,
4571 ServiceContext serviceContext)
4572 throws PortalException, SystemException {
4573
4574
4575
4576 User user = userPersistence.findByPrimaryKey(userId);
4577 articleId = StringUtil.toUpperCase(articleId.trim());
4578
4579 byte[] smallImageBytes = null;
4580
4581 try {
4582 smallImageBytes = FileUtil.getBytes(smallImageFile);
4583 }
4584 catch (IOException ioe) {
4585 }
4586
4587 JournalArticle latestArticle = getLatestArticle(
4588 groupId, articleId, WorkflowConstants.STATUS_ANY);
4589
4590 JournalArticle article = latestArticle;
4591
4592 boolean imported = ExportImportThreadLocal.isImportInProcess();
4593
4594 double latestVersion = latestArticle.getVersion();
4595
4596 boolean addNewVersion = false;
4597
4598 if (imported) {
4599 if (latestVersion > version) {
4600 JournalArticle existingArticle =
4601 journalArticlePersistence.fetchByG_A_V(
4602 groupId, articleId, version);
4603
4604 if (existingArticle != null) {
4605 article = existingArticle;
4606 }
4607 else {
4608 addNewVersion = true;
4609 }
4610 }
4611 else if (latestVersion < version) {
4612 addNewVersion = true;
4613 }
4614 }
4615 else {
4616 if ((version > 0) && (version != latestVersion)) {
4617 throw new ArticleVersionException();
4618 }
4619
4620 serviceContext.validateModifiedDate(
4621 latestArticle, ArticleVersionException.class);
4622
4623 if (latestArticle.isApproved() || latestArticle.isExpired() ||
4624 latestArticle.isScheduled()) {
4625
4626 addNewVersion = true;
4627
4628 version = MathUtil.format(latestVersion + 0.1, 1, 1);
4629 }
4630 }
4631
4632 Date displayDate = null;
4633 Date expirationDate = null;
4634 Date reviewDate = null;
4635
4636 if (article.getClassNameId() ==
4637 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
4638
4639 displayDate = PortalUtil.getDate(
4640 displayDateMonth, displayDateDay, displayDateYear,
4641 displayDateHour, displayDateMinute, user.getTimeZone(),
4642 ArticleDisplayDateException.class);
4643
4644 if (!neverExpire) {
4645 expirationDate = PortalUtil.getDate(
4646 expirationDateMonth, expirationDateDay, expirationDateYear,
4647 expirationDateHour, expirationDateMinute,
4648 user.getTimeZone(), ArticleExpirationDateException.class);
4649 }
4650
4651 if (!neverReview) {
4652 reviewDate = PortalUtil.getDate(
4653 reviewDateMonth, reviewDateDay, reviewDateYear,
4654 reviewDateHour, reviewDateMinute, user.getTimeZone(),
4655 ArticleReviewDateException.class);
4656 }
4657 }
4658
4659 Date now = new Date();
4660
4661 boolean expired = false;
4662
4663 if ((expirationDate != null) && expirationDate.before(now)) {
4664 expired = true;
4665 }
4666
4667 validate(
4668 user.getCompanyId(), groupId, latestArticle.getClassNameId(),
4669 titleMap, content, type, ddmStructureKey, ddmTemplateKey,
4670 expirationDate, smallImage, smallImageURL, smallImageFile,
4671 smallImageBytes);
4672
4673 if (addNewVersion) {
4674 long id = counterLocalService.increment();
4675
4676 article = journalArticlePersistence.create(id);
4677
4678 article.setResourcePrimKey(latestArticle.getResourcePrimKey());
4679 article.setGroupId(latestArticle.getGroupId());
4680 article.setCompanyId(latestArticle.getCompanyId());
4681 article.setUserId(user.getUserId());
4682 article.setUserName(user.getFullName());
4683 article.setCreateDate(serviceContext.getModifiedDate(now));
4684 article.setClassNameId(latestArticle.getClassNameId());
4685 article.setClassPK(latestArticle.getClassPK());
4686 article.setArticleId(articleId);
4687 article.setVersion(version);
4688 article.setSmallImageId(latestArticle.getSmallImageId());
4689 }
4690
4691 Locale locale = LocaleUtil.getSiteDefault();
4692
4693 String defaultLanguageId = ParamUtil.getString(
4694 serviceContext, "defaultLanguageId");
4695
4696 if (Validator.isNull(defaultLanguageId)) {
4697 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
4698 }
4699
4700 if (Validator.isNotNull(defaultLanguageId)) {
4701 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
4702 }
4703
4704 String title = titleMap.get(locale);
4705
4706 content = format(
4707 user, groupId, articleId, article.getVersion(), addNewVersion,
4708 content, ddmStructureKey, images);
4709
4710 article.setModifiedDate(serviceContext.getModifiedDate(now));
4711 article.setFolderId(folderId);
4712 article.setTreePath(article.buildTreePath());
4713 article.setTitleMap(titleMap, locale);
4714 article.setUrlTitle(
4715 getUniqueUrlTitle(
4716 article.getId(), article.getArticleId(), title,
4717 latestArticle.getUrlTitle(), serviceContext));
4718 article.setDescriptionMap(descriptionMap, locale);
4719 article.setContent(content);
4720 article.setType(type);
4721 article.setStructureId(ddmStructureKey);
4722 article.setTemplateId(ddmTemplateKey);
4723 article.setLayoutUuid(layoutUuid);
4724 article.setDisplayDate(displayDate);
4725 article.setExpirationDate(expirationDate);
4726 article.setReviewDate(reviewDate);
4727 article.setIndexable(indexable);
4728 article.setSmallImage(smallImage);
4729
4730 if (smallImage) {
4731 if ((smallImageFile != null) && (smallImageBytes != null)) {
4732 article.setSmallImageId(counterLocalService.increment());
4733 }
4734 }
4735 else {
4736 article.setSmallImageId(0);
4737 }
4738
4739 article.setSmallImageURL(smallImageURL);
4740
4741 if (latestArticle.isPending()) {
4742 article.setStatus(latestArticle.getStatus());
4743 }
4744 else if (!expired) {
4745 article.setStatus(WorkflowConstants.STATUS_DRAFT);
4746 }
4747 else {
4748 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
4749 }
4750
4751 article.setExpandoBridgeAttributes(serviceContext);
4752
4753 journalArticlePersistence.update(article);
4754
4755
4756
4757 updateAsset(
4758 userId, article, serviceContext.getAssetCategoryIds(),
4759 serviceContext.getAssetTagNames(),
4760 serviceContext.getAssetLinkEntryIds());
4761
4762
4763
4764 if (PortalUtil.getClassNameId(DDMStructure.class) ==
4765 article.getClassNameId()) {
4766
4767 updateDDMStructureXSD(
4768 article.getClassPK(), content, serviceContext);
4769 }
4770
4771
4772
4773 saveImages(
4774 smallImage, article.getSmallImageId(), smallImageFile,
4775 smallImageBytes);
4776
4777
4778
4779 PortletPreferences preferences =
4780 ServiceContextUtil.getPortletPreferences(serviceContext);
4781
4782
4783
4784 if (expired && imported) {
4785 updateStatus(
4786 userId, article, article.getStatus(), articleURL,
4787 new HashMap<String, Serializable>(), serviceContext);
4788 }
4789
4790 if (serviceContext.getWorkflowAction() ==
4791 WorkflowConstants.ACTION_PUBLISH) {
4792
4793 sendEmail(
4794 article, articleURL, preferences, "requested", serviceContext);
4795
4796 WorkflowHandlerRegistryUtil.startWorkflowInstance(
4797 user.getCompanyId(), groupId, userId,
4798 JournalArticle.class.getName(), article.getId(), article,
4799 serviceContext);
4800 }
4801
4802 return journalArticlePersistence.findByPrimaryKey(article.getId());
4803 }
4804
4805
4834 @Override
4835 public JournalArticle updateArticle(
4836 long userId, long groupId, long folderId, String articleId,
4837 double version, String content, ServiceContext serviceContext)
4838 throws PortalException, SystemException {
4839
4840 JournalArticle article = journalArticlePersistence.findByG_A_V(
4841 groupId, articleId, version);
4842
4843 return journalArticleLocalService.updateArticle(
4844 userId, groupId, folderId, articleId, version,
4845 article.getTitleMap(), article.getDescriptionMap(), content,
4846 article.getLayoutUuid(), serviceContext);
4847 }
4848
4849
4854 @Override
4855 public JournalArticle updateArticleTranslation(
4856 long groupId, String articleId, double version, Locale locale,
4857 String title, String description, String content,
4858 Map<String, byte[]> images)
4859 throws PortalException, SystemException {
4860
4861 return journalArticleLocalService.updateArticleTranslation(
4862 groupId, articleId, version, locale, title, description, content,
4863 images, null);
4864 }
4865
4866
4888 @Indexable(type = IndexableType.REINDEX)
4889 @Override
4890 public JournalArticle updateArticleTranslation(
4891 long groupId, String articleId, double version, Locale locale,
4892 String title, String description, String content,
4893 Map<String, byte[]> images, ServiceContext serviceContext)
4894 throws PortalException, SystemException {
4895
4896 validateContent(content);
4897
4898 JournalArticle oldArticle = getLatestArticle(
4899 groupId, articleId, WorkflowConstants.STATUS_ANY);
4900
4901 double oldVersion = oldArticle.getVersion();
4902
4903 if ((version > 0) && (version != oldVersion)) {
4904 throw new ArticleVersionException();
4905 }
4906
4907 boolean incrementVersion = false;
4908
4909 if (oldArticle.isApproved() || oldArticle.isExpired()) {
4910 incrementVersion = true;
4911 }
4912
4913 if (serviceContext != null) {
4914 serviceContext.validateModifiedDate(
4915 oldArticle, ArticleVersionException.class);
4916 }
4917
4918 JournalArticle article = null;
4919
4920 User user = userPersistence.findByPrimaryKey(oldArticle.getUserId());
4921
4922 if (incrementVersion) {
4923 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
4924
4925 long id = counterLocalService.increment();
4926
4927 article = journalArticlePersistence.create(id);
4928
4929 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
4930 article.setGroupId(oldArticle.getGroupId());
4931 article.setCompanyId(oldArticle.getCompanyId());
4932 article.setUserId(oldArticle.getUserId());
4933 article.setUserName(user.getFullName());
4934 article.setCreateDate(new Date());
4935 article.setModifiedDate(new Date());
4936 article.setClassNameId(oldArticle.getClassNameId());
4937 article.setClassPK(oldArticle.getClassPK());
4938 article.setArticleId(articleId);
4939 article.setVersion(newVersion);
4940 article.setTitleMap(oldArticle.getTitleMap());
4941 article.setUrlTitle(
4942 getUniqueUrlTitle(
4943 id, articleId, title, oldArticle.getUrlTitle(),
4944 serviceContext));
4945 article.setDescriptionMap(oldArticle.getDescriptionMap());
4946 article.setType(oldArticle.getType());
4947 article.setStructureId(oldArticle.getStructureId());
4948 article.setTemplateId(oldArticle.getTemplateId());
4949 article.setLayoutUuid(oldArticle.getLayoutUuid());
4950 article.setDisplayDate(oldArticle.getDisplayDate());
4951 article.setExpirationDate(oldArticle.getExpirationDate());
4952 article.setReviewDate(oldArticle.getReviewDate());
4953 article.setIndexable(oldArticle.getIndexable());
4954 article.setSmallImage(oldArticle.getSmallImage());
4955 article.setSmallImageId(oldArticle.getSmallImageId());
4956
4957 if (article.getSmallImageId() == 0) {
4958 article.setSmallImageId(counterLocalService.increment());
4959 }
4960
4961 article.setSmallImageURL(oldArticle.getSmallImageURL());
4962
4963 article.setStatus(WorkflowConstants.STATUS_DRAFT);
4964 article.setStatusDate(new Date());
4965 }
4966 else {
4967 article = oldArticle;
4968 }
4969
4970 Map<Locale, String> titleMap = article.getTitleMap();
4971
4972 titleMap.put(locale, title);
4973
4974 article.setTitleMap(titleMap);
4975
4976 Map<Locale, String> descriptionMap = article.getDescriptionMap();
4977
4978 descriptionMap.put(locale, description);
4979
4980 article.setDescriptionMap(descriptionMap);
4981
4982 content = format(
4983 user, groupId, articleId, article.getVersion(),
4984 !oldArticle.isDraft(), content, oldArticle.getStructureId(),
4985 images);
4986
4987 article.setContent(content);
4988
4989 journalArticlePersistence.update(article);
4990
4991 return article;
4992 }
4993
4994
5007 @Override
5008 public void updateAsset(
5009 long userId, JournalArticle article, long[] assetCategoryIds,
5010 String[] assetTagNames, long[] assetLinkEntryIds)
5011 throws PortalException, SystemException {
5012
5013 boolean visible = article.isApproved();
5014
5015 if (article.getClassNameId() !=
5016 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5017
5018 visible = false;
5019 }
5020
5021 boolean addDraftAssetEntry = false;
5022
5023 if (!article.isApproved() &&
5024 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
5025
5026 int approvedArticlesCount = journalArticlePersistence.countByG_A_ST(
5027 article.getGroupId(), article.getArticleId(),
5028 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
5029
5030 if (approvedArticlesCount > 0) {
5031 addDraftAssetEntry = true;
5032 }
5033 }
5034
5035 AssetEntry assetEntry = null;
5036
5037 if (addDraftAssetEntry) {
5038 assetEntry = assetEntryLocalService.updateEntry(
5039 userId, article.getGroupId(), article.getCreateDate(),
5040 article.getModifiedDate(), JournalArticle.class.getName(),
5041 article.getPrimaryKey(), article.getUuid(),
5042 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
5043 null, null, null, ContentTypes.TEXT_HTML, article.getTitle(),
5044 article.getDescription(), article.getDescription(), null,
5045 article.getLayoutUuid(), 0, 0, null, false);
5046 }
5047 else {
5048 JournalArticleResource journalArticleResource =
5049 journalArticleResourceLocalService.getArticleResource(
5050 article.getResourcePrimKey());
5051
5052 assetEntry = assetEntryLocalService.updateEntry(
5053 userId, article.getGroupId(), article.getCreateDate(),
5054 article.getModifiedDate(), JournalArticle.class.getName(),
5055 journalArticleResource.getResourcePrimKey(),
5056 journalArticleResource.getUuid(), getClassTypeId(article),
5057 assetCategoryIds, assetTagNames, visible, null, null, null,
5058 ContentTypes.TEXT_HTML, article.getTitle(),
5059 article.getDescription(), article.getDescription(), null,
5060 article.getLayoutUuid(), 0, 0, null, false);
5061 }
5062
5063 assetLinkLocalService.updateLinks(
5064 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5065 AssetLinkConstants.TYPE_RELATED);
5066 }
5067
5068
5083 @Indexable(type = IndexableType.REINDEX)
5084 @Override
5085 public JournalArticle updateContent(
5086 long groupId, String articleId, double version, String content)
5087 throws PortalException, SystemException {
5088
5089 JournalArticle article = journalArticlePersistence.findByG_A_V(
5090 groupId, articleId, version);
5091
5092 article.setContent(content);
5093
5094 journalArticlePersistence.update(article);
5095
5096 return article;
5097 }
5098
5099
5122 @Indexable(type = IndexableType.REINDEX)
5123 @Override
5124 public JournalArticle updateStatus(
5125 long userId, JournalArticle article, int status, String articleURL,
5126 Map<String, Serializable> workflowContext,
5127 ServiceContext serviceContext)
5128 throws PortalException, SystemException {
5129
5130
5131
5132 User user = userPersistence.findByPrimaryKey(userId);
5133 Date now = new Date();
5134
5135 if ((status == WorkflowConstants.STATUS_APPROVED) &&
5136 (article.getClassNameId() ==
5137 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5138 (article.getDisplayDate() != null) &&
5139 now.before(article.getDisplayDate())) {
5140
5141 status = WorkflowConstants.STATUS_SCHEDULED;
5142 }
5143
5144 int oldStatus = article.getStatus();
5145
5146 article.setModifiedDate(serviceContext.getModifiedDate(now));
5147
5148 boolean neverExpire = false;
5149
5150 if (status == WorkflowConstants.STATUS_APPROVED) {
5151 Date expirationDate = article.getExpirationDate();
5152
5153 if ((expirationDate != null) && expirationDate.before(now)) {
5154 neverExpire = true;
5155
5156 article.setExpirationDate(null);
5157 }
5158 }
5159
5160 if (status == WorkflowConstants.STATUS_EXPIRED) {
5161 article.setExpirationDate(now);
5162 }
5163
5164 article.setStatus(status);
5165 article.setStatusByUserId(user.getUserId());
5166 article.setStatusByUserName(user.getFullName());
5167 article.setStatusDate(serviceContext.getModifiedDate(now));
5168
5169 journalArticlePersistence.update(article);
5170
5171 if (hasModifiedLatestApprovedVersion(
5172 article.getGroupId(), article.getArticleId(),
5173 article.getVersion())) {
5174
5175 if (status == WorkflowConstants.STATUS_APPROVED) {
5176 updateUrlTitles(
5177 article.getGroupId(), article.getArticleId(),
5178 article.getUrlTitle());
5179
5180
5181
5182 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
5183 (article.getVersion() !=
5184 JournalArticleConstants.VERSION_DEFAULT)) {
5185
5186 AssetEntry draftAssetEntry =
5187 assetEntryLocalService.fetchEntry(
5188 JournalArticle.class.getName(),
5189 article.getPrimaryKey());
5190
5191 if (draftAssetEntry != null) {
5192 long[] assetCategoryIds =
5193 draftAssetEntry.getCategoryIds();
5194 String[] assetTagNames = draftAssetEntry.getTagNames();
5195
5196 List<AssetLink> assetLinks =
5197 assetLinkLocalService.getDirectLinks(
5198 draftAssetEntry.getEntryId(),
5199 AssetLinkConstants.TYPE_RELATED);
5200
5201 long[] assetLinkEntryIds = StringUtil.split(
5202 ListUtil.toString(
5203 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
5204
5205 AssetEntry assetEntry =
5206 assetEntryLocalService.updateEntry(
5207 userId, article.getGroupId(),
5208 article.getCreateDate(),
5209 article.getModifiedDate(),
5210 JournalArticle.class.getName(),
5211 article.getResourcePrimKey(), article.getUuid(),
5212 getClassTypeId(article), assetCategoryIds,
5213 assetTagNames, false, null, null, null,
5214 ContentTypes.TEXT_HTML, article.getTitle(),
5215 article.getDescription(),
5216 article.getDescription(), null,
5217 article.getLayoutUuid(), 0, 0, null, false);
5218
5219 assetLinkLocalService.updateLinks(
5220 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5221 AssetLinkConstants.TYPE_RELATED);
5222
5223 SystemEventHierarchyEntryThreadLocal.push(
5224 JournalArticle.class);
5225
5226 try {
5227 assetEntryLocalService.deleteEntry(
5228 JournalArticle.class.getName(),
5229 article.getPrimaryKey());
5230 }
5231 finally {
5232 SystemEventHierarchyEntryThreadLocal.pop(
5233 JournalArticle.class);
5234 }
5235 }
5236 }
5237
5238 if (article.getClassNameId() ==
5239 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5240
5241
5242
5243
5244 Date[] dateInterval = getDateInterval(
5245 article.getGroupId(), article.getArticleId(),
5246 article.getDisplayDate(), article.getExpirationDate());
5247
5248 Date displayDate = dateInterval[0];
5249 Date expirationDate = dateInterval[1];
5250
5251 if (neverExpire) {
5252 expirationDate = null;
5253 }
5254
5255 assetEntryLocalService.updateEntry(
5256 JournalArticle.class.getName(),
5257 article.getResourcePrimKey(), displayDate,
5258 expirationDate, true);
5259 }
5260
5261
5262
5263 JSONObject extraDataJSONObject =
5264 JSONFactoryUtil.createJSONObject();
5265
5266 extraDataJSONObject.put("title", article.getTitle());
5267
5268 if (serviceContext.isCommandUpdate()) {
5269 socialActivityLocalService.addActivity(
5270 user.getUserId(), article.getGroupId(),
5271 JournalArticle.class.getName(),
5272 article.getResourcePrimKey(),
5273 JournalActivityKeys.UPDATE_ARTICLE,
5274 extraDataJSONObject.toString(), 0);
5275 }
5276 else {
5277 socialActivityLocalService.addUniqueActivity(
5278 user.getUserId(), article.getGroupId(),
5279 JournalArticle.class.getName(),
5280 article.getResourcePrimKey(),
5281 JournalActivityKeys.ADD_ARTICLE,
5282 extraDataJSONObject.toString(), 0);
5283 }
5284 }
5285 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
5286 updatePreviousApprovedArticle(article);
5287 }
5288 }
5289
5290 if ((article.getClassNameId() ==
5291 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5292 (oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
5293 (status != WorkflowConstants.STATUS_IN_TRASH)) {
5294
5295
5296
5297 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
5298 ((status == WorkflowConstants.STATUS_APPROVED) ||
5299 (status == WorkflowConstants.STATUS_DENIED))) {
5300
5301 String msg = "granted";
5302
5303 if (status == WorkflowConstants.STATUS_DENIED) {
5304 msg = "denied";
5305 }
5306
5307 try {
5308 PortletPreferences preferences =
5309 ServiceContextUtil.getPortletPreferences(
5310 serviceContext);
5311
5312 sendEmail(
5313 article, articleURL, preferences, msg, serviceContext);
5314 }
5315 catch (Exception e) {
5316 _log.error(
5317 "Unable to send email to notify the change of status " +
5318 " to " + msg + " for article " + article.getId() +
5319 ": " + e.getMessage());
5320 }
5321 }
5322
5323
5324
5325 notifySubscribers(article, serviceContext);
5326 }
5327
5328 return article;
5329 }
5330
5331
5352 @Override
5353 public JournalArticle updateStatus(
5354 long userId, long classPK, int status,
5355 Map<String, Serializable> workflowContext,
5356 ServiceContext serviceContext)
5357 throws PortalException, SystemException {
5358
5359 JournalArticle article = getArticle(classPK);
5360
5361 return journalArticleLocalService.updateStatus(
5362 userId, article, status, null, workflowContext, serviceContext);
5363 }
5364
5365
5387 @Override
5388 public JournalArticle updateStatus(
5389 long userId, long groupId, String articleId, double version,
5390 int status, String articleURL,
5391 Map<String, Serializable> workflowContext,
5392 ServiceContext serviceContext)
5393 throws PortalException, SystemException {
5394
5395 JournalArticle article = journalArticlePersistence.findByG_A_V(
5396 groupId, articleId, version);
5397
5398 return journalArticleLocalService.updateStatus(
5399 userId, article, status, articleURL, workflowContext,
5400 serviceContext);
5401 }
5402
5403
5418 @Override
5419 public void updateTemplateId(
5420 long groupId, long classNameId, String oldDDMTemplateKey,
5421 String newDDMTemplateKey)
5422 throws SystemException {
5423
5424 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
5425 groupId, classNameId, oldDDMTemplateKey);
5426
5427 for (JournalArticle article : articles) {
5428 article.setTemplateId(newDDMTemplateKey);
5429
5430 journalArticlePersistence.update(article);
5431 }
5432 }
5433
5434 protected void checkArticlesByDisplayDate(Date displayDate)
5435 throws PortalException, SystemException {
5436
5437 List<JournalArticle> articles = journalArticlePersistence.findByLtD_S(
5438 displayDate, WorkflowConstants.STATUS_SCHEDULED);
5439
5440 for (JournalArticle article : articles) {
5441 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5442 JournalArticle.class);
5443
5444 indexer.reindex(article);
5445
5446 ServiceContext serviceContext = new ServiceContext();
5447
5448 serviceContext.setCommand(Constants.UPDATE);
5449
5450 String layoutFullURL = PortalUtil.getLayoutFullURL(
5451 article.getGroupId(), PortletKeys.JOURNAL);
5452
5453 serviceContext.setLayoutFullURL(layoutFullURL);
5454
5455 serviceContext.setScopeGroupId(article.getGroupId());
5456
5457 updateStatus(
5458 article.getUserId(), article, WorkflowConstants.STATUS_APPROVED,
5459 null, new HashMap<String, Serializable>(), serviceContext);
5460 }
5461 }
5462
5463 protected void checkArticlesByExpirationDate(Date expirationDate)
5464 throws PortalException, SystemException {
5465
5466 List<JournalArticle> articles =
5467 journalArticleFinder.findByExpirationDate(
5468 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
5469 new Date(
5470 expirationDate.getTime() + _JOURNAL_ARTICLE_CHECK_INTERVAL),
5471 new QueryDefinition(WorkflowConstants.STATUS_APPROVED));
5472
5473 if (_log.isDebugEnabled()) {
5474 _log.debug("Expiring " + articles.size() + " articles");
5475 }
5476
5477 Set<Long> companyIds = new HashSet<Long>();
5478
5479 for (JournalArticle article : articles) {
5480 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
5481 List<JournalArticle> currentArticles =
5482 journalArticlePersistence.findByG_A(
5483 article.getGroupId(), article.getArticleId(),
5484 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
5485 new ArticleVersionComparator(true));
5486
5487 for (JournalArticle currentArticle : currentArticles) {
5488 currentArticle.setExpirationDate(
5489 article.getExpirationDate());
5490 currentArticle.setStatus(WorkflowConstants.STATUS_EXPIRED);
5491
5492 journalArticlePersistence.update(currentArticle);
5493 }
5494 }
5495 else {
5496 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5497
5498 journalArticlePersistence.update(article);
5499 }
5500
5501 updatePreviousApprovedArticle(article);
5502
5503 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5504 JournalArticle.class);
5505
5506 indexer.reindex(article);
5507
5508 JournalContentUtil.clearCache(
5509 article.getGroupId(), article.getArticleId(),
5510 article.getTemplateId());
5511
5512 companyIds.add(article.getCompanyId());
5513 }
5514
5515 for (long companyId : companyIds) {
5516 CacheUtil.clearCache(companyId);
5517 }
5518
5519 if (_previousCheckDate == null) {
5520 _previousCheckDate = new Date(
5521 expirationDate.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL);
5522 }
5523 }
5524
5525 protected void checkArticlesByReviewDate(Date reviewDate)
5526 throws PortalException, SystemException {
5527
5528 List<JournalArticle> articles = journalArticleFinder.findByReviewDate(
5529 JournalArticleConstants.CLASSNAME_ID_DEFAULT, reviewDate,
5530 _previousCheckDate);
5531
5532 if (_log.isDebugEnabled()) {
5533 _log.debug(
5534 "Sending review notifications for " + articles.size() +
5535 " articles");
5536 }
5537
5538 for (JournalArticle article : articles) {
5539 String articleURL = StringPool.BLANK;
5540
5541 long ownerId = article.getGroupId();
5542 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
5543 long plid = PortletKeys.PREFS_PLID_SHARED;
5544 String portletId = PortletKeys.JOURNAL;
5545
5546 PortletPreferences preferences =
5547 portletPreferencesLocalService.getPreferences(
5548 article.getCompanyId(), ownerId, ownerType, plid,
5549 portletId);
5550
5551 sendEmail(
5552 article, articleURL, preferences, "review",
5553 new ServiceContext());
5554 }
5555 }
5556
5557 protected void checkStructure(Document contentDoc, Element root)
5558 throws PortalException {
5559
5560 for (Element el : root.elements()) {
5561 checkStructureField(el, contentDoc);
5562
5563 checkStructure(contentDoc, el);
5564 }
5565 }
5566
5567 protected void checkStructure(JournalArticle article)
5568 throws PortalException, SystemException {
5569
5570 Group companyGroup = groupLocalService.getCompanyGroup(
5571 article.getCompanyId());
5572
5573 DDMStructure structure = null;
5574
5575 try {
5576 structure = ddmStructurePersistence.findByG_C_S(
5577 PortalUtil.getSiteGroupId(article.getGroupId()),
5578 PortalUtil.getClassNameId(JournalArticle.class),
5579 article.getStructureId());
5580 }
5581 catch (NoSuchStructureException nsse) {
5582 structure = ddmStructurePersistence.findByG_C_S(
5583 companyGroup.getGroupId(),
5584 PortalUtil.getClassNameId(JournalArticle.class),
5585 article.getStructureId());
5586 }
5587
5588 String content = GetterUtil.getString(article.getContent());
5589
5590 try {
5591 Document contentDocument = SAXReaderUtil.read(content);
5592 Document xsdDocument = SAXReaderUtil.read(structure.getXsd());
5593
5594 checkStructure(contentDocument, xsdDocument.getRootElement());
5595 }
5596 catch (DocumentException de) {
5597 throw new SystemException(de);
5598 }
5599 catch (StructureXsdException sxsde) {
5600 long groupId = article.getGroupId();
5601 String articleId = article.getArticleId();
5602 double version = article.getVersion();
5603
5604 if (_log.isWarnEnabled()) {
5605 _log.warn(
5606 "Article {groupId=" + groupId + ", articleId=" +
5607 articleId + ", version=" + version +
5608 "} has content that does not match its " +
5609 "structure: " + sxsde.getMessage());
5610 }
5611 }
5612 }
5613
5614 protected void checkStructureField(Element el, Document contentDoc)
5615 throws PortalException {
5616
5617 StringBuilder elPath = new StringBuilder();
5618
5619 elPath.append(el.attributeValue("name"));
5620
5621 Element elParent = el.getParent();
5622
5623 while (true) {
5624 if ((elParent == null) || elParent.getName().equals("root")) {
5625 break;
5626 }
5627
5628 elPath.insert(
5629 0, elParent.attributeValue("name") + StringPool.COMMA);
5630
5631 elParent = elParent.getParent();
5632 }
5633
5634 String[] elPathNames = StringUtil.split(elPath.toString());
5635
5636 Element contentEl = contentDoc.getRootElement();
5637
5638 for (String _elPathName : elPathNames) {
5639 boolean foundEl = false;
5640
5641 for (Element tempEl : contentEl.elements()) {
5642 if (_elPathName.equals(
5643 tempEl.attributeValue("name", StringPool.BLANK))) {
5644
5645 contentEl = tempEl;
5646 foundEl = true;
5647
5648 break;
5649 }
5650 }
5651
5652 if (!foundEl) {
5653 String elType = contentEl.attributeValue(
5654 "type", StringPool.BLANK);
5655
5656 if (!elType.equals("list") && !elType.equals("multi-list")) {
5657 throw new StructureXsdException(elPath.toString());
5658 }
5659
5660 break;
5661 }
5662 }
5663 }
5664
5665 protected void copyArticleImages(
5666 JournalArticle oldArticle, JournalArticle newArticle)
5667 throws Exception {
5668
5669 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
5670
5671 XPath xPathSelector = SAXReaderUtil.createXPath(
5672 "
5673
5674 List<Node> imageNodes = xPathSelector.selectNodes(contentDoc);
5675
5676 for (Node imageNode : imageNodes) {
5677 Element imageEl = (Element)imageNode;
5678
5679 String instanceId = imageEl.attributeValue("instance-id");
5680 String name = imageEl.attributeValue("name");
5681
5682 List<Element> dynamicContentEls = imageEl.elements(
5683 "dynamic-content");
5684
5685 for (Element dynamicContentEl : dynamicContentEls) {
5686 long imageId = GetterUtil.getLong(
5687 dynamicContentEl.attributeValue("id"));
5688 String languageId = dynamicContentEl.attributeValue(
5689 "language-id");
5690
5691 Image oldImage = null;
5692
5693 try {
5694 oldImage = imageLocalService.getImage(imageId);
5695 }
5696 catch (NoSuchImageException nsie) {
5697 continue;
5698 }
5699
5700 imageId = journalArticleImageLocalService.getArticleImageId(
5701 newArticle.getGroupId(), newArticle.getArticleId(),
5702 newArticle.getVersion(), instanceId, name, languageId);
5703
5704 imageLocalService.updateImage(imageId, oldImage.getTextObj());
5705
5706 String elContent =
5707 "/image/journal/article?img_id=" + imageId + "&t=" +
5708 WebServerServletTokenUtil.getToken(imageId);
5709
5710 dynamicContentEl.setText(elContent);
5711 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
5712 }
5713 }
5714
5715 newArticle.setContent(contentDoc.formattedString());
5716 }
5717
5718 protected void format(
5719 User user, long groupId, String articleId, double version,
5720 boolean incrementVersion, Element root, Map<String, byte[]> images)
5721 throws PortalException, SystemException {
5722
5723 for (Element element : root.elements()) {
5724 String elInstanceId = element.attributeValue(
5725 "instance-id", StringPool.BLANK);
5726 String elType = element.attributeValue("type", StringPool.BLANK);
5727
5728 if (elType.equals("image")) {
5729 String elName = element.attributeValue(
5730 "name", StringPool.BLANK);
5731 String elIndex = element.attributeValue(
5732 "index", StringPool.BLANK);
5733
5734 String name = elName + "_" + elIndex;
5735
5736 formatImage(
5737 groupId, articleId, version, incrementVersion, element,
5738 elInstanceId, name, images);
5739 }
5740 else if (elType.equals("text_area") || elType.equals("text") ||
5741 elType.equals("text_box")) {
5742
5743 List<Element> dynamicContentElements = element.elements(
5744 "dynamic-content");
5745
5746 for (Element dynamicContentElement : dynamicContentElements) {
5747 String dynamicContent = dynamicContentElement.getText();
5748
5749 if (Validator.isNotNull(dynamicContent)) {
5750 String contentType = ContentTypes.TEXT_PLAIN;
5751
5752 if (elType.equals("text_area")) {
5753 contentType = ContentTypes.TEXT_HTML;
5754 }
5755
5756 dynamicContent = SanitizerUtil.sanitize(
5757 user.getCompanyId(), groupId, user.getUserId(),
5758 JournalArticle.class.getName(), 0, contentType,
5759 dynamicContent);
5760
5761 dynamicContentElement.clearContent();
5762
5763 dynamicContentElement.addCDATA(dynamicContent);
5764 }
5765 }
5766 }
5767
5768 format(
5769 user, groupId, articleId, version, incrementVersion, element,
5770 images);
5771 }
5772 }
5773
5774 protected String format(
5775 User user, long groupId, String articleId, double version,
5776 boolean incrementVersion, String content, String ddmStructureKey,
5777 Map<String, byte[]> images)
5778 throws PortalException, SystemException {
5779
5780 Document document = null;
5781
5782 try {
5783 document = SAXReaderUtil.read(content);
5784
5785 Element rootElement = document.getRootElement();
5786
5787 if (Validator.isNotNull(ddmStructureKey)) {
5788 format(
5789 user, groupId, articleId, version, incrementVersion,
5790 rootElement, images);
5791 }
5792 else {
5793 List<Element> staticContentElements = rootElement.elements(
5794 "static-content");
5795
5796 for (Element staticContentElement : staticContentElements) {
5797 String staticContent = staticContentElement.getText();
5798
5799 staticContent = SanitizerUtil.sanitize(
5800 user.getCompanyId(), groupId, user.getUserId(),
5801 JournalArticle.class.getName(), 0,
5802 ContentTypes.TEXT_HTML, staticContent);
5803
5804 staticContentElement.clearContent();
5805
5806 staticContentElement.addCDATA(staticContent);
5807 }
5808 }
5809
5810 content = DDMXMLUtil.formatXML(document);
5811 }
5812 catch (DocumentException de) {
5813 _log.error(de, de);
5814 }
5815
5816 content = HtmlUtil.replaceMsWordCharacters(content);
5817
5818 return content;
5819 }
5820
5821 protected void formatImage(
5822 long groupId, String articleId, double version,
5823 boolean incrementVersion, Element el, String elInstanceId,
5824 String elName, Map<String, byte[]> images)
5825 throws PortalException, SystemException {
5826
5827 List<Element> imageContents = el.elements("dynamic-content");
5828
5829 for (Element dynamicContent : imageContents) {
5830 String elLanguage = dynamicContent.attributeValue(
5831 "language-id", StringPool.BLANK);
5832
5833 if (!elLanguage.equals(StringPool.BLANK)) {
5834 elLanguage = "_" + elLanguage;
5835 }
5836
5837 long imageId = journalArticleImageLocalService.getArticleImageId(
5838 groupId, articleId, version, elInstanceId, elName, elLanguage);
5839
5840 if (dynamicContent.getText().equals("delete") ||
5841 Validator.isNull(dynamicContent.getText())) {
5842
5843 dynamicContent.setText(StringPool.BLANK);
5844
5845 imageLocalService.deleteImage(imageId);
5846
5847 String defaultElLanguage = "";
5848
5849 if (Validator.isNull(elLanguage)) {
5850 defaultElLanguage =
5851 "_" +
5852 LocaleUtil.toLanguageId(
5853 LocaleUtil.getSiteDefault());
5854 }
5855
5856 long defaultImageId =
5857 journalArticleImageLocalService.getArticleImageId(
5858 groupId, articleId, version, elInstanceId, elName,
5859 defaultElLanguage);
5860
5861 imageLocalService.deleteImage(defaultImageId);
5862
5863 continue;
5864 }
5865
5866 String elContent =
5867 "/image/journal/article?img_id=" + imageId + "&t=" +
5868 WebServerServletTokenUtil.getToken(imageId);
5869
5870 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
5871
5872 if (ArrayUtil.isNotEmpty(bytes)) {
5873 dynamicContent.setText(elContent);
5874 dynamicContent.addAttribute("id", String.valueOf(imageId));
5875
5876 imageLocalService.updateImage(imageId, bytes);
5877
5878 continue;
5879 }
5880
5881 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
5882 incrementVersion) {
5883
5884 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
5885
5886 long oldImageId = 0;
5887
5888 if ((oldVersion >= 1) && incrementVersion) {
5889 oldImageId =
5890 journalArticleImageLocalService.getArticleImageId(
5891 groupId, articleId, oldVersion, elInstanceId,
5892 elName, elLanguage);
5893 }
5894
5895 Image oldImage = null;
5896
5897 if (oldImageId > 0) {
5898 oldImage = imageLocalService.getImage(oldImageId);
5899 }
5900
5901 if (oldImage != null) {
5902 dynamicContent.setText(elContent);
5903 dynamicContent.addAttribute("id", String.valueOf(imageId));
5904
5905 bytes = oldImage.getTextObj();
5906
5907 imageLocalService.updateImage(imageId, bytes);
5908 }
5909 else if (dynamicContent.getText().equals("update")) {
5910 dynamicContent.setText(StringPool.BLANK);
5911 }
5912
5913 continue;
5914 }
5915
5916 Image image = imageLocalService.getImage(imageId);
5917
5918 if (image != null) {
5919 dynamicContent.setText(elContent);
5920 dynamicContent.addAttribute("id", String.valueOf(imageId));
5921
5922 continue;
5923 }
5924 else if (dynamicContent.getText().equals("update")) {
5925 dynamicContent.setText(StringPool.BLANK);
5926
5927 continue;
5928 }
5929
5930 long contentImageId = GetterUtil.getLong(
5931 HttpUtil.getParameter(dynamicContent.getText(), "img_id"));
5932
5933 if (contentImageId <= 0) {
5934 contentImageId = GetterUtil.getLong(
5935 HttpUtil.getParameter(
5936 dynamicContent.getText(), "img_id", false));
5937 }
5938
5939 if (contentImageId > 0) {
5940 image = imageLocalService.getImage(contentImageId);
5941
5942 if (image != null) {
5943 dynamicContent.addAttribute(
5944 "id", String.valueOf(contentImageId));
5945
5946 continue;
5947 }
5948 }
5949
5950 String defaultElLanguage = "";
5951
5952 if (Validator.isNull(elLanguage)) {
5953 defaultElLanguage =
5954 "_" + LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
5955 }
5956
5957 long defaultImageId =
5958 journalArticleImageLocalService.getArticleImageId(
5959 groupId, articleId, version, elInstanceId, elName,
5960 defaultElLanguage);
5961
5962 Image defaultImage = imageLocalService.getImage(defaultImageId);
5963
5964 if (defaultImage != null) {
5965 dynamicContent.setText(elContent);
5966 dynamicContent.addAttribute(
5967 "id", String.valueOf(defaultImageId));
5968
5969 bytes = defaultImage.getTextObj();
5970
5971 imageLocalService.updateImage(defaultImageId, bytes);
5972
5973 continue;
5974 }
5975
5976 if (Validator.isNotNull(elLanguage)) {
5977 dynamicContent.setText(StringPool.BLANK);
5978 }
5979 }
5980 }
5981
5982 protected List<ObjectValuePair<Long, Integer>> getArticleVersionStatuses(
5983 List<JournalArticle> articles) {
5984
5985 List<ObjectValuePair<Long, Integer>> dlArticleVersionStatusOVPs =
5986 new ArrayList<ObjectValuePair<Long, Integer>>(articles.size());
5987
5988 for (JournalArticle article : articles) {
5989 int status = article.getStatus();
5990
5991 if (status == WorkflowConstants.STATUS_PENDING) {
5992 status = WorkflowConstants.STATUS_DRAFT;
5993 }
5994
5995 ObjectValuePair<Long, Integer> dlFileVersionStatusOVP =
5996 new ObjectValuePair<Long, Integer>(article.getId(), status);
5997
5998 dlArticleVersionStatusOVPs.add(dlFileVersionStatusOVP);
5999 }
6000
6001 return dlArticleVersionStatusOVPs;
6002 }
6003
6004 protected long getClassTypeId(JournalArticle article) {
6005 long classTypeId = 0;
6006
6007 try {
6008 long classNameId = PortalUtil.getClassNameId(JournalArticle.class);
6009
6010 DDMStructure ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6011 article.getGroupId(), classNameId, article.getStructureId());
6012
6013 if (ddmStructure == null) {
6014 Group companyGroup = groupLocalService.getCompanyGroup(
6015 article.getCompanyId());
6016
6017 ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6018 companyGroup.getGroupId(), classNameId,
6019 article.getStructureId());
6020 }
6021
6022 if (ddmStructure != null) {
6023 classTypeId = ddmStructure.getStructureId();
6024 }
6025 }
6026 catch (Exception e) {
6027 _log.error(e, e);
6028 }
6029
6030 return classTypeId;
6031 }
6032
6033 protected Date[] getDateInterval(
6034 long groupId, String articleId, Date earliestDisplayDate,
6035 Date latestExpirationDate)
6036 throws SystemException {
6037
6038 Date[] dateInterval = new Date[2];
6039
6040 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
6041 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6042
6043 boolean expiringArticle = true;
6044
6045 if (latestExpirationDate == null) {
6046 expiringArticle = false;
6047 }
6048
6049 for (JournalArticle article : articles) {
6050 if ((earliestDisplayDate == null) ||
6051 ((article.getDisplayDate() != null) &&
6052 earliestDisplayDate.after(article.getDisplayDate()))) {
6053
6054 earliestDisplayDate = article.getDisplayDate();
6055 }
6056
6057 if (expiringArticle &&
6058 ((latestExpirationDate == null) ||
6059 ((article.getExpirationDate() != null) &&
6060 latestExpirationDate.before(article.getExpirationDate())))) {
6061
6062 latestExpirationDate = article.getExpirationDate();
6063 }
6064
6065 if (expiringArticle && (article.getExpirationDate() == null) &&
6066 (latestExpirationDate != null)) {
6067
6068 expiringArticle = false;
6069 }
6070 }
6071
6072 dateInterval[0] = earliestDisplayDate;
6073 dateInterval[1] = latestExpirationDate;
6074
6075 return dateInterval;
6076 }
6077
6078 protected String getUniqueUrlTitle(
6079 long id, long groupId, String articleId, String title)
6080 throws PortalException, SystemException {
6081
6082 String urlTitle = JournalUtil.getUrlTitle(id, title);
6083
6084 return getUniqueUrlTitle(groupId, articleId, urlTitle);
6085 }
6086
6087 protected String getUniqueUrlTitle(
6088 long id, String articleId, String title, String oldUrlTitle,
6089 ServiceContext serviceContext)
6090 throws PortalException, SystemException {
6091
6092 String serviceContextUrlTitle = ParamUtil.getString(
6093 serviceContext, "urlTitle");
6094
6095 String urlTitle = null;
6096
6097 if (Validator.isNotNull(serviceContextUrlTitle)) {
6098 urlTitle = JournalUtil.getUrlTitle(id, serviceContextUrlTitle);
6099 }
6100 else if (Validator.isNotNull(oldUrlTitle)) {
6101 return oldUrlTitle;
6102 }
6103 else {
6104 urlTitle = getUniqueUrlTitle(
6105 id, serviceContext.getScopeGroupId(), articleId, title);
6106 }
6107
6108 JournalArticle urlTitleArticle = null;
6109
6110 try {
6111 urlTitleArticle = getArticleByUrlTitle(
6112 serviceContext.getScopeGroupId(), urlTitle);
6113 }
6114 catch (NoSuchArticleException nsae) {
6115 }
6116
6117 if ((urlTitleArticle != null) &&
6118 !Validator.equals(
6119 urlTitleArticle.getArticleId(), articleId)) {
6120
6121 urlTitle = getUniqueUrlTitle(
6122 id, serviceContext.getScopeGroupId(), articleId, urlTitle);
6123 }
6124
6125 return urlTitle;
6126 }
6127
6128 protected boolean hasModifiedLatestApprovedVersion(
6129 long groupId, String articleId, double version)
6130 throws PortalException, SystemException {
6131
6132 double latestApprovedVersion;
6133
6134 try {
6135 latestApprovedVersion = getLatestVersion(
6136 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6137
6138 if (version >= latestApprovedVersion) {
6139 return true;
6140 }
6141 else {
6142 return false;
6143 }
6144 }
6145 catch (NoSuchArticleException nsae) {
6146 return true;
6147 }
6148 }
6149
6150 protected void notifySubscribers(
6151 JournalArticle article, ServiceContext serviceContext)
6152 throws PortalException, SystemException {
6153
6154 if (!article.isApproved()) {
6155 return;
6156 }
6157
6158 String articleURL = PortalUtil.getControlPanelFullURL(
6159 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
6160
6161 if (Validator.isNull(articleURL)) {
6162 return;
6163 }
6164
6165 PortletPreferences preferences =
6166 ServiceContextUtil.getPortletPreferences(serviceContext);
6167
6168 if (preferences == null) {
6169 long ownerId = article.getGroupId();
6170 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
6171 long plid = PortletKeys.PREFS_PLID_SHARED;
6172 String portletId = PortletKeys.JOURNAL;
6173 String defaultPreferences = null;
6174
6175 preferences = portletPreferencesLocalService.getPreferences(
6176 article.getCompanyId(), ownerId, ownerType, plid, portletId,
6177 defaultPreferences);
6178 }
6179
6180 if ((article.getVersion() == 1.0) &&
6181 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
6182 }
6183 else if ((article.getVersion() != 1.0) &&
6184 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
6185 }
6186 else {
6187 return;
6188 }
6189
6190 String fromName = JournalUtil.getEmailFromName(
6191 preferences, article.getCompanyId());
6192 String fromAddress = JournalUtil.getEmailFromAddress(
6193 preferences, article.getCompanyId());
6194
6195 String subject = null;
6196 String body = null;
6197
6198 if (article.getVersion() == 1.0) {
6199 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
6200 body = JournalUtil.getEmailArticleAddedBody(preferences);
6201 }
6202 else {
6203 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
6204 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
6205 }
6206
6207 SubscriptionSender subscriptionSender = new SubscriptionSender();
6208
6209 subscriptionSender.setBody(body);
6210 subscriptionSender.setCompanyId(article.getCompanyId());
6211 subscriptionSender.setContextAttributes(
6212 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6213 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6214 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
6215 subscriptionSender.setContextUserPrefix("ARTICLE");
6216 subscriptionSender.setFrom(fromAddress, fromName);
6217 subscriptionSender.setHtmlFormat(true);
6218 subscriptionSender.setMailId("journal_article", article.getId());
6219 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6220 subscriptionSender.setReplyToAddress(fromAddress);
6221 subscriptionSender.setScopeGroupId(article.getGroupId());
6222 subscriptionSender.setServiceContext(serviceContext);
6223 subscriptionSender.setSubject(subject);
6224 subscriptionSender.setUserId(article.getUserId());
6225
6226 subscriptionSender.addPersistedSubscribers(
6227 JournalArticle.class.getName(), article.getResourcePrimKey());
6228
6229 JournalFolder folder = article.getFolder();
6230
6231 List<Long> folderIds = new ArrayList<Long>();
6232
6233 if (folder != null) {
6234 folderIds.add(folder.getFolderId());
6235
6236 folderIds.addAll(folder.getAncestorFolderIds());
6237 }
6238
6239 for (long curFolderId : folderIds) {
6240 subscriptionSender.addPersistedSubscribers(
6241 JournalFolder.class.getName(), curFolderId);
6242 }
6243
6244 subscriptionSender.addPersistedSubscribers(
6245 JournalFolder.class.getName(), article.getGroupId());
6246
6247 subscriptionSender.flushNotificationsAsync();
6248 }
6249
6250 protected void saveImages(
6251 boolean smallImage, long smallImageId, File smallImageFile,
6252 byte[] smallImageBytes)
6253 throws PortalException, SystemException {
6254
6255 if (smallImage) {
6256 if ((smallImageFile != null) && (smallImageBytes != null)) {
6257 imageLocalService.updateImage(smallImageId, smallImageBytes);
6258 }
6259 }
6260 else {
6261 imageLocalService.deleteImage(smallImageId);
6262 }
6263 }
6264
6265 protected void sendEmail(
6266 JournalArticle article, String articleURL,
6267 PortletPreferences preferences, String emailType,
6268 ServiceContext serviceContext)
6269 throws PortalException, SystemException {
6270
6271 if (preferences == null) {
6272 return;
6273 }
6274 else if (emailType.equals("denied") &&
6275 JournalUtil.getEmailArticleApprovalDeniedEnabled(
6276 preferences)) {
6277 }
6278 else if (emailType.equals("granted") &&
6279 JournalUtil.getEmailArticleApprovalGrantedEnabled(
6280 preferences)) {
6281 }
6282 else if (emailType.equals("requested") &&
6283 JournalUtil.getEmailArticleApprovalRequestedEnabled(
6284 preferences)) {
6285 }
6286 else if (emailType.equals("review") &&
6287 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
6288 }
6289 else {
6290 return;
6291 }
6292
6293 Company company = companyPersistence.findByPrimaryKey(
6294 article.getCompanyId());
6295
6296 User user = userPersistence.findByPrimaryKey(article.getUserId());
6297
6298 articleURL +=
6299 "&groupId=" + article.getGroupId() + "&articleId=" +
6300 article.getArticleId() + "&version=" + article.getVersion();
6301
6302 String fromName = JournalUtil.getEmailFromName(
6303 preferences, article.getCompanyId());
6304 String fromAddress = JournalUtil.getEmailFromAddress(
6305 preferences, article.getCompanyId());
6306
6307 String toName = user.getFullName();
6308 String toAddress = user.getEmailAddress();
6309
6310 if (emailType.equals("requested") || emailType.equals("review")) {
6311 String tempToName = fromName;
6312 String tempToAddress = fromAddress;
6313
6314 fromName = toName;
6315 fromAddress = toAddress;
6316
6317 toName = tempToName;
6318 toAddress = tempToAddress;
6319 }
6320
6321 String subject = null;
6322 String body = null;
6323
6324 if (emailType.equals("denied")) {
6325 subject = JournalUtil.getEmailArticleApprovalDeniedSubject(
6326 preferences);
6327 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
6328 }
6329 else if (emailType.equals("granted")) {
6330 subject = JournalUtil.getEmailArticleApprovalGrantedSubject(
6331 preferences);
6332 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
6333 }
6334 else if (emailType.equals("requested")) {
6335 subject = JournalUtil.getEmailArticleApprovalRequestedSubject(
6336 preferences);
6337 body = JournalUtil.getEmailArticleApprovalRequestedBody(
6338 preferences);
6339 }
6340 else if (emailType.equals("review")) {
6341 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
6342 body = JournalUtil.getEmailArticleReviewBody(preferences);
6343 }
6344
6345 SubscriptionSender subscriptionSender = new SubscriptionSender();
6346
6347 subscriptionSender.setBody(body);
6348 subscriptionSender.setCompanyId(company.getCompanyId());
6349 subscriptionSender.setContextAttributes(
6350 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6351 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6352 articleURL, "[$ARTICLE_USER_NAME$]", article.getUserName(),
6353 "[$ARTICLE_VERSION$]", article.getVersion());
6354 subscriptionSender.setContextUserPrefix("ARTICLE");
6355 subscriptionSender.setFrom(fromAddress, fromName);
6356 subscriptionSender.setHtmlFormat(true);
6357 subscriptionSender.setMailId("journal_article", article.getId());
6358 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6359 subscriptionSender.setScopeGroupId(article.getGroupId());
6360 subscriptionSender.setServiceContext(serviceContext);
6361 subscriptionSender.setSubject(subject);
6362 subscriptionSender.setUserId(article.getUserId());
6363
6364 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
6365
6366 subscriptionSender.flushNotificationsAsync();
6367 }
6368
6369 protected void updateDDMStructureXSD(
6370 long ddmStructureId, String content, ServiceContext serviceContext)
6371 throws PortalException, SystemException {
6372
6373 try {
6374 Document document = SAXReaderUtil.read(content);
6375
6376 Element rootElement = document.getRootElement();
6377
6378 List<Element> elements = rootElement.elements();
6379
6380 for (Element element : elements) {
6381 String fieldName = element.attributeValue(
6382 "name", StringPool.BLANK);
6383
6384 List<Element> dynamicContentElements = element.elements(
6385 "dynamic-content");
6386
6387 for (Element dynamicContentElement : dynamicContentElements) {
6388 String value = dynamicContentElement.getText();
6389
6390 ddmStructureLocalService.updateXSDFieldMetadata(
6391 ddmStructureId, fieldName,
6392 FieldConstants.PREDEFINED_VALUE, value, serviceContext);
6393 }
6394 }
6395 }
6396 catch (DocumentException de) {
6397 throw new SystemException(de);
6398 }
6399 }
6400
6401 protected void updatePreviousApprovedArticle(JournalArticle article)
6402 throws PortalException, SystemException {
6403
6404 List<JournalArticle> approvedArticles =
6405 journalArticlePersistence.findByG_A_ST(
6406 article.getGroupId(), article.getArticleId(),
6407 WorkflowConstants.STATUS_APPROVED, 0, 2);
6408
6409 if (approvedArticles.isEmpty() ||
6410 ((approvedArticles.size() == 1) &&
6411 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
6412
6413 assetEntryLocalService.updateVisible(
6414 JournalArticle.class.getName(), article.getResourcePrimKey(),
6415 false);
6416 }
6417 else {
6418 JournalArticle previousApprovedArticle = approvedArticles.get(0);
6419
6420 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
6421 previousApprovedArticle = approvedArticles.get(1);
6422 }
6423
6424 Date[] dateInterval = getDateInterval(
6425 previousApprovedArticle.getGroupId(),
6426 previousApprovedArticle.getArticleId(),
6427 previousApprovedArticle.getDisplayDate(),
6428 previousApprovedArticle.getExpirationDate());
6429
6430 Date displayDate = dateInterval[0];
6431 Date expirationDate = dateInterval[1];
6432
6433 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
6434 JournalArticle.class.getName(), article.getResourcePrimKey(),
6435 displayDate, expirationDate, true);
6436
6437 assetEntry.setModifiedDate(
6438 previousApprovedArticle.getModifiedDate());
6439 assetEntry.setTitle(previousApprovedArticle.getTitle());
6440
6441 assetEntryPersistence.update(assetEntry);
6442 }
6443 }
6444
6445 protected void updateUrlTitles(
6446 long groupId, String articleId, String urlTitle)
6447 throws SystemException {
6448
6449 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
6450 groupId, articleId);
6451
6452 for (JournalArticle article : articles) {
6453 if (!article.getUrlTitle().equals(urlTitle)) {
6454 article.setUrlTitle(urlTitle);
6455
6456 journalArticlePersistence.update(article);
6457 }
6458 }
6459 }
6460
6461 protected void validate(
6462 long companyId, long groupId, long classNameId,
6463 Map<Locale, String> titleMap, String content, String type,
6464 String ddmStructureKey, String ddmTemplateKey, Date expirationDate,
6465 boolean smallImage, String smallImageURL, File smallImageFile,
6466 byte[] smallImageBytes)
6467 throws PortalException, SystemException {
6468
6469 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
6470 LocalizationUtil.getDefaultLanguageId(content));
6471
6472 Locale[] availableLocales = LanguageUtil.getAvailableLocales(groupId);
6473
6474 if (!ArrayUtil.contains(availableLocales, articleDefaultLocale)) {
6475 LocaleException le = new LocaleException(
6476 LocaleException.TYPE_CONTENT,
6477 "The locale " + articleDefaultLocale +
6478 " is not available in site with groupId" + groupId);
6479
6480 Locale[] sourceAvailableLocales = {articleDefaultLocale};
6481
6482 le.setSourceAvailableLocales(sourceAvailableLocales);
6483 le.setTargetAvailableLocales(availableLocales);
6484
6485 throw le;
6486 }
6487
6488 if ((classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
6489 (titleMap.isEmpty() ||
6490 Validator.isNull(titleMap.get(articleDefaultLocale)))) {
6491
6492 throw new ArticleTitleException();
6493 }
6494 else if (Validator.isNull(type)) {
6495 throw new ArticleTypeException();
6496 }
6497
6498 validateContent(content);
6499
6500 if (Validator.isNotNull(ddmStructureKey)) {
6501 Group companyGroup = groupLocalService.getCompanyGroup(companyId);
6502
6503 DDMStructure ddmStructure = null;
6504
6505 try {
6506 ddmStructure = ddmStructurePersistence.findByG_C_S(
6507 PortalUtil.getSiteGroupId(groupId),
6508 PortalUtil.getClassNameId(JournalArticle.class),
6509 ddmStructureKey);
6510 }
6511 catch (NoSuchStructureException nsse) {
6512 ddmStructure = ddmStructurePersistence.findByG_C_S(
6513 companyGroup.getGroupId(),
6514 PortalUtil.getClassNameId(JournalArticle.class),
6515 ddmStructureKey);
6516 }
6517
6518 DDMTemplate ddmTemplate = null;
6519
6520 if (Validator.isNotNull(ddmTemplateKey)) {
6521 try {
6522 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
6523 PortalUtil.getSiteGroupId(groupId),
6524 PortalUtil.getClassNameId(DDMStructure.class),
6525 ddmTemplateKey);
6526 }
6527 catch (NoSuchTemplateException nste) {
6528 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
6529 companyGroup.getGroupId(),
6530 PortalUtil.getClassNameId(DDMStructure.class),
6531 ddmTemplateKey);
6532 }
6533
6534 if (ddmTemplate.getClassPK() != ddmStructure.getStructureId()) {
6535 throw new NoSuchTemplateException();
6536 }
6537 }
6538 else if (classNameId ==
6539 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
6540
6541 throw new NoSuchTemplateException();
6542 }
6543 }
6544
6545 if ((expirationDate != null) && expirationDate.before(new Date()) &&
6546 !ExportImportThreadLocal.isImportInProcess()) {
6547
6548 throw new ArticleExpirationDateException();
6549 }
6550
6551 String[] imageExtensions = PrefsPropsUtil.getStringArray(
6552 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
6553
6554 if (!smallImage || Validator.isNotNull(smallImageURL) ||
6555 (smallImageFile == null) || (smallImageBytes == null)) {
6556
6557 return;
6558 }
6559
6560 String smallImageName = smallImageFile.getName();
6561
6562 if (smallImageName != null) {
6563 boolean validSmallImageExtension = false;
6564
6565 for (String _imageExtension : imageExtensions) {
6566 if (StringPool.STAR.equals(_imageExtension) ||
6567 StringUtil.endsWith(smallImageName, _imageExtension)) {
6568
6569 validSmallImageExtension = true;
6570
6571 break;
6572 }
6573 }
6574
6575 if (!validSmallImageExtension) {
6576 throw new ArticleSmallImageNameException(smallImageName);
6577 }
6578 }
6579
6580 long smallImageMaxSize = PrefsPropsUtil.getLong(
6581 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
6582
6583 if ((smallImageMaxSize > 0) &&
6584 ((smallImageBytes == null) ||
6585 (smallImageBytes.length > smallImageMaxSize))) {
6586
6587 throw new ArticleSmallImageSizeException();
6588 }
6589 }
6590
6591 protected void validate(
6592 long companyId, long groupId, long classNameId, String articleId,
6593 boolean autoArticleId, double version, Map<Locale, String> titleMap,
6594 String content, String type, String ddmStructureKey,
6595 String ddmTemplateKey, Date expirationDate, boolean smallImage,
6596 String smallImageURL, File smallImageFile, byte[] smallImageBytes)
6597 throws PortalException, SystemException {
6598
6599 if (!autoArticleId) {
6600 validate(articleId);
6601 }
6602
6603 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
6604 groupId, articleId, version);
6605
6606 if (article != null) {
6607 throw new DuplicateArticleIdException();
6608 }
6609
6610 validate(
6611 companyId, groupId, classNameId, titleMap, content, type,
6612 ddmStructureKey, ddmTemplateKey, expirationDate, smallImage,
6613 smallImageURL, smallImageFile, smallImageBytes);
6614 }
6615
6616 protected void validate(String articleId) throws PortalException {
6617 if (Validator.isNull(articleId) ||
6618 (articleId.indexOf(CharPool.COMMA) != -1) ||
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 }