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 = articleId.trim().toUpperCase();
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.setArticleId(articleId);
366 article.setVersion(version);
367 article.setTitleMap(titleMap, locale);
368 article.setUrlTitle(
369 getUniqueUrlTitle(id, articleId, title, null, serviceContext));
370 article.setDescriptionMap(descriptionMap, locale);
371 article.setContent(content);
372 article.setType(type);
373 article.setStructureId(ddmStructureKey);
374 article.setTemplateId(ddmTemplateKey);
375 article.setLayoutUuid(layoutUuid);
376 article.setDisplayDate(displayDate);
377 article.setExpirationDate(expirationDate);
378 article.setReviewDate(reviewDate);
379 article.setIndexable(indexable);
380 article.setSmallImage(smallImage);
381 article.setSmallImageId(counterLocalService.increment());
382 article.setSmallImageURL(smallImageURL);
383
384 if ((expirationDate == null) || expirationDate.after(now)) {
385 article.setStatus(WorkflowConstants.STATUS_DRAFT);
386 }
387 else {
388 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
389 }
390
391 article.setStatusByUserId(userId);
392 article.setStatusDate(serviceContext.getModifiedDate(now));
393 article.setExpandoBridgeAttributes(serviceContext);
394
395 journalArticlePersistence.update(article);
396
397
398
399 if (serviceContext.isAddGroupPermissions() ||
400 serviceContext.isAddGuestPermissions()) {
401
402 addArticleResources(
403 article, serviceContext.isAddGroupPermissions(),
404 serviceContext.isAddGuestPermissions());
405 }
406 else {
407 addArticleResources(
408 article, serviceContext.getGroupPermissions(),
409 serviceContext.getGuestPermissions());
410 }
411
412
413
414 saveImages(
415 smallImage, article.getSmallImageId(), smallImageFile,
416 smallImageBytes);
417
418
419
420 updateAsset(
421 userId, article, serviceContext.getAssetCategoryIds(),
422 serviceContext.getAssetTagNames(),
423 serviceContext.getAssetLinkEntryIds());
424
425
426
427 if (PortalUtil.getClassNameId(DDMStructure.class) == classNameId) {
428 updateDDMStructureXSD(classPK, content, serviceContext);
429 }
430
431
432
433 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
434 mbMessageLocalService.addDiscussionMessage(
435 userId, article.getUserName(), groupId,
436 JournalArticle.class.getName(), resourcePrimKey,
437 WorkflowConstants.ACTION_PUBLISH);
438 }
439
440
441
442 PortletPreferences preferences =
443 ServiceContextUtil.getPortletPreferences(serviceContext);
444
445 sendEmail(
446 article, articleURL, preferences, "requested", serviceContext);
447
448
449
450 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
451 WorkflowHandlerRegistryUtil.startWorkflowInstance(
452 user.getCompanyId(), groupId, userId,
453 JournalArticle.class.getName(), article.getId(), article,
454 serviceContext);
455 }
456 else {
457 updateStatus(
458 userId, article, WorkflowConstants.STATUS_APPROVED, null,
459 new HashMap<String, Serializable>(), serviceContext);
460 }
461
462 return journalArticlePersistence.findByPrimaryKey(article.getId());
463 }
464
465
494 @Override
495 public JournalArticle addArticle(
496 long userId, long groupId, long folderId,
497 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
498 String content, String ddmStructureKey, String ddmTemplateKey,
499 ServiceContext serviceContext)
500 throws PortalException, SystemException {
501
502 Calendar calendar = CalendarFactoryUtil.getCalendar();
503
504 int displayDateMonth = calendar.get(Calendar.MONTH);
505 int displayDateDay = calendar.get(Calendar.DAY_OF_MONTH);
506 int displayDateYear = calendar.get(Calendar.YEAR);
507 int displayDateHour = calendar.get(Calendar.HOUR_OF_DAY);
508 int displayDateMinute = calendar.get(Calendar.MINUTE);
509
510 return journalArticleLocalService.addArticle(
511 userId, groupId, folderId,
512 JournalArticleConstants.CLASSNAME_ID_DEFAULT, 0, StringPool.BLANK,
513 true, 1, titleMap, descriptionMap, content, "general",
514 ddmStructureKey, ddmTemplateKey, null, displayDateMonth,
515 displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
516 0, 0, 0, 0, 0, true, 0, 0, 0, 0, 0, true, true, false, null, null,
517 null, null, serviceContext);
518 }
519
520
530 @Override
531 public void addArticleResources(
532 JournalArticle article, boolean addGroupPermissions,
533 boolean addGuestPermissions)
534 throws PortalException, SystemException {
535
536 resourceLocalService.addResources(
537 article.getCompanyId(), article.getGroupId(), article.getUserId(),
538 JournalArticle.class.getName(), article.getResourcePrimKey(), false,
539 addGroupPermissions, addGuestPermissions);
540 }
541
542
551 @Override
552 public void addArticleResources(
553 JournalArticle article, String[] groupPermissions,
554 String[] guestPermissions)
555 throws PortalException, SystemException {
556
557 resourceLocalService.addModelResources(
558 article.getCompanyId(), article.getGroupId(), article.getUserId(),
559 JournalArticle.class.getName(), article.getResourcePrimKey(),
560 groupPermissions, guestPermissions);
561 }
562
563
573 @Override
574 public void addArticleResources(
575 long groupId, String articleId, boolean addGroupPermissions,
576 boolean addGuestPermissions)
577 throws PortalException, SystemException {
578
579 JournalArticle article = getLatestArticle(groupId, articleId);
580
581 addArticleResources(article, addGroupPermissions, addGuestPermissions);
582 }
583
584
595 @Override
596 public void addArticleResources(
597 long groupId, String articleId, String[] groupPermissions,
598 String[] guestPermissions)
599 throws PortalException, SystemException {
600
601 JournalArticle article = getLatestArticle(groupId, articleId);
602
603 addArticleResources(article, groupPermissions, guestPermissions);
604 }
605
606
619 @Override
620 public JournalArticle checkArticleResourcePrimKey(
621 long groupId, String articleId, double version)
622 throws PortalException, SystemException {
623
624 JournalArticle article = journalArticlePersistence.findByG_A_V(
625 groupId, articleId, version);
626
627 if (article.getResourcePrimKey() > 0) {
628 return article;
629 }
630
631 long resourcePrimKey =
632 journalArticleResourceLocalService.getArticleResourcePrimKey(
633 groupId, articleId);
634
635 article.setResourcePrimKey(resourcePrimKey);
636
637 journalArticlePersistence.update(article);
638
639 return article;
640 }
641
642
649 @Override
650 public void checkArticles() throws PortalException, SystemException {
651 Date now = new Date();
652
653 checkArticlesByExpirationDate(now);
654
655 checkArticlesByReviewDate(now);
656
657 checkArticlesByDisplayDate(now);
658
659 _previousCheckDate = now;
660 }
661
662
674 @Override
675 public void checkNewLine(long groupId, String articleId, double version)
676 throws PortalException, SystemException {
677
678 JournalArticle article = journalArticlePersistence.findByG_A_V(
679 groupId, articleId, version);
680
681 String content = GetterUtil.getString(article.getContent());
682
683 if (content.contains("\\n")) {
684 content = StringUtil.replace(
685 content, new String[] {"\\n", "\\r"},
686 new String[] {"\n", "\r"});
687
688 article.setContent(content);
689
690 journalArticlePersistence.update(article);
691 }
692 }
693
694
707 @Override
708 public void checkStructure(long groupId, String articleId, double version)
709 throws PortalException, SystemException {
710
711 JournalArticle article = journalArticlePersistence.findByG_A_V(
712 groupId, articleId, version);
713
714 if (Validator.isNull(article.getStructureId())) {
715 return;
716 }
717
718 checkStructure(article);
719 }
720
721
737 @Indexable(type = IndexableType.REINDEX)
738 @Override
739 public JournalArticle copyArticle(
740 long userId, long groupId, String oldArticleId, String newArticleId,
741 boolean autoArticleId, double version)
742 throws PortalException, SystemException {
743
744
745
746 User user = userPersistence.findByPrimaryKey(userId);
747 oldArticleId = oldArticleId.trim().toUpperCase();
748 newArticleId = newArticleId.trim().toUpperCase();
749 Date now = new Date();
750
751 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
752 groupId, oldArticleId, version);
753
754 if (autoArticleId) {
755 newArticleId = String.valueOf(counterLocalService.increment());
756 }
757 else {
758 validate(newArticleId);
759
760 if (journalArticlePersistence.countByG_A(
761 groupId, newArticleId) > 0) {
762
763 throw new DuplicateArticleIdException();
764 }
765 }
766
767 long id = counterLocalService.increment();
768
769 long resourcePrimKey =
770 journalArticleResourceLocalService.getArticleResourcePrimKey(
771 groupId, newArticleId);
772
773 JournalArticle newArticle = journalArticlePersistence.create(id);
774
775 newArticle.setResourcePrimKey(resourcePrimKey);
776 newArticle.setGroupId(groupId);
777 newArticle.setCompanyId(user.getCompanyId());
778 newArticle.setUserId(user.getUserId());
779 newArticle.setUserName(user.getFullName());
780 newArticle.setCreateDate(now);
781 newArticle.setModifiedDate(now);
782 newArticle.setFolderId(oldArticle.getFolderId());
783 newArticle.setArticleId(newArticleId);
784 newArticle.setVersion(JournalArticleConstants.VERSION_DEFAULT);
785 newArticle.setTitle(oldArticle.getTitle());
786 newArticle.setUrlTitle(
787 getUniqueUrlTitle(
788 id, groupId, newArticleId, oldArticle.getTitleCurrentValue()));
789 newArticle.setDescription(oldArticle.getDescription());
790
791 try {
792 copyArticleImages(oldArticle, newArticle);
793 }
794 catch (Exception e) {
795 newArticle.setContent(oldArticle.getContent());
796 }
797
798 newArticle.setType(oldArticle.getType());
799 newArticle.setStructureId(oldArticle.getStructureId());
800 newArticle.setTemplateId(oldArticle.getTemplateId());
801 newArticle.setLayoutUuid(oldArticle.getLayoutUuid());
802 newArticle.setDisplayDate(oldArticle.getDisplayDate());
803 newArticle.setExpirationDate(oldArticle.getExpirationDate());
804 newArticle.setReviewDate(oldArticle.getReviewDate());
805 newArticle.setIndexable(oldArticle.isIndexable());
806 newArticle.setSmallImage(oldArticle.isSmallImage());
807 newArticle.setSmallImageId(counterLocalService.increment());
808 newArticle.setSmallImageURL(oldArticle.getSmallImageURL());
809
810 if (oldArticle.isPending() ||
811 workflowDefinitionLinkLocalService.hasWorkflowDefinitionLink(
812 user.getCompanyId(), groupId, JournalArticle.class.getName())) {
813
814 newArticle.setStatus(WorkflowConstants.STATUS_DRAFT);
815 }
816 else {
817 newArticle.setStatus(oldArticle.getStatus());
818 }
819
820 newArticle.setExpandoBridgeAttributes(oldArticle);
821
822 journalArticlePersistence.update(newArticle);
823
824
825
826 addArticleResources(newArticle, true, true);
827
828
829
830 if (oldArticle.getSmallImage()) {
831 Image image = imageLocalService.getImage(
832 oldArticle.getSmallImageId());
833
834 byte[] smallImageBytes = image.getTextObj();
835
836 imageLocalService.updateImage(
837 newArticle.getSmallImageId(), smallImageBytes);
838 }
839
840
841
842 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
843 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
844 String[] assetTagNames = assetTagLocalService.getTagNames(
845 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
846
847 updateAsset(userId, newArticle, assetCategoryIds, assetTagNames, null);
848
849 return newArticle;
850 }
851
852
859 @Override
860 @SystemEvent(
861 action = SystemEventConstants.ACTION_SKIP, send = false)
862 public JournalArticle deleteArticle(JournalArticle article)
863 throws PortalException, SystemException {
864
865 return journalArticleLocalService.deleteArticle(
866 article, StringPool.BLANK, null);
867 }
868
869
883 @Indexable(type = IndexableType.DELETE)
884 @Override
885 @SystemEvent(
886 action = SystemEventConstants.ACTION_SKIP, send = false)
887 public JournalArticle deleteArticle(
888 JournalArticle article, String articleURL,
889 ServiceContext serviceContext)
890 throws PortalException, SystemException {
891
892 JournalArticleResource articleResource =
893 journalArticleResourceLocalService.fetchArticleResource(
894 article.getGroupId(), article.getArticleId());
895
896 if (article.isApproved() &&
897 isLatestVersion(
898 article.getGroupId(), article.getArticleId(),
899 article.getVersion(), WorkflowConstants.STATUS_APPROVED)) {
900
901 updatePreviousApprovedArticle(article);
902 }
903
904
905
906 if ((serviceContext != null) && Validator.isNotNull(articleURL)) {
907 PortletPreferences preferences =
908 ServiceContextUtil.getPortletPreferences(serviceContext);
909
910 if ((preferences != null) && !article.isApproved() &&
911 isLatestVersion(
912 article.getGroupId(), article.getArticleId(),
913 article.getVersion())) {
914
915 sendEmail(
916 article, articleURL, preferences, "denied", serviceContext);
917 }
918 }
919
920
921
922 journalArticleImageLocalService.deleteImages(
923 article.getGroupId(), article.getArticleId(), article.getVersion());
924
925
926
927 expandoRowLocalService.deleteRows(article.getId());
928
929
930
931 if (!article.isDraft()) {
932 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
933 article.getCompanyId(), article.getGroupId(),
934 JournalArticle.class.getName(), article.getId());
935 }
936
937 int articlesCount = journalArticlePersistence.countByG_A(
938 article.getGroupId(), article.getArticleId());
939
940 if (articlesCount == 1) {
941
942
943
944 subscriptionLocalService.deleteSubscriptions(
945 article.getCompanyId(), JournalArticle.class.getName(),
946 article.getResourcePrimKey());
947
948
949
950 ratingsStatsLocalService.deleteStats(
951 JournalArticle.class.getName(), article.getResourcePrimKey());
952
953
954
955 mbMessageLocalService.deleteDiscussionMessages(
956 JournalArticle.class.getName(), article.getResourcePrimKey());
957
958
959
960 assetEntryLocalService.deleteEntry(
961 JournalArticle.class.getName(), article.getResourcePrimKey());
962
963
964
965 journalContentSearchLocalService.deleteArticleContentSearches(
966 article.getGroupId(), article.getArticleId());
967
968
969
970 imageLocalService.deleteImage(article.getSmallImageId());
971
972
973
974 trashEntryLocalService.deleteEntry(
975 JournalArticle.class.getName(), article.getResourcePrimKey());
976
977
978
979 resourceLocalService.deleteResource(
980 article.getCompanyId(), JournalArticle.class.getName(),
981 ResourceConstants.SCOPE_INDIVIDUAL,
982 article.getResourcePrimKey());
983
984
985
986 if (articleResource != null) {
987 journalArticleResourceLocalService.deleteJournalArticleResource(
988 articleResource);
989 }
990 }
991
992
993
994 journalArticlePersistence.remove(article);
995
996
997
998 if (articleResource != null) {
999 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1000
1001 extraDataJSONObject.put("version", article.getVersion());
1002
1003 systemEventLocalService.addSystemEvent(
1004 0, article.getGroupId(), article.getModelClassName(),
1005 article.getPrimaryKey(), articleResource.getUuid(), null,
1006 SystemEventConstants.TYPE_DELETE,
1007 extraDataJSONObject.toString());
1008 }
1009
1010 return article;
1011 }
1012
1013
1029 @Override
1030 public JournalArticle deleteArticle(
1031 long groupId, String articleId, double version, String articleURL,
1032 ServiceContext serviceContext)
1033 throws PortalException, SystemException {
1034
1035 JournalArticle article = journalArticlePersistence.findByG_A_V(
1036 groupId, articleId, version);
1037
1038 return journalArticleLocalService.deleteArticle(
1039 article, articleURL, serviceContext);
1040 }
1041
1042
1055 @Override
1056 public void deleteArticle(
1057 long groupId, String articleId, ServiceContext serviceContext)
1058 throws PortalException, SystemException {
1059
1060 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class, 0);
1061
1062 JournalArticleResource articleResource =
1063 journalArticleResourceLocalService.fetchArticleResource(
1064 groupId, articleId);
1065
1066 try {
1067 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1068 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1069 new ArticleVersionComparator(true));
1070
1071 for (JournalArticle article : articles) {
1072 journalArticleLocalService.deleteArticle(
1073 article, null, serviceContext);
1074 }
1075 }
1076 finally {
1077 SystemEventHierarchyEntryThreadLocal.pop();
1078 }
1079
1080 if (articleResource != null) {
1081 systemEventLocalService.addSystemEvent(
1082 0, groupId, JournalArticle.class.getName(),
1083 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1084 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1085 }
1086 }
1087
1088
1095 @Override
1096 public void deleteArticles(long groupId)
1097 throws PortalException, SystemException {
1098
1099 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class, 0);
1100
1101 List<JournalArticleResource> articleResources =
1102 new ArrayList<JournalArticleResource>();
1103
1104 try {
1105 JournalArticleResource articleResource = null;
1106
1107 for (JournalArticle article :
1108 journalArticlePersistence.findByGroupId(groupId)) {
1109
1110 if ((articleResource == null) ||
1111 (articleResource.getPrimaryKey() !=
1112 article.getResourcePrimKey())) {
1113
1114 articleResource =
1115 journalArticleResourceLocalService.getArticleResource(
1116 article.getResourcePrimKey());
1117
1118 articleResources.add(articleResource);
1119 }
1120
1121 journalArticleLocalService.deleteArticle(article, null, null);
1122 }
1123 }
1124 finally {
1125 SystemEventHierarchyEntryThreadLocal.pop();
1126 }
1127
1128 for (JournalArticleResource articleResource : articleResources) {
1129 systemEventLocalService.addSystemEvent(
1130 0, groupId, JournalArticle.class.getName(),
1131 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1132 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1133 }
1134 }
1135
1136
1145 @Override
1146 public void deleteArticles(long groupId, long folderId)
1147 throws PortalException, SystemException {
1148
1149 deleteArticles(groupId, folderId, true);
1150 }
1151
1152
1163 @Override
1164 public void deleteArticles(
1165 long groupId, long folderId, boolean includeTrashedEntries)
1166 throws PortalException, SystemException {
1167
1168 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class, 0);
1169
1170 List<JournalArticleResource> articleResources =
1171 new ArrayList<JournalArticleResource>();
1172
1173 try {
1174 JournalArticleResource articleResource = null;
1175
1176 for (JournalArticle article :
1177 journalArticlePersistence.findByG_F(groupId, folderId)) {
1178
1179 if ((articleResource == null) ||
1180 (articleResource.getPrimaryKey() !=
1181 article.getResourcePrimKey())) {
1182
1183 articleResource =
1184 journalArticleResourceLocalService.getArticleResource(
1185 article.getResourcePrimKey());
1186
1187 articleResources.add(articleResource);
1188 }
1189
1190 if (includeTrashedEntries || !article.isInTrash()) {
1191 journalArticleLocalService.deleteArticle(
1192 article, null, null);
1193 }
1194 else {
1195 articleResources.remove(articleResource);
1196 }
1197 }
1198 }
1199 finally {
1200 SystemEventHierarchyEntryThreadLocal.pop();
1201 }
1202
1203 for (JournalArticleResource articleResource : articleResources) {
1204 systemEventLocalService.addSystemEvent(
1205 0, groupId, JournalArticle.class.getName(),
1206 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1207 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1208 }
1209 }
1210
1211
1220 @Override
1221 public void deleteLayoutArticleReferences(long groupId, String layoutUuid)
1222 throws SystemException {
1223
1224 List<JournalArticle> articles = journalArticlePersistence.findByG_L(
1225 groupId, layoutUuid);
1226
1227 for (JournalArticle article : articles) {
1228 article.setLayoutUuid(StringPool.BLANK);
1229
1230 journalArticlePersistence.update(article);
1231 }
1232 }
1233
1234
1257 @Indexable(type = IndexableType.REINDEX)
1258 @Override
1259 public JournalArticle expireArticle(
1260 long userId, long groupId, String articleId, double version,
1261 String articleURL, ServiceContext serviceContext)
1262 throws PortalException, SystemException {
1263
1264 return updateStatus(
1265 userId, groupId, articleId, version,
1266 WorkflowConstants.STATUS_EXPIRED, articleURL,
1267 new HashMap<String, Serializable>(), serviceContext);
1268 }
1269
1270
1293 @Override
1294 public void expireArticle(
1295 long userId, long groupId, String articleId, String articleURL,
1296 ServiceContext serviceContext)
1297 throws PortalException, SystemException {
1298
1299 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
1300 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1301 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1302 new ArticleVersionComparator(true));
1303
1304 for (JournalArticle article : articles) {
1305 journalArticleLocalService.expireArticle(
1306 userId, groupId, article.getArticleId(),
1307 article.getVersion(), articleURL, serviceContext);
1308 }
1309 }
1310 else {
1311 JournalArticle article = getLatestArticle(
1312 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1313
1314 journalArticleLocalService.expireArticle(
1315 userId, groupId, article.getArticleId(), article.getVersion(),
1316 articleURL, serviceContext);
1317 }
1318 }
1319
1320 @Override
1321 public JournalArticle fetchArticle(
1322 long groupId, String articleId, double version)
1323 throws SystemException {
1324
1325 return journalArticlePersistence.fetchByG_A_V(
1326 groupId, articleId, version);
1327 }
1328
1329 @Override
1330 public JournalArticle fetchLatestArticle(
1331 long resourcePrimKey, int status, boolean preferApproved)
1332 throws SystemException {
1333
1334 JournalArticle article = null;
1335
1336 OrderByComparator orderByComparator = new ArticleVersionComparator();
1337
1338 if (status == WorkflowConstants.STATUS_ANY) {
1339 if (preferApproved) {
1340 article = journalArticlePersistence.fetchByR_ST_First(
1341 resourcePrimKey, WorkflowConstants.STATUS_APPROVED,
1342 orderByComparator);
1343 }
1344
1345 if (article == null) {
1346 article =
1347 journalArticlePersistence.fetchByResourcePrimKey_First(
1348 resourcePrimKey, orderByComparator);
1349 }
1350 }
1351 else {
1352 article = journalArticlePersistence.fetchByR_ST_First(
1353 resourcePrimKey, status, orderByComparator);
1354 }
1355
1356 return article;
1357 }
1358
1359 @Override
1360 public JournalArticle fetchLatestArticle(
1361 long groupId, String articleId, int status)
1362 throws SystemException {
1363
1364 OrderByComparator orderByComparator = new ArticleVersionComparator();
1365
1366 if (status == WorkflowConstants.STATUS_ANY) {
1367 return journalArticlePersistence.fetchByG_A_First(
1368 groupId, articleId, orderByComparator);
1369 }
1370
1371 return journalArticlePersistence.fetchByG_A_ST_First(
1372 groupId, articleId, status, orderByComparator);
1373 }
1374
1375 @Override
1376 public JournalArticle fetchLatestIndexableArticle(long resourcePrimKey)
1377 throws SystemException {
1378
1379 OrderByComparator orderByComparator = new ArticleVersionComparator();
1380
1381 int[] statuses = new int[] {
1382 WorkflowConstants.STATUS_APPROVED, WorkflowConstants.STATUS_IN_TRASH
1383 };
1384
1385 List<JournalArticle> articles =
1386 journalArticlePersistence.findByR_I_S(
1387 resourcePrimKey, true, statuses, 0, 1, orderByComparator);
1388
1389 if (articles.isEmpty()) {
1390 return null;
1391 }
1392
1393 return articles.get(0);
1394 }
1395
1396
1405 @Override
1406 public JournalArticle getArticle(long id)
1407 throws PortalException, SystemException {
1408
1409 return journalArticlePersistence.findByPrimaryKey(id);
1410 }
1411
1412
1424 @Override
1425 public JournalArticle getArticle(long groupId, String articleId)
1426 throws PortalException, SystemException {
1427
1428
1429
1430
1431 try {
1432 return getLatestArticle(
1433 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1434 }
1435 catch (NoSuchArticleException nsae) {
1436 return getLatestArticle(
1437 groupId, articleId, WorkflowConstants.STATUS_ANY);
1438 }
1439 }
1440
1441
1453 @Override
1454 public JournalArticle getArticle(
1455 long groupId, String articleId, double version)
1456 throws PortalException, SystemException {
1457
1458 return journalArticlePersistence.findByG_A_V(
1459 groupId, articleId, version);
1460 }
1461
1462
1480 @Override
1481 public JournalArticle getArticle(
1482 long groupId, String className, long classPK)
1483 throws PortalException, SystemException {
1484
1485 long classNameId = PortalUtil.getClassNameId(className);
1486
1487 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1488 groupId, classNameId, classPK);
1489
1490 if (articles.isEmpty()) {
1491 throw new NoSuchArticleException(
1492 "No approved JournalArticle exists with the key {groupId=" +
1493 groupId + ", className=" + className + ", classPK=" +
1494 classPK + "}");
1495 }
1496
1497 return articles.get(0);
1498 }
1499
1500
1511 @Override
1512 public JournalArticle getArticleByUrlTitle(long groupId, String urlTitle)
1513 throws PortalException, SystemException {
1514
1515
1516
1517
1518 try {
1519 return getLatestArticleByUrlTitle(
1520 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
1521 }
1522 catch (NoSuchArticleException nsae) {
1523 return getLatestArticleByUrlTitle(
1524 groupId, urlTitle, WorkflowConstants.STATUS_PENDING);
1525 }
1526 }
1527
1528
1545 @Override
1546 public String getArticleContent(
1547 JournalArticle article, String ddmTemplateKey, String viewMode,
1548 String languageId, ThemeDisplay themeDisplay)
1549 throws PortalException, SystemException {
1550
1551 JournalArticleDisplay articleDisplay = getArticleDisplay(
1552 article, ddmTemplateKey, viewMode, languageId, 1, null,
1553 themeDisplay);
1554
1555 if (articleDisplay == null) {
1556 return StringPool.BLANK;
1557 }
1558 else {
1559 return articleDisplay.getContent();
1560 }
1561 }
1562
1563
1582 @Override
1583 public String getArticleContent(
1584 long groupId, String articleId, double version, String viewMode,
1585 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1586 throws PortalException, SystemException {
1587
1588 JournalArticleDisplay articleDisplay = getArticleDisplay(
1589 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
1590 themeDisplay);
1591
1592 if (articleDisplay == null) {
1593 return StringPool.BLANK;
1594 }
1595 else {
1596 return articleDisplay.getContent();
1597 }
1598 }
1599
1600
1614 @Override
1615 public String getArticleContent(
1616 long groupId, String articleId, double version, String viewMode,
1617 String languageId, ThemeDisplay themeDisplay)
1618 throws PortalException, SystemException {
1619
1620 return getArticleContent(
1621 groupId, articleId, version, viewMode, null, languageId,
1622 themeDisplay);
1623 }
1624
1625
1643 @Override
1644 public String getArticleContent(
1645 long groupId, String articleId, String viewMode,
1646 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1647 throws PortalException, SystemException {
1648
1649 JournalArticleDisplay articleDisplay = getArticleDisplay(
1650 groupId, articleId, ddmTemplateKey, viewMode, languageId,
1651 themeDisplay);
1652
1653 return articleDisplay.getContent();
1654 }
1655
1656
1669 @Override
1670 public String getArticleContent(
1671 long groupId, String articleId, String viewMode, String languageId,
1672 ThemeDisplay themeDisplay)
1673 throws PortalException, SystemException {
1674
1675 return getArticleContent(
1676 groupId, articleId, viewMode, null, languageId, themeDisplay);
1677 }
1678
1679
1703 @Override
1704 public JournalArticleDisplay getArticleDisplay(
1705 JournalArticle article, String ddmTemplateKey, String viewMode,
1706 String languageId, int page, String xmlRequest,
1707 ThemeDisplay themeDisplay)
1708 throws PortalException, SystemException {
1709
1710 String content = null;
1711
1712 if (page < 1) {
1713 page = 1;
1714 }
1715
1716 int numberOfPages = 1;
1717 boolean paginate = false;
1718 boolean pageFlow = false;
1719
1720 boolean cacheable = true;
1721
1722 if (Validator.isNull(xmlRequest)) {
1723 xmlRequest = "<request />";
1724 }
1725
1726 Map<String, String> tokens = JournalUtil.getTokens(
1727 article.getGroupId(), themeDisplay, xmlRequest);
1728
1729 if ((themeDisplay == null) && xmlRequest.equals("<request />")) {
1730 tokens.put("company_id", String.valueOf(article.getCompanyId()));
1731
1732 Group companyGroup = groupLocalService.getCompanyGroup(
1733 article.getCompanyId());
1734
1735 tokens.put(
1736 "article_group_id", String.valueOf(article.getGroupId()));
1737 tokens.put(
1738 "company_group_id", String.valueOf(companyGroup.getGroupId()));
1739
1740
1741
1742 tokens.put("group_id", String.valueOf(article.getGroupId()));
1743 }
1744
1745 tokens.put(
1746 "article_resource_pk",
1747 String.valueOf(article.getResourcePrimKey()));
1748
1749 String defaultDDMTemplateKey = article.getTemplateId();
1750
1751 if (article.isTemplateDriven()) {
1752 if (Validator.isNull(ddmTemplateKey)) {
1753 ddmTemplateKey = defaultDDMTemplateKey;
1754 }
1755
1756 tokens.put("structure_id", article.getStructureId());
1757 tokens.put("template_id", ddmTemplateKey);
1758 }
1759
1760 String xml = article.getContent();
1761
1762 try {
1763 Document document = null;
1764
1765 Element rootElement = null;
1766
1767 if (article.isTemplateDriven()) {
1768 document = SAXReaderUtil.read(xml);
1769
1770 rootElement = document.getRootElement();
1771
1772 Document requestDocument = SAXReaderUtil.read(xmlRequest);
1773
1774 List<Element> pages = rootElement.elements("page");
1775
1776 if (!pages.isEmpty()) {
1777 pageFlow = true;
1778
1779 String targetPage = requestDocument.valueOf(
1780 "/request/parameters/parameter[name='targetPage']/" +
1781 "value");
1782
1783 Element pageElement = null;
1784
1785 if (Validator.isNotNull(targetPage)) {
1786 targetPage = HtmlUtil.escapeXPathAttribute(targetPage);
1787
1788 XPath xPathSelector = SAXReaderUtil.createXPath(
1789 "/root/page[@id = " + targetPage + "]");
1790
1791 pageElement = (Element)xPathSelector.selectSingleNode(
1792 document);
1793 }
1794
1795 if (pageElement != null) {
1796 document = SAXReaderUtil.createDocument(pageElement);
1797
1798 rootElement = document.getRootElement();
1799
1800 numberOfPages = pages.size();
1801 }
1802 else {
1803 if (page > pages.size()) {
1804 page = 1;
1805 }
1806
1807 pageElement = pages.get(page - 1);
1808
1809 document = SAXReaderUtil.createDocument(pageElement);
1810
1811 rootElement = document.getRootElement();
1812
1813 numberOfPages = pages.size();
1814 paginate = true;
1815 }
1816 }
1817
1818 rootElement.add(requestDocument.getRootElement().createCopy());
1819
1820 JournalUtil.addAllReservedEls(
1821 rootElement, tokens, article, languageId, themeDisplay);
1822
1823 xml = DDMXMLUtil.formatXML(document);
1824 }
1825 }
1826 catch (DocumentException de) {
1827 throw new SystemException(de);
1828 }
1829
1830 try {
1831 if (_log.isDebugEnabled()) {
1832 _log.debug(
1833 "Transforming " + article.getArticleId() + " " +
1834 article.getVersion() + " " + languageId);
1835 }
1836
1837 String script = null;
1838 String langType = null;
1839
1840 if (article.isTemplateDriven()) {
1841
1842
1843
1844
1845
1846
1847
1848 DDMTemplate ddmTemplate = null;
1849
1850 try {
1851 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1852 article.getGroupId(),
1853 PortalUtil.getClassNameId(DDMStructure.class),
1854 ddmTemplateKey);
1855 }
1856 catch (NoSuchTemplateException nste1) {
1857 try {
1858 Group companyGroup = groupLocalService.getCompanyGroup(
1859 article.getCompanyId());
1860
1861 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1862 companyGroup.getGroupId(),
1863 PortalUtil.getClassNameId(DDMStructure.class),
1864 ddmTemplateKey);
1865
1866 tokens.put(
1867 "company_group_id",
1868 String.valueOf(companyGroup.getGroupId()));
1869 }
1870 catch (NoSuchTemplateException nste2) {
1871 if (!defaultDDMTemplateKey.equals(ddmTemplateKey)) {
1872 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1873 article.getGroupId(),
1874 PortalUtil.getClassNameId(DDMStructure.class),
1875 defaultDDMTemplateKey);
1876 }
1877 else {
1878 throw nste1;
1879 }
1880 }
1881 }
1882
1883 script = ddmTemplate.getScript();
1884 langType = ddmTemplate.getLanguage();
1885 cacheable = ddmTemplate.isCacheable();
1886 }
1887
1888 content = JournalUtil.transform(
1889 themeDisplay, tokens, viewMode, languageId, xml, script,
1890 langType);
1891
1892 if (!pageFlow) {
1893 String[] pieces = StringUtil.split(
1894 content, PropsValues.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
1895
1896 if (pieces.length > 1) {
1897 if (page > pieces.length) {
1898 page = 1;
1899 }
1900
1901 content = pieces[page - 1];
1902 numberOfPages = pieces.length;
1903 paginate = true;
1904 }
1905 }
1906 }
1907 catch (Exception e) {
1908 throw new SystemException(e);
1909 }
1910
1911 return new JournalArticleDisplayImpl(
1912 article.getCompanyId(), article.getId(),
1913 article.getResourcePrimKey(), article.getGroupId(),
1914 article.getUserId(), article.getArticleId(), article.getVersion(),
1915 article.getTitle(languageId), article.getUrlTitle(),
1916 article.getDescription(languageId),
1917 article.getAvailableLanguageIds(), content, article.getType(),
1918 article.getStructureId(), ddmTemplateKey, article.isSmallImage(),
1919 article.getSmallImageId(), article.getSmallImageURL(),
1920 numberOfPages, page, paginate, cacheable);
1921 }
1922
1923
1950 @Override
1951 public JournalArticleDisplay getArticleDisplay(
1952 long groupId, String articleId, double version,
1953 String ddmTemplateKey, String viewMode, String languageId, int page,
1954 String xmlRequest, ThemeDisplay themeDisplay)
1955 throws PortalException, SystemException {
1956
1957 Date now = new Date();
1958
1959 JournalArticle article = journalArticlePersistence.findByG_A_V(
1960 groupId, articleId, version);
1961
1962 if (article.isExpired()) {
1963 Date expirationDate = article.getExpirationDate();
1964
1965 if ((expirationDate != null) && expirationDate.before(now)) {
1966 return null;
1967 }
1968 }
1969
1970 Date displayDate = article.getDisplayDate();
1971
1972 if (displayDate.after(now)) {
1973 return null;
1974 }
1975
1976 return getArticleDisplay(
1977 article, ddmTemplateKey, viewMode, languageId, page, xmlRequest,
1978 themeDisplay);
1979 }
1980
1981
2005 @Override
2006 public JournalArticleDisplay getArticleDisplay(
2007 long groupId, String articleId, double version,
2008 String ddmTemplateKey, String viewMode, String languageId,
2009 ThemeDisplay themeDisplay)
2010 throws PortalException, SystemException {
2011
2012 return getArticleDisplay(
2013 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
2014 1, null, themeDisplay);
2015 }
2016
2017
2039 @Override
2040 public JournalArticleDisplay getArticleDisplay(
2041 long groupId, String articleId, String viewMode, String languageId,
2042 int page, String xmlRequest, ThemeDisplay themeDisplay)
2043 throws PortalException, SystemException {
2044
2045 return getArticleDisplay(
2046 groupId, articleId, null, viewMode, languageId, page, xmlRequest,
2047 themeDisplay);
2048 }
2049
2050
2077 @Override
2078 public JournalArticleDisplay getArticleDisplay(
2079 long groupId, String articleId, String ddmTemplateKey,
2080 String viewMode, String languageId, int page, String xmlRequest,
2081 ThemeDisplay themeDisplay)
2082 throws PortalException, SystemException {
2083
2084 JournalArticle article = getDisplayArticle(groupId, articleId);
2085
2086 return getArticleDisplay(
2087 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2088 languageId, page, xmlRequest, themeDisplay);
2089 }
2090
2091
2114 @Override
2115 public JournalArticleDisplay getArticleDisplay(
2116 long groupId, String articleId, String ddmTemplateKey,
2117 String viewMode, String languageId, ThemeDisplay themeDisplay)
2118 throws PortalException, SystemException {
2119
2120 JournalArticle article = getDisplayArticle(groupId, articleId);
2121
2122 return getArticleDisplay(
2123 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2124 languageId, themeDisplay);
2125 }
2126
2127
2145 @Override
2146 public JournalArticleDisplay getArticleDisplay(
2147 long groupId, String articleId, String viewMode, String languageId,
2148 ThemeDisplay themeDisplay)
2149 throws PortalException, SystemException {
2150
2151 return getArticleDisplay(
2152 groupId, articleId, null, viewMode, languageId, themeDisplay);
2153 }
2154
2155
2161 @Override
2162 public List<JournalArticle> getArticles() throws SystemException {
2163 return journalArticlePersistence.findAll();
2164 }
2165
2166
2173 @Override
2174 public List<JournalArticle> getArticles(long groupId)
2175 throws SystemException {
2176
2177 return journalArticlePersistence.findByGroupId(groupId);
2178 }
2179
2180
2200 @Override
2201 public List<JournalArticle> getArticles(long groupId, int start, int end)
2202 throws SystemException {
2203
2204 return journalArticlePersistence.findByGroupId(groupId, start, end);
2205 }
2206
2207
2230 @Override
2231 public List<JournalArticle> getArticles(
2232 long groupId, int start, int end, OrderByComparator obc)
2233 throws SystemException {
2234
2235 return journalArticlePersistence.findByGroupId(
2236 groupId, start, end, obc);
2237 }
2238
2239
2247 @Override
2248 public List<JournalArticle> getArticles(long groupId, long folderId)
2249 throws SystemException {
2250
2251 return journalArticlePersistence.findByG_F(groupId, folderId);
2252 }
2253
2254
2276 @Override
2277 public List<JournalArticle> getArticles(
2278 long groupId, long folderId, int start, int end)
2279 throws SystemException {
2280
2281 return journalArticlePersistence.findByG_F(
2282 groupId, folderId, start, end);
2283 }
2284
2285
2310 @Override
2311 public List<JournalArticle> getArticles(
2312 long groupId, long folderId, int start, int end,
2313 OrderByComparator orderByComparator)
2314 throws SystemException {
2315
2316 return journalArticlePersistence.findByG_F(
2317 groupId, folderId, start, end, orderByComparator);
2318 }
2319
2320
2328 @Override
2329 public List<JournalArticle> getArticles(long groupId, String articleId)
2330 throws SystemException {
2331
2332 return journalArticlePersistence.findByG_A(groupId, articleId);
2333 }
2334
2335 @Override
2336 public List<JournalArticle> getArticlesByResourcePrimKey(
2337 long resourcePrimKey)
2338 throws SystemException {
2339
2340 return journalArticlePersistence.findByResourcePrimKey(resourcePrimKey);
2341 }
2342
2343
2351 @Override
2352 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId)
2353 throws SystemException {
2354
2355 return journalArticlePersistence.findBySmallImageId(smallImageId);
2356 }
2357
2358
2365 @Override
2366 public int getArticlesCount(long groupId) throws SystemException {
2367 return journalArticlePersistence.countByGroupId(groupId);
2368 }
2369
2370
2378 @Override
2379 public int getArticlesCount(long groupId, long folderId)
2380 throws SystemException {
2381
2382 return journalArticlePersistence.countByG_F(groupId, folderId);
2383 }
2384
2385
2410 @Override
2411 public List<JournalArticle> getCompanyArticles(
2412 long companyId, double version, int status, int start, int end)
2413 throws SystemException {
2414
2415 if (status == WorkflowConstants.STATUS_ANY) {
2416 return journalArticlePersistence.findByC_V(
2417 companyId, version, start, end, new ArticleIDComparator(true));
2418 }
2419 else {
2420 return journalArticlePersistence.findByC_V_ST(
2421 companyId, version, status, start, end,
2422 new ArticleIDComparator(true));
2423 }
2424 }
2425
2426
2450 @Override
2451 public List<JournalArticle> getCompanyArticles(
2452 long companyId, int status, int start, int end)
2453 throws SystemException {
2454
2455 if (status == WorkflowConstants.STATUS_ANY) {
2456 return journalArticlePersistence.findByCompanyId(
2457 companyId, start, end, new ArticleIDComparator(true));
2458 }
2459 else {
2460 return journalArticlePersistence.findByC_ST(
2461 companyId, status, start, end, new ArticleIDComparator(true));
2462 }
2463 }
2464
2465
2490 @Override
2491 public int getCompanyArticlesCount(
2492 long companyId, double version, int status, int start, int end)
2493 throws SystemException {
2494
2495 if (status == WorkflowConstants.STATUS_ANY) {
2496 return journalArticlePersistence.countByC_V(companyId, version);
2497 }
2498 else {
2499 return journalArticlePersistence.countByC_V_ST(
2500 companyId, version, status);
2501 }
2502 }
2503
2504
2515 @Override
2516 public int getCompanyArticlesCount(long companyId, int status)
2517 throws SystemException {
2518
2519 if (status == WorkflowConstants.STATUS_ANY) {
2520 return journalArticlePersistence.countByCompanyId(companyId);
2521 }
2522 else {
2523 return journalArticlePersistence.countByC_ST(companyId, status);
2524 }
2525 }
2526
2527
2540 @Override
2541 public JournalArticle getDisplayArticle(long groupId, String articleId)
2542 throws PortalException, SystemException {
2543
2544 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
2545 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
2546
2547 if (articles.isEmpty()) {
2548 throw new NoSuchArticleException(
2549 "No approved JournalArticle exists with the key {groupId=" +
2550 groupId + ", " + "articleId=" + articleId + "}");
2551 }
2552
2553 Date now = new Date();
2554
2555 for (int i = 0; i < articles.size(); i++) {
2556 JournalArticle article = articles.get(i);
2557
2558 Date displayDate = article.getDisplayDate();
2559 Date expirationDate = article.getExpirationDate();
2560
2561 if (((displayDate == null) || displayDate.before(now)) &&
2562 ((expirationDate == null) || expirationDate.after(now))) {
2563
2564 return article;
2565 }
2566 }
2567
2568 return articles.get(0);
2569 }
2570
2571
2584 @Override
2585 public JournalArticle getDisplayArticleByUrlTitle(
2586 long groupId, String urlTitle)
2587 throws PortalException, SystemException {
2588
2589 List<JournalArticle> articles = null;
2590
2591 OrderByComparator orderByComparator = new ArticleVersionComparator();
2592
2593 articles = journalArticlePersistence.findByG_UT_ST(
2594 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED,
2595 QueryUtil.ALL_POS, QueryUtil.ALL_POS, orderByComparator);
2596
2597 if (articles.isEmpty()) {
2598 throw new NoSuchArticleException(
2599 "No JournalArticle exists with the key {groupId=" + groupId +
2600 ", urlTitle=" + urlTitle + "}");
2601 }
2602
2603 Date now = new Date();
2604
2605 for (JournalArticle article : articles) {
2606 Date displayDate = article.getDisplayDate();
2607 Date expirationDate = article.getExpirationDate();
2608
2609 if (((displayDate != null) && displayDate.before(now)) &&
2610 ((expirationDate == null) || expirationDate.after(now)) ) {
2611
2612 return article;
2613 }
2614 }
2615
2616 return articles.get(0);
2617 }
2618
2619
2630 @Override
2631 public JournalArticle getLatestArticle(long resourcePrimKey)
2632 throws PortalException, SystemException {
2633
2634 return getLatestArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);
2635 }
2636
2637
2652 @Override
2653 public JournalArticle getLatestArticle(long resourcePrimKey, int status)
2654 throws PortalException, SystemException {
2655
2656 return getLatestArticle(resourcePrimKey, status, true);
2657 }
2658
2659
2679 @Override
2680 public JournalArticle getLatestArticle(
2681 long resourcePrimKey, int status, boolean preferApproved)
2682 throws PortalException, SystemException {
2683
2684 List<JournalArticle> articles = null;
2685
2686 OrderByComparator orderByComparator = new ArticleVersionComparator();
2687
2688 if (status == WorkflowConstants.STATUS_ANY) {
2689 if (preferApproved) {
2690 articles = journalArticlePersistence.findByR_ST(
2691 resourcePrimKey, WorkflowConstants.STATUS_APPROVED, 0, 1,
2692 orderByComparator);
2693 }
2694
2695 if ((articles == null) || (articles.size() == 0)) {
2696 articles = journalArticlePersistence.findByResourcePrimKey(
2697 resourcePrimKey, 0, 1, orderByComparator);
2698 }
2699 }
2700 else {
2701 articles = journalArticlePersistence.findByR_ST(
2702 resourcePrimKey, status, 0, 1, orderByComparator);
2703 }
2704
2705 if (articles.isEmpty()) {
2706 throw new NoSuchArticleException(
2707 "No JournalArticle exists with the key {resourcePrimKey=" +
2708 resourcePrimKey + "}");
2709 }
2710
2711 return articles.get(0);
2712 }
2713
2714
2724 @Override
2725 public JournalArticle getLatestArticle(long groupId, String articleId)
2726 throws PortalException, SystemException {
2727
2728 return getLatestArticle(
2729 groupId, articleId, WorkflowConstants.STATUS_ANY);
2730 }
2731
2732
2746 @Override
2747 public JournalArticle getLatestArticle(
2748 long groupId, String articleId, int status)
2749 throws PortalException, SystemException {
2750
2751 List<JournalArticle> articles = null;
2752
2753 OrderByComparator orderByComparator = new ArticleVersionComparator();
2754
2755 if (status == WorkflowConstants.STATUS_ANY) {
2756 articles = journalArticlePersistence.findByG_A(
2757 groupId, articleId, 0, 1, orderByComparator);
2758 }
2759 else {
2760 articles = journalArticlePersistence.findByG_A_ST(
2761 groupId, articleId, status, 0, 1, orderByComparator);
2762 }
2763
2764 if (articles.isEmpty()) {
2765 throw new NoSuchArticleException(
2766 "No JournalArticle exists with the key {groupId=" + groupId +
2767 ", articleId=" + articleId + ", status=" + status + "}");
2768 }
2769
2770 return articles.get(0);
2771 }
2772
2773
2791 @Override
2792 public JournalArticle getLatestArticle(
2793 long groupId, String className, long classPK)
2794 throws PortalException, SystemException {
2795
2796 long classNameId = PortalUtil.getClassNameId(className);
2797
2798 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
2799 groupId, classNameId, classPK, 0, 1,
2800 new ArticleVersionComparator());
2801
2802 if (articles.isEmpty()) {
2803 throw new NoSuchArticleException(
2804 "No JournalArticle exists with the key {groupId=" + groupId +
2805 ", className=" + className + ", classPK =" + classPK + "}");
2806 }
2807
2808 return articles.get(0);
2809 }
2810
2811
2825 @Override
2826 public JournalArticle getLatestArticleByUrlTitle(
2827 long groupId, String urlTitle, int status)
2828 throws PortalException, SystemException {
2829
2830 List<JournalArticle> articles = null;
2831
2832 OrderByComparator orderByComparator = new ArticleVersionComparator();
2833
2834 if (status == WorkflowConstants.STATUS_ANY) {
2835 articles = journalArticlePersistence.findByG_UT(
2836 groupId, urlTitle, 0, 1, orderByComparator);
2837 }
2838 else {
2839 articles = journalArticlePersistence.findByG_UT_ST(
2840 groupId, urlTitle, status, 0, 1, orderByComparator);
2841 }
2842
2843 if (articles.isEmpty()) {
2844 throw new NoSuchArticleException(
2845 "No JournalArticle exists with the key {groupId=" + groupId +
2846 ", urlTitle=" + urlTitle + ", status=" + status + "}");
2847 }
2848
2849 return articles.get(0);
2850 }
2851
2852
2863 @Override
2864 public double getLatestVersion(long groupId, String articleId)
2865 throws PortalException, SystemException {
2866
2867 JournalArticle article = getLatestArticle(groupId, articleId);
2868
2869 return article.getVersion();
2870 }
2871
2872
2886 @Override
2887 public double getLatestVersion(long groupId, String articleId, int status)
2888 throws PortalException, SystemException {
2889
2890 JournalArticle article = getLatestArticle(groupId, articleId, status);
2891
2892 return article.getVersion();
2893 }
2894
2895
2903 @Override
2904 public int getNotInTrashArticlesCount(long groupId, long folderId)
2905 throws SystemException {
2906
2907 QueryDefinition queryDefinition = new QueryDefinition(
2908 WorkflowConstants.STATUS_ANY);
2909
2910 List<Long> folderIds = new ArrayList<Long>();
2911
2912 folderIds.add(folderId);
2913
2914 return journalArticleFinder.countByG_F(
2915 groupId, folderIds, queryDefinition);
2916 }
2917
2918
2928 @Override
2929 public List<JournalArticle> getStructureArticles(
2930 long groupId, String ddmStructureKey)
2931 throws SystemException {
2932
2933 return journalArticlePersistence.findByG_S(groupId, ddmStructureKey);
2934 }
2935
2936
2961 @Override
2962 public List<JournalArticle> getStructureArticles(
2963 long groupId, String ddmStructureKey, int start, int end,
2964 OrderByComparator obc)
2965 throws SystemException {
2966
2967 return journalArticlePersistence.findByG_S(
2968 groupId, ddmStructureKey, start, end, obc);
2969 }
2970
2971 @Override
2972 public List<JournalArticle> getStructureArticles(String[] ddmStructureKeys)
2973 throws SystemException {
2974
2975 return journalArticlePersistence.findByStructureId(ddmStructureKeys);
2976 }
2977
2978
2988 @Override
2989 public int getStructureArticlesCount(long groupId, String ddmStructureKey)
2990 throws SystemException {
2991
2992 return journalArticlePersistence.countByG_S(groupId, ddmStructureKey);
2993 }
2994
2995
3006 @Override
3007 public List<JournalArticle> getTemplateArticles(
3008 long groupId, String ddmTemplateKey)
3009 throws SystemException {
3010
3011 return journalArticlePersistence.findByG_T(groupId, ddmTemplateKey);
3012 }
3013
3014
3041 @Override
3042 public List<JournalArticle> getTemplateArticles(
3043 long groupId, String ddmTemplateKey, int start, int end,
3044 OrderByComparator obc)
3045 throws SystemException {
3046
3047 return journalArticlePersistence.findByG_T(
3048 groupId, ddmTemplateKey, start, end, obc);
3049 }
3050
3051
3063 @Override
3064 public int getTemplateArticlesCount(long groupId, String ddmTemplateKey)
3065 throws SystemException {
3066
3067 return journalArticlePersistence.countByG_T(groupId, ddmTemplateKey);
3068 }
3069
3070 @Override
3071 public String getUniqueUrlTitle(
3072 long groupId, String articleId, String urlTitle)
3073 throws PortalException, SystemException {
3074
3075 for (int i = 1;; i++) {
3076 JournalArticle article = null;
3077
3078 try {
3079 article = getArticleByUrlTitle(groupId, urlTitle);
3080 }
3081 catch (NoSuchArticleException nsae) {
3082 }
3083
3084 if ((article == null) || articleId.equals(article.getArticleId())) {
3085 break;
3086 }
3087 else {
3088 String suffix = StringPool.DASH + i;
3089
3090 String prefix = urlTitle;
3091
3092 if (urlTitle.length() > suffix.length()) {
3093 prefix = urlTitle.substring(
3094 0, urlTitle.length() - suffix.length());
3095 }
3096
3097 urlTitle = prefix + suffix;
3098 }
3099 }
3100
3101 return urlTitle;
3102 }
3103
3104
3113 @Override
3114 public boolean hasArticle(long groupId, String articleId)
3115 throws SystemException {
3116
3117 try {
3118 getArticle(groupId, articleId);
3119
3120 return true;
3121 }
3122 catch (PortalException pe) {
3123 return false;
3124 }
3125 }
3126
3127
3140 @Override
3141 public boolean isLatestVersion(
3142 long groupId, String articleId, double version)
3143 throws PortalException, SystemException {
3144
3145 if (getLatestVersion(groupId, articleId) == version) {
3146 return true;
3147 }
3148 else {
3149 return false;
3150 }
3151 }
3152
3153
3169 @Override
3170 public boolean isLatestVersion(
3171 long groupId, String articleId, double version, int status)
3172 throws PortalException, SystemException {
3173
3174 if (getLatestVersion(groupId, articleId, status) == version) {
3175 return true;
3176 }
3177 else {
3178 return false;
3179 }
3180 }
3181
3182
3195 @Indexable(type = IndexableType.REINDEX)
3196 @Override
3197 public JournalArticle moveArticle(
3198 long groupId, String articleId, long newFolderId)
3199 throws PortalException, SystemException {
3200
3201 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3202 groupId, articleId);
3203
3204 for (JournalArticle article : articles) {
3205 article.setFolderId(newFolderId);
3206
3207 journalArticlePersistence.update(article);
3208 }
3209
3210 return getArticle(groupId, articleId);
3211 }
3212
3213
3236 @Indexable(type = IndexableType.REINDEX)
3237 @Override
3238 public JournalArticle moveArticleFromTrash(
3239 long userId, long groupId, JournalArticle article, long newFolderId,
3240 ServiceContext serviceContext)
3241 throws PortalException, SystemException {
3242
3243 if (article.isInTrash()) {
3244 restoreArticleFromTrash(userId, article);
3245 }
3246 else {
3247 updateStatus(
3248 userId, article, article.getStatus(), null,
3249 new HashMap<String, Serializable>(), serviceContext);
3250 }
3251
3252 return moveArticle(groupId, article.getArticleId(), newFolderId);
3253 }
3254
3255
3268 @Indexable(type = IndexableType.REINDEX)
3269 @Override
3270 public JournalArticle moveArticleToTrash(
3271 long userId, JournalArticle article)
3272 throws PortalException, SystemException {
3273
3274 int oldStatus = article.getStatus();
3275
3276 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3277 article.setStatus(WorkflowConstants.STATUS_DRAFT);
3278
3279 journalArticlePersistence.update(article);
3280 }
3281
3282 List<JournalArticle> articleVersions =
3283 journalArticlePersistence.findByG_A(
3284 article.getGroupId(), article.getArticleId());
3285
3286 articleVersions = ListUtil.sort(
3287 articleVersions, new ArticleVersionComparator());
3288
3289 Map<String, Serializable> workflowContext =
3290 new HashMap<String, Serializable>();
3291
3292 workflowContext.put("articleVersions", (Serializable)articleVersions);
3293
3294 article = updateStatus(
3295 userId, article.getId(), WorkflowConstants.STATUS_IN_TRASH,
3296 workflowContext, new ServiceContext());
3297
3298 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3299 JournalArticle.class.getName(), article.getResourcePrimKey());
3300
3301 String trashArticleId = TrashUtil.getTrashTitle(
3302 trashEntry.getEntryId());
3303
3304 if (!articleVersions.isEmpty()) {
3305 for (JournalArticle articleVersion : articleVersions) {
3306 articleVersion.setArticleId(trashArticleId);
3307
3308 journalArticlePersistence.update(articleVersion);
3309 }
3310 }
3311
3312 JournalArticleResource articleResource =
3313 journalArticleResourcePersistence.fetchByPrimaryKey(
3314 article.getResourcePrimKey());
3315
3316 articleResource.setArticleId(trashArticleId);
3317
3318 journalArticleResourcePersistence.update(articleResource);
3319
3320 article.setArticleId(trashArticleId);
3321
3322 article = journalArticlePersistence.update(article);
3323
3324 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3325
3326 extraDataJSONObject.put("title", article.getTitle());
3327
3328 socialActivityLocalService.addActivity(
3329 userId, article.getGroupId(), JournalArticle.class.getName(),
3330 article.getResourcePrimKey(),
3331 SocialActivityConstants.TYPE_MOVE_TO_TRASH,
3332 extraDataJSONObject.toString(), 0);
3333
3334 if (!articleVersions.isEmpty()) {
3335 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3336 JournalArticle.class);
3337
3338 for (JournalArticle articleVersion : articleVersions) {
3339 indexer.reindex(articleVersion);
3340 }
3341 }
3342
3343 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3344 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
3345 article.getCompanyId(), article.getGroupId(),
3346 JournalArticle.class.getName(), article.getId());
3347 }
3348
3349 return article;
3350 }
3351
3352
3366 @Override
3367 public JournalArticle moveArticleToTrash(
3368 long userId, long groupId, String articleId)
3369 throws PortalException, SystemException {
3370
3371 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3372 groupId, articleId, 0, 1, new ArticleVersionComparator());
3373
3374 if (!articles.isEmpty()) {
3375 return journalArticleLocalService.moveArticleToTrash(
3376 userId, articles.get(0));
3377 }
3378
3379 return null;
3380 }
3381
3382
3395 @Indexable(type = IndexableType.REINDEX)
3396 @Override
3397 public JournalArticle removeArticleLocale(
3398 long groupId, String articleId, double version, String languageId)
3399 throws PortalException, SystemException {
3400
3401 JournalArticle article = journalArticlePersistence.findByG_A_V(
3402 groupId, articleId, version);
3403
3404 String title = article.getTitle();
3405
3406 title = LocalizationUtil.removeLocalization(
3407 title, "static-content", languageId, true);
3408
3409 article.setTitle(title);
3410
3411 String description = article.getDescription();
3412
3413 description = LocalizationUtil.removeLocalization(
3414 description, "static-content", languageId, true);
3415
3416 article.setDescription(description);
3417
3418 String content = article.getContent();
3419
3420 if (article.isTemplateDriven()) {
3421 content = JournalUtil.removeArticleLocale(content, languageId);
3422 }
3423 else {
3424 content = LocalizationUtil.removeLocalization(
3425 content, "static-content", languageId, true);
3426 }
3427
3428 article.setContent(content);
3429
3430 journalArticlePersistence.update(article);
3431
3432 return article;
3433 }
3434
3435
3447 @Indexable(type = IndexableType.REINDEX)
3448 @Override
3449 public JournalArticle restoreArticleFromTrash(
3450 long userId, JournalArticle article)
3451 throws PortalException, SystemException {
3452
3453 String trashArticleId = TrashUtil.getOriginalTitle(
3454 article.getArticleId());
3455
3456 List<JournalArticle> articleVersions =
3457 journalArticlePersistence.findByG_A(
3458 article.getGroupId(), article.getArticleId());
3459
3460 if (!articleVersions.isEmpty()) {
3461 for (JournalArticle articleVersion : articleVersions) {
3462 articleVersion.setArticleId(trashArticleId);
3463
3464 journalArticlePersistence.update(articleVersion);
3465 }
3466 }
3467
3468 article.setArticleId(trashArticleId);
3469
3470 journalArticlePersistence.update(article);
3471
3472 JournalArticleResource articleResource =
3473 journalArticleResourcePersistence.fetchByPrimaryKey(
3474 article.getResourcePrimKey());
3475
3476 articleResource.setArticleId(trashArticleId);
3477
3478 journalArticleResourcePersistence.update(articleResource);
3479
3480 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3481 JournalArticle.class.getName(), article.getResourcePrimKey());
3482
3483 Map<String, Serializable> workflowContext =
3484 new HashMap<String, Serializable>();
3485
3486 List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
3487 trashEntry.getEntryId());
3488
3489 workflowContext.put("trashVersions", (Serializable)trashVersions);
3490
3491 ServiceContext serviceContext = new ServiceContext();
3492
3493 serviceContext.setScopeGroupId(article.getGroupId());
3494
3495 updateStatus(
3496 userId, article, trashEntry.getStatus(), null, workflowContext,
3497 serviceContext);
3498
3499 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3500
3501 extraDataJSONObject.put("title", article.getTitle());
3502
3503 socialActivityLocalService.addActivity(
3504 userId, article.getGroupId(), JournalArticle.class.getName(),
3505 article.getResourcePrimKey(),
3506 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
3507 extraDataJSONObject.toString(), 0);
3508
3509 if (!articleVersions.isEmpty()) {
3510 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3511 JournalArticle.class);
3512
3513 for (JournalArticle articleVersion : articleVersions) {
3514 indexer.reindex(articleVersion);
3515 }
3516 }
3517
3518 return article;
3519 }
3520
3521
3583 @Override
3584 public List<JournalArticle> search(
3585 long companyId, long groupId, List<Long> folderIds,
3586 long classNameId, String keywords, Double version, String type,
3587 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3588 Date displayDateLT, int status, Date reviewDate, int start, int end,
3589 OrderByComparator obc)
3590 throws SystemException {
3591
3592 return journalArticleFinder.findByKeywords(
3593 companyId, groupId, folderIds, classNameId, keywords, version, type,
3594 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
3595 status, reviewDate, start, end, obc);
3596 }
3597
3598
3667 @Override
3668 public List<JournalArticle> search(
3669 long companyId, long groupId, List<Long> folderIds,
3670 long classNameId, String articleId, Double version, String title,
3671 String description, String content, String type,
3672 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3673 Date displayDateLT, int status, Date reviewDate,
3674 boolean andOperator, int start, int end, OrderByComparator obc)
3675 throws SystemException {
3676
3677 QueryDefinition queryDefinition = new QueryDefinition(
3678 status, start, end, obc);
3679
3680 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3681 companyId, groupId, folderIds, classNameId, articleId, version,
3682 title, description, content, type, ddmStructureKey, ddmTemplateKey,
3683 displayDateGT, displayDateLT, reviewDate, andOperator,
3684 queryDefinition);
3685 }
3686
3687
3753 @Override
3754 public List<JournalArticle> search(
3755 long companyId, long groupId, List<Long> folderIds,
3756 long classNameId, String articleId, Double version, String title,
3757 String description, String content, String type,
3758 String[] ddmStructureKeys, String[] ddmTemplateKeys,
3759 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
3760 boolean andOperator, int start, int end, OrderByComparator obc)
3761 throws SystemException {
3762
3763 QueryDefinition queryDefinition = new QueryDefinition(
3764 status, start, end, obc);
3765
3766 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3767 companyId, groupId, folderIds, classNameId, articleId, version,
3768 title, description, content, type, ddmStructureKeys,
3769 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
3770 andOperator, queryDefinition);
3771 }
3772
3773
3820 @Override
3821 public Hits search(
3822 long companyId, long groupId, List<Long> folderIds,
3823 long classNameId, String ddmStructureKey, String ddmTemplateKey,
3824 String keywords, LinkedHashMap<String, Object> params, int start,
3825 int end, Sort sort)
3826 throws SystemException {
3827
3828 String articleId = null;
3829 String title = null;
3830 String description = null;
3831 String content = null;
3832 boolean andOperator = false;
3833
3834 if (Validator.isNotNull(keywords)) {
3835 articleId = keywords;
3836 title = keywords;
3837 description = keywords;
3838 content = keywords;
3839 }
3840 else {
3841 andOperator = true;
3842 }
3843
3844 String status = String.valueOf(WorkflowConstants.STATUS_ANY);
3845
3846 if (params != null) {
3847 params.put("keywords", keywords);
3848 }
3849
3850 return search(
3851 companyId, groupId, folderIds, classNameId, articleId, title,
3852 description, content, null, status, ddmStructureKey, ddmTemplateKey,
3853 params, andOperator, start, end, sort);
3854 }
3855
3856
3917 @Override
3918 public Hits search(
3919 long companyId, long groupId, List<Long> folderIds,
3920 long classNameId, String articleId, String title,
3921 String description, String content, String type, String status,
3922 String ddmStructureKey, String ddmTemplateKey,
3923 LinkedHashMap<String, Object> params, boolean andSearch, int start,
3924 int end, Sort sort)
3925 throws SystemException {
3926
3927 try {
3928 SearchContext searchContext = new SearchContext();
3929
3930 searchContext.setAndSearch(andSearch);
3931
3932 Map<String, Serializable> attributes =
3933 new HashMap<String, Serializable>();
3934
3935 attributes.put(Field.CLASS_NAME_ID, classNameId);
3936 attributes.put(Field.CONTENT, content);
3937 attributes.put(Field.DESCRIPTION, description);
3938 attributes.put(Field.STATUS, status);
3939 attributes.put(Field.TITLE, title);
3940 attributes.put(Field.TYPE, type);
3941 attributes.put("articleId", articleId);
3942 attributes.put("ddmStructureKey", ddmStructureKey);
3943 attributes.put("ddmTemplateKey", ddmTemplateKey);
3944 attributes.put("params", params);
3945
3946 searchContext.setAttributes(attributes);
3947
3948 searchContext.setCompanyId(companyId);
3949 searchContext.setEnd(end);
3950 searchContext.setFolderIds(folderIds);
3951 searchContext.setGroupIds(new long[] {groupId});
3952 searchContext.setIncludeDiscussions(
3953 GetterUtil.getBoolean(params.get("includeDiscussions")));
3954
3955 if (params != null) {
3956 String keywords = (String)params.remove("keywords");
3957
3958 if (Validator.isNotNull(keywords)) {
3959 searchContext.setKeywords(keywords);
3960 }
3961 }
3962
3963 QueryConfig queryConfig = new QueryConfig();
3964
3965 queryConfig.setHighlightEnabled(false);
3966 queryConfig.setScoreEnabled(false);
3967
3968 searchContext.setQueryConfig(queryConfig);
3969
3970 if (sort != null) {
3971 searchContext.setSorts(sort);
3972 }
3973
3974 searchContext.setStart(start);
3975
3976 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3977 JournalArticle.class);
3978
3979 return indexer.search(searchContext);
3980 }
3981 catch (Exception e) {
3982 throw new SystemException(e);
3983 }
3984 }
3985
3986 @Override
3987 public Hits search(
3988 long groupId, long userId, long creatorUserId, int status,
3989 int start, int end)
3990 throws PortalException, SystemException {
3991
3992 Indexer indexer = IndexerRegistryUtil.getIndexer(
3993 JournalArticle.class.getName());
3994
3995 SearchContext searchContext = new SearchContext();
3996
3997 searchContext.setAttribute(Field.STATUS, status);
3998
3999 searchContext.setAttribute("paginationType", "none");
4000
4001 if (creatorUserId > 0) {
4002 searchContext.setAttribute(
4003 Field.USER_ID, String.valueOf(creatorUserId));
4004 }
4005
4006 Group group = groupLocalService.getGroup(groupId);
4007
4008 searchContext.setCompanyId(group.getCompanyId());
4009
4010 searchContext.setEnd(end);
4011 searchContext.setGroupIds(new long[] {groupId});
4012 searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true));
4013 searchContext.setStart(start);
4014 searchContext.setUserId(userId);
4015
4016 return indexer.search(searchContext);
4017 }
4018
4019
4063 @Override
4064 public int searchCount(
4065 long companyId, long groupId, List<Long> folderIds,
4066 long classNameId, String keywords, Double version, String type,
4067 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4068 Date displayDateLT, int status, Date reviewDate)
4069 throws SystemException {
4070
4071 return journalArticleFinder.countByKeywords(
4072 companyId, groupId, folderIds, classNameId, keywords, version, type,
4073 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
4074 status, reviewDate);
4075 }
4076
4077
4127 @Override
4128 public int searchCount(
4129 long companyId, long groupId, List<Long> folderIds,
4130 long classNameId, String articleId, Double version, String title,
4131 String description, String content, String type,
4132 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4133 Date displayDateLT, int status, Date reviewDate,
4134 boolean andOperator)
4135 throws SystemException {
4136
4137 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4138 companyId, groupId, folderIds, classNameId, articleId, version,
4139 title, description, content, type, ddmStructureKey, ddmTemplateKey,
4140 displayDateGT, displayDateLT, reviewDate, andOperator,
4141 new QueryDefinition(status));
4142 }
4143
4144
4194 @Override
4195 public int searchCount(
4196 long companyId, long groupId, List<Long> folderIds,
4197 long classNameId, String articleId, Double version, String title,
4198 String description, String content, String type,
4199 String[] ddmStructureKeys, String[] ddmTemplateKeys,
4200 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4201 boolean andOperator)
4202 throws SystemException {
4203
4204 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4205 companyId, groupId, folderIds, classNameId, articleId, version,
4206 title, description, content, type, ddmStructureKeys,
4207 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
4208 andOperator, new QueryDefinition(status));
4209 }
4210
4211
4221 @Override
4222 public void subscribe(long userId, long groupId)
4223 throws PortalException, SystemException {
4224
4225 subscriptionLocalService.addSubscription(
4226 userId, groupId, JournalArticle.class.getName(), groupId);
4227 }
4228
4229
4239 @Override
4240 public void unsubscribe(long userId, long groupId)
4241 throws PortalException, SystemException {
4242
4243 subscriptionLocalService.deleteSubscription(
4244 userId, JournalArticle.class.getName(), groupId);
4245 }
4246
4247
4281 @Override
4282 public JournalArticle updateArticle(
4283 long userId, long groupId, long folderId, String articleId,
4284 double version, Map<Locale, String> titleMap,
4285 Map<Locale, String> descriptionMap, String content,
4286 String layoutUuid, ServiceContext serviceContext)
4287 throws PortalException, SystemException {
4288
4289 User user = userPersistence.findByPrimaryKey(userId);
4290
4291 JournalArticle article = journalArticlePersistence.findByG_A_V(
4292 groupId, articleId, version);
4293
4294 Date displayDate = article.getDisplayDate();
4295
4296 int displayDateMonth = 0;
4297 int displayDateDay = 0;
4298 int displayDateYear = 0;
4299 int displayDateHour = 0;
4300 int displayDateMinute = 0;
4301
4302 if (displayDate != null) {
4303 Calendar displayCal = CalendarFactoryUtil.getCalendar(
4304 user.getTimeZone());
4305
4306 displayCal.setTime(displayDate);
4307
4308 displayDateMonth = displayCal.get(Calendar.MONTH);
4309 displayDateDay = displayCal.get(Calendar.DATE);
4310 displayDateYear = displayCal.get(Calendar.YEAR);
4311 displayDateHour = displayCal.get(Calendar.HOUR);
4312 displayDateMinute = displayCal.get(Calendar.MINUTE);
4313
4314 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
4315 displayDateHour += 12;
4316 }
4317 }
4318
4319 Date expirationDate = article.getExpirationDate();
4320
4321 int expirationDateMonth = 0;
4322 int expirationDateDay = 0;
4323 int expirationDateYear = 0;
4324 int expirationDateHour = 0;
4325 int expirationDateMinute = 0;
4326 boolean neverExpire = true;
4327
4328 if (expirationDate != null) {
4329 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
4330 user.getTimeZone());
4331
4332 expirationCal.setTime(expirationDate);
4333
4334 expirationDateMonth = expirationCal.get(Calendar.MONTH);
4335 expirationDateDay = expirationCal.get(Calendar.DATE);
4336 expirationDateYear = expirationCal.get(Calendar.YEAR);
4337 expirationDateHour = expirationCal.get(Calendar.HOUR);
4338 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
4339 neverExpire = false;
4340
4341 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
4342 expirationDateHour += 12;
4343 }
4344 }
4345
4346 Date reviewDate = article.getReviewDate();
4347
4348 int reviewDateMonth = 0;
4349 int reviewDateDay = 0;
4350 int reviewDateYear = 0;
4351 int reviewDateHour = 0;
4352 int reviewDateMinute = 0;
4353 boolean neverReview = true;
4354
4355 if (reviewDate != null) {
4356 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
4357 user.getTimeZone());
4358
4359 reviewCal.setTime(reviewDate);
4360
4361 reviewDateMonth = reviewCal.get(Calendar.MONTH);
4362 reviewDateDay = reviewCal.get(Calendar.DATE);
4363 reviewDateYear = reviewCal.get(Calendar.YEAR);
4364 reviewDateHour = reviewCal.get(Calendar.HOUR);
4365 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
4366 neverReview = false;
4367
4368 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
4369 reviewDateHour += 12;
4370 }
4371 }
4372
4373 return journalArticleLocalService.updateArticle(
4374 userId, groupId, folderId, articleId, version, titleMap,
4375 descriptionMap, content, article.getType(),
4376 article.getStructureId(), article.getTemplateId(), layoutUuid,
4377 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
4378 displayDateMinute, expirationDateMonth, expirationDateDay,
4379 expirationDateYear, expirationDateHour, expirationDateMinute,
4380 neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
4381 reviewDateHour, reviewDateMinute, neverReview,
4382 article.getIndexable(), article.isSmallImage(),
4383 article.getSmallImageURL(), null, null, null, serviceContext);
4384 }
4385
4386
4473 @Indexable(type = IndexableType.REINDEX)
4474 @Override
4475 public JournalArticle updateArticle(
4476 long userId, long groupId, long folderId, String articleId,
4477 double version, Map<Locale, String> titleMap,
4478 Map<Locale, String> descriptionMap, String content, String type,
4479 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
4480 int displayDateMonth, int displayDateDay, int displayDateYear,
4481 int displayDateHour, int displayDateMinute, int expirationDateMonth,
4482 int expirationDateDay, int expirationDateYear,
4483 int expirationDateHour, int expirationDateMinute,
4484 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
4485 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
4486 boolean neverReview, boolean indexable, boolean smallImage,
4487 String smallImageURL, File smallImageFile,
4488 Map<String, byte[]> images, String articleURL,
4489 ServiceContext serviceContext)
4490 throws PortalException, SystemException {
4491
4492
4493
4494 User user = userPersistence.findByPrimaryKey(userId);
4495 articleId = articleId.trim().toUpperCase();
4496
4497 byte[] smallImageBytes = null;
4498
4499 try {
4500 smallImageBytes = FileUtil.getBytes(smallImageFile);
4501 }
4502 catch (IOException ioe) {
4503 }
4504
4505 JournalArticle latestArticle = getLatestArticle(
4506 groupId, articleId, WorkflowConstants.STATUS_ANY);
4507
4508 JournalArticle article = latestArticle;
4509
4510 boolean imported = ExportImportThreadLocal.isImportInProcess();
4511
4512 double latestVersion = latestArticle.getVersion();
4513
4514 boolean addNewVersion = false;
4515
4516 if (imported) {
4517 if (latestVersion > version) {
4518 JournalArticle existingArticle =
4519 journalArticlePersistence.fetchByG_A_V(
4520 groupId, articleId, version);
4521
4522 if (existingArticle != null) {
4523 article = existingArticle;
4524 }
4525 else {
4526 addNewVersion = true;
4527 }
4528 }
4529 else if (latestVersion < version) {
4530 addNewVersion = true;
4531 }
4532 }
4533 else {
4534 if ((version > 0) && (version != latestVersion)) {
4535 throw new ArticleVersionException();
4536 }
4537
4538 serviceContext.validateModifiedDate(
4539 latestArticle, ArticleVersionException.class);
4540
4541 if (latestArticle.isApproved() || latestArticle.isExpired() ||
4542 latestArticle.isScheduled()) {
4543
4544 addNewVersion = true;
4545
4546 version = MathUtil.format(latestVersion + 0.1, 1, 1);
4547 }
4548 }
4549
4550 Date displayDate = null;
4551 Date expirationDate = null;
4552 Date reviewDate = null;
4553
4554 if (article.getClassNameId() ==
4555 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
4556
4557 displayDate = PortalUtil.getDate(
4558 displayDateMonth, displayDateDay, displayDateYear,
4559 displayDateHour, displayDateMinute, user.getTimeZone(),
4560 ArticleDisplayDateException.class);
4561
4562 if (!neverExpire) {
4563 expirationDate = PortalUtil.getDate(
4564 expirationDateMonth, expirationDateDay, expirationDateYear,
4565 expirationDateHour, expirationDateMinute,
4566 user.getTimeZone(), ArticleExpirationDateException.class);
4567 }
4568
4569 if (!neverReview) {
4570 reviewDate = PortalUtil.getDate(
4571 reviewDateMonth, reviewDateDay, reviewDateYear,
4572 reviewDateHour, reviewDateMinute, user.getTimeZone(),
4573 ArticleReviewDateException.class);
4574 }
4575 }
4576
4577 Date now = new Date();
4578
4579 boolean expired = false;
4580
4581 if ((expirationDate != null) && expirationDate.before(now)) {
4582 expired = true;
4583 }
4584
4585 validate(
4586 user.getCompanyId(), groupId, latestArticle.getClassNameId(),
4587 titleMap, content, type, ddmStructureKey, ddmTemplateKey,
4588 expirationDate, smallImage, smallImageURL, smallImageFile,
4589 smallImageBytes);
4590
4591 if (addNewVersion) {
4592 long id = counterLocalService.increment();
4593
4594 article = journalArticlePersistence.create(id);
4595
4596 article.setResourcePrimKey(latestArticle.getResourcePrimKey());
4597 article.setGroupId(latestArticle.getGroupId());
4598 article.setCompanyId(latestArticle.getCompanyId());
4599 article.setUserId(user.getUserId());
4600 article.setUserName(user.getFullName());
4601 article.setCreateDate(serviceContext.getModifiedDate(now));
4602 article.setClassNameId(latestArticle.getClassNameId());
4603 article.setClassPK(latestArticle.getClassPK());
4604 article.setArticleId(articleId);
4605 article.setVersion(version);
4606 article.setSmallImageId(latestArticle.getSmallImageId());
4607 }
4608
4609 Locale locale = LocaleUtil.getSiteDefault();
4610
4611 String defaultLanguageId = ParamUtil.getString(
4612 serviceContext, "defaultLanguageId");
4613
4614 if (Validator.isNull(defaultLanguageId)) {
4615 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
4616 }
4617
4618 if (Validator.isNotNull(defaultLanguageId)) {
4619 locale = LocaleUtil.fromLanguageId(defaultLanguageId);
4620 }
4621
4622 String title = titleMap.get(locale);
4623
4624 content = format(
4625 user, groupId, articleId, article.getVersion(), addNewVersion,
4626 content, ddmStructureKey, images);
4627
4628 article.setModifiedDate(serviceContext.getModifiedDate(now));
4629 article.setFolderId(folderId);
4630 article.setTitleMap(titleMap, locale);
4631 article.setUrlTitle(
4632 getUniqueUrlTitle(
4633 article.getId(), article.getArticleId(), title,
4634 latestArticle.getUrlTitle(), serviceContext));
4635 article.setDescriptionMap(descriptionMap, locale);
4636 article.setContent(content);
4637 article.setType(type);
4638 article.setStructureId(ddmStructureKey);
4639 article.setTemplateId(ddmTemplateKey);
4640 article.setLayoutUuid(layoutUuid);
4641 article.setDisplayDate(displayDate);
4642 article.setExpirationDate(expirationDate);
4643 article.setReviewDate(reviewDate);
4644 article.setIndexable(indexable);
4645 article.setSmallImage(smallImage);
4646
4647 if (smallImage) {
4648 if ((smallImageFile != null) && (smallImageBytes != null)) {
4649 article.setSmallImageId(counterLocalService.increment());
4650 }
4651 }
4652 else {
4653 article.setSmallImageId(0);
4654 }
4655
4656 article.setSmallImageURL(smallImageURL);
4657
4658 if (latestArticle.isPending()) {
4659 article.setStatus(latestArticle.getStatus());
4660 }
4661 else if (!expired) {
4662 article.setStatus(WorkflowConstants.STATUS_DRAFT);
4663 }
4664 else {
4665 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
4666 }
4667
4668 article.setExpandoBridgeAttributes(serviceContext);
4669
4670 journalArticlePersistence.update(article);
4671
4672
4673
4674 updateAsset(
4675 userId, article, serviceContext.getAssetCategoryIds(),
4676 serviceContext.getAssetTagNames(),
4677 serviceContext.getAssetLinkEntryIds());
4678
4679
4680
4681 if (PortalUtil.getClassNameId(DDMStructure.class) ==
4682 article.getClassNameId()) {
4683
4684 updateDDMStructureXSD(
4685 article.getClassPK(), content, serviceContext);
4686 }
4687
4688
4689
4690 saveImages(
4691 smallImage, article.getSmallImageId(), smallImageFile,
4692 smallImageBytes);
4693
4694
4695
4696 PortletPreferences preferences =
4697 ServiceContextUtil.getPortletPreferences(serviceContext);
4698
4699
4700
4701 if (expired && imported) {
4702 updateStatus(
4703 userId, article, article.getStatus(), articleURL,
4704 new HashMap<String, Serializable>(), serviceContext);
4705 }
4706
4707 if (serviceContext.getWorkflowAction() ==
4708 WorkflowConstants.ACTION_PUBLISH) {
4709
4710 sendEmail(
4711 article, articleURL, preferences, "requested", serviceContext);
4712
4713 WorkflowHandlerRegistryUtil.startWorkflowInstance(
4714 user.getCompanyId(), groupId, userId,
4715 JournalArticle.class.getName(), article.getId(), article,
4716 serviceContext);
4717 }
4718
4719 return journalArticlePersistence.findByPrimaryKey(article.getId());
4720 }
4721
4722
4751 @Override
4752 public JournalArticle updateArticle(
4753 long userId, long groupId, long folderId, String articleId,
4754 double version, String content, ServiceContext serviceContext)
4755 throws PortalException, SystemException {
4756
4757 JournalArticle article = journalArticlePersistence.findByG_A_V(
4758 groupId, articleId, version);
4759
4760 return journalArticleLocalService.updateArticle(
4761 userId, groupId, folderId, articleId, version,
4762 article.getTitleMap(), article.getDescriptionMap(), content,
4763 article.getLayoutUuid(), serviceContext);
4764 }
4765
4766
4771 @Override
4772 public JournalArticle updateArticleTranslation(
4773 long groupId, String articleId, double version, Locale locale,
4774 String title, String description, String content,
4775 Map<String, byte[]> images)
4776 throws PortalException, SystemException {
4777
4778 return journalArticleLocalService.updateArticleTranslation(
4779 groupId, articleId, version, locale, title, description, content,
4780 images, null);
4781 }
4782
4783
4805 @Indexable(type = IndexableType.REINDEX)
4806 @Override
4807 public JournalArticle updateArticleTranslation(
4808 long groupId, String articleId, double version, Locale locale,
4809 String title, String description, String content,
4810 Map<String, byte[]> images, ServiceContext serviceContext)
4811 throws PortalException, SystemException {
4812
4813 validateContent(content);
4814
4815 JournalArticle oldArticle = getLatestArticle(
4816 groupId, articleId, WorkflowConstants.STATUS_ANY);
4817
4818 double oldVersion = oldArticle.getVersion();
4819
4820 if ((version > 0) && (version != oldVersion)) {
4821 throw new ArticleVersionException();
4822 }
4823
4824 boolean incrementVersion = false;
4825
4826 if (oldArticle.isApproved() || oldArticle.isExpired()) {
4827 incrementVersion = true;
4828 }
4829
4830 if (serviceContext != null) {
4831 serviceContext.validateModifiedDate(
4832 oldArticle, ArticleVersionException.class);
4833 }
4834
4835 JournalArticle article = null;
4836
4837 User user = userPersistence.findByPrimaryKey(oldArticle.getUserId());
4838
4839 if (incrementVersion) {
4840 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
4841
4842 long id = counterLocalService.increment();
4843
4844 article = journalArticlePersistence.create(id);
4845
4846 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
4847 article.setGroupId(oldArticle.getGroupId());
4848 article.setCompanyId(oldArticle.getCompanyId());
4849 article.setUserId(oldArticle.getUserId());
4850 article.setUserName(user.getFullName());
4851 article.setCreateDate(new Date());
4852 article.setModifiedDate(new Date());
4853 article.setClassNameId(oldArticle.getClassNameId());
4854 article.setClassPK(oldArticle.getClassPK());
4855 article.setArticleId(articleId);
4856 article.setVersion(newVersion);
4857 article.setTitleMap(oldArticle.getTitleMap());
4858 article.setUrlTitle(
4859 getUniqueUrlTitle(
4860 id, articleId, title, oldArticle.getUrlTitle(),
4861 serviceContext));
4862 article.setDescriptionMap(oldArticle.getDescriptionMap());
4863 article.setType(oldArticle.getType());
4864 article.setStructureId(oldArticle.getStructureId());
4865 article.setTemplateId(oldArticle.getTemplateId());
4866 article.setLayoutUuid(oldArticle.getLayoutUuid());
4867 article.setDisplayDate(oldArticle.getDisplayDate());
4868 article.setExpirationDate(oldArticle.getExpirationDate());
4869 article.setReviewDate(oldArticle.getReviewDate());
4870 article.setIndexable(oldArticle.getIndexable());
4871 article.setSmallImage(oldArticle.getSmallImage());
4872 article.setSmallImageId(oldArticle.getSmallImageId());
4873
4874 if (article.getSmallImageId() == 0) {
4875 article.setSmallImageId(counterLocalService.increment());
4876 }
4877
4878 article.setSmallImageURL(oldArticle.getSmallImageURL());
4879
4880 article.setStatus(WorkflowConstants.STATUS_DRAFT);
4881 article.setStatusDate(new Date());
4882 }
4883 else {
4884 article = oldArticle;
4885 }
4886
4887 Map<Locale, String> titleMap = article.getTitleMap();
4888
4889 titleMap.put(locale, title);
4890
4891 article.setTitleMap(titleMap);
4892
4893 Map<Locale, String> descriptionMap = article.getDescriptionMap();
4894
4895 descriptionMap.put(locale, description);
4896
4897 article.setDescriptionMap(descriptionMap);
4898
4899 content = format(
4900 user, groupId, articleId, article.getVersion(),
4901 !oldArticle.isDraft(), content, oldArticle.getStructureId(),
4902 images);
4903
4904 article.setContent(content);
4905
4906 journalArticlePersistence.update(article);
4907
4908 return article;
4909 }
4910
4911
4924 @Override
4925 public void updateAsset(
4926 long userId, JournalArticle article, long[] assetCategoryIds,
4927 String[] assetTagNames, long[] assetLinkEntryIds)
4928 throws PortalException, SystemException {
4929
4930 boolean visible = article.isApproved();
4931
4932 if (article.getClassNameId() !=
4933 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
4934
4935 visible = false;
4936 }
4937
4938 boolean addDraftAssetEntry = false;
4939
4940 if (!article.isApproved() &&
4941 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
4942
4943 int approvedArticlesCount = journalArticlePersistence.countByG_A_ST(
4944 article.getGroupId(), article.getArticleId(),
4945 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
4946
4947 if (approvedArticlesCount > 0) {
4948 addDraftAssetEntry = true;
4949 }
4950 }
4951
4952 AssetEntry assetEntry = null;
4953
4954 if (addDraftAssetEntry) {
4955 assetEntry = assetEntryLocalService.updateEntry(
4956 userId, article.getGroupId(), article.getCreateDate(),
4957 article.getModifiedDate(), JournalArticle.class.getName(),
4958 article.getPrimaryKey(), article.getUuid(),
4959 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
4960 null, null, null, ContentTypes.TEXT_HTML, article.getTitle(),
4961 article.getDescription(), article.getDescription(), null,
4962 article.getLayoutUuid(), 0, 0, null, false);
4963 }
4964 else {
4965 JournalArticleResource journalArticleResource =
4966 journalArticleResourceLocalService.getArticleResource(
4967 article.getResourcePrimKey());
4968
4969 assetEntry = assetEntryLocalService.updateEntry(
4970 userId, article.getGroupId(), article.getCreateDate(),
4971 article.getModifiedDate(), JournalArticle.class.getName(),
4972 journalArticleResource.getResourcePrimKey(),
4973 journalArticleResource.getUuid(), getClassTypeId(article),
4974 assetCategoryIds, assetTagNames, visible, null, null, null,
4975 ContentTypes.TEXT_HTML, article.getTitle(),
4976 article.getDescription(), article.getDescription(), null,
4977 article.getLayoutUuid(), 0, 0, null, false);
4978 }
4979
4980 assetLinkLocalService.updateLinks(
4981 userId, assetEntry.getEntryId(), assetLinkEntryIds,
4982 AssetLinkConstants.TYPE_RELATED);
4983 }
4984
4985
5000 @Indexable(type = IndexableType.REINDEX)
5001 @Override
5002 public JournalArticle updateContent(
5003 long groupId, String articleId, double version, String content)
5004 throws PortalException, SystemException {
5005
5006 JournalArticle article = journalArticlePersistence.findByG_A_V(
5007 groupId, articleId, version);
5008
5009 article.setContent(content);
5010
5011 journalArticlePersistence.update(article);
5012
5013 return article;
5014 }
5015
5016
5039 @Override
5040 public JournalArticle updateStatus(
5041 long userId, JournalArticle article, int status, String articleURL,
5042 Map<String, Serializable> workflowContext,
5043 ServiceContext serviceContext)
5044 throws PortalException, SystemException {
5045
5046
5047
5048 User user = userPersistence.findByPrimaryKey(userId);
5049 Date now = new Date();
5050
5051 if ((status == WorkflowConstants.STATUS_APPROVED) &&
5052 (article.getClassNameId() ==
5053 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5054 (article.getDisplayDate() != null) &&
5055 now.before(article.getDisplayDate())) {
5056
5057 status = WorkflowConstants.STATUS_SCHEDULED;
5058 }
5059
5060 int oldStatus = article.getStatus();
5061
5062 int oldArticleVersionStatus = WorkflowConstants.STATUS_ANY;
5063
5064 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
5065 new ArrayList<ObjectValuePair<Long, Integer>>();
5066
5067 List<JournalArticle> articleVersions =
5068 (List<JournalArticle>)workflowContext.get("articleVersions");
5069
5070 if ((articleVersions != null) && !articleVersions.isEmpty()) {
5071 JournalArticle oldArticleVersion = articleVersions.get(0);
5072
5073 oldArticleVersionStatus = oldArticleVersion.getStatus();
5074
5075 articleVersionStatusOVPs = getArticleVersionStatuses(
5076 articleVersions);
5077 }
5078
5079 article.setModifiedDate(serviceContext.getModifiedDate(now));
5080
5081 boolean neverExpire = false;
5082
5083 if (status == WorkflowConstants.STATUS_APPROVED) {
5084 Date expirationDate = article.getExpirationDate();
5085
5086 if ((expirationDate != null) && expirationDate.before(now)) {
5087 neverExpire = true;
5088
5089 article.setExpirationDate(null);
5090 }
5091 }
5092
5093 if (status == WorkflowConstants.STATUS_EXPIRED) {
5094 article.setExpirationDate(now);
5095 }
5096
5097 article.setStatus(status);
5098 article.setStatusByUserId(user.getUserId());
5099 article.setStatusByUserName(user.getFullName());
5100 article.setStatusDate(serviceContext.getModifiedDate(now));
5101
5102 journalArticlePersistence.update(article);
5103
5104 if (hasModifiedLatestApprovedVersion(
5105 article.getGroupId(), article.getArticleId(),
5106 article.getVersion())) {
5107
5108 if (status == WorkflowConstants.STATUS_APPROVED) {
5109 updateUrlTitles(
5110 article.getGroupId(), article.getArticleId(),
5111 article.getUrlTitle());
5112
5113
5114
5115 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
5116 (article.getVersion() !=
5117 JournalArticleConstants.VERSION_DEFAULT)) {
5118
5119 AssetEntry draftAssetEntry =
5120 assetEntryLocalService.fetchEntry(
5121 JournalArticle.class.getName(),
5122 article.getPrimaryKey());
5123
5124 if (draftAssetEntry != null) {
5125 long[] assetCategoryIds =
5126 draftAssetEntry.getCategoryIds();
5127 String[] assetTagNames = draftAssetEntry.getTagNames();
5128
5129 List<AssetLink> assetLinks =
5130 assetLinkLocalService.getDirectLinks(
5131 draftAssetEntry.getEntryId(),
5132 AssetLinkConstants.TYPE_RELATED);
5133
5134 long[] assetLinkEntryIds = StringUtil.split(
5135 ListUtil.toString(
5136 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
5137
5138 AssetEntry assetEntry =
5139 assetEntryLocalService.updateEntry(
5140 userId, article.getGroupId(),
5141 article.getCreateDate(),
5142 article.getModifiedDate(),
5143 JournalArticle.class.getName(),
5144 article.getResourcePrimKey(), article.getUuid(),
5145 getClassTypeId(article), assetCategoryIds,
5146 assetTagNames, false, null, null, null,
5147 ContentTypes.TEXT_HTML, article.getTitle(),
5148 article.getDescription(),
5149 article.getDescription(), null,
5150 article.getLayoutUuid(), 0, 0, null, false);
5151
5152 assetLinkLocalService.updateLinks(
5153 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5154 AssetLinkConstants.TYPE_RELATED);
5155
5156 SystemEventHierarchyEntryThreadLocal.push(
5157 JournalArticle.class, 0,
5158 SystemEventConstants.ACTION_SKIP);
5159
5160 try {
5161 assetEntryLocalService.deleteEntry(
5162 JournalArticle.class.getName(),
5163 article.getPrimaryKey());
5164 }
5165 finally {
5166 SystemEventHierarchyEntryThreadLocal.pop();
5167 }
5168 }
5169 }
5170
5171 if (article.getClassNameId() ==
5172 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5173
5174
5175
5176
5177 Date[] dateInterval = getDateInterval(
5178 article.getGroupId(), article.getArticleId(),
5179 article.getDisplayDate(), article.getExpirationDate());
5180
5181 Date displayDate = dateInterval[0];
5182 Date expirationDate = dateInterval[1];
5183
5184 if (neverExpire) {
5185 expirationDate = null;
5186 }
5187
5188 assetEntryLocalService.updateEntry(
5189 JournalArticle.class.getName(),
5190 article.getResourcePrimKey(), displayDate,
5191 expirationDate, true);
5192 }
5193
5194
5195
5196 JSONObject extraDataJSONObject =
5197 JSONFactoryUtil.createJSONObject();
5198
5199 extraDataJSONObject.put("title", article.getTitle());
5200
5201 if (serviceContext.isCommandUpdate()) {
5202 socialActivityLocalService.addActivity(
5203 user.getUserId(), article.getGroupId(),
5204 JournalArticle.class.getName(),
5205 article.getResourcePrimKey(),
5206 JournalActivityKeys.UPDATE_ARTICLE,
5207 extraDataJSONObject.toString(), 0);
5208 }
5209 else {
5210 socialActivityLocalService.addUniqueActivity(
5211 user.getUserId(), article.getGroupId(),
5212 JournalArticle.class.getName(),
5213 article.getResourcePrimKey(),
5214 JournalActivityKeys.ADD_ARTICLE,
5215 extraDataJSONObject.toString(), 0);
5216 }
5217 }
5218 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
5219 updatePreviousApprovedArticle(article);
5220 }
5221 }
5222
5223 if (oldStatus == WorkflowConstants.STATUS_IN_TRASH) {
5224
5225
5226
5227 List<TrashVersion> trashVersions =
5228 (List<TrashVersion>)workflowContext.get("trashVersions");
5229
5230 for (TrashVersion trashVersion : trashVersions) {
5231 JournalArticle trashArticleVersion =
5232 journalArticlePersistence.findByPrimaryKey(
5233 trashVersion.getClassPK());
5234
5235 trashArticleVersion.setStatus(trashVersion.getStatus());
5236
5237 journalArticlePersistence.update(trashArticleVersion);
5238 }
5239
5240 trashEntryLocalService.deleteEntry(
5241 JournalArticle.class.getName(), article.getResourcePrimKey());
5242 }
5243 else if (status == WorkflowConstants.STATUS_IN_TRASH) {
5244 assetEntryLocalService.updateVisible(
5245 JournalArticle.class.getName(), article.getResourcePrimKey(),
5246 false);
5247
5248
5249
5250 for (JournalArticle articleVersion : articleVersions) {
5251 articleVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
5252
5253 journalArticlePersistence.update(articleVersion);
5254 }
5255
5256 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
5257
5258 typeSettingsProperties.put("title", article.getArticleId());
5259
5260 trashEntryLocalService.addTrashEntry(
5261 userId, article.getGroupId(), JournalArticle.class.getName(),
5262 article.getResourcePrimKey(), oldArticleVersionStatus,
5263 articleVersionStatusOVPs, typeSettingsProperties);
5264 }
5265
5266 if ((article.getClassNameId() ==
5267 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5268 (oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
5269 (status != WorkflowConstants.STATUS_IN_TRASH)) {
5270
5271
5272
5273 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
5274 ((status == WorkflowConstants.STATUS_APPROVED) ||
5275 (status == WorkflowConstants.STATUS_DENIED))) {
5276
5277 String msg = "granted";
5278
5279 if (status == WorkflowConstants.STATUS_DENIED) {
5280 msg = "denied";
5281 }
5282
5283 try {
5284 PortletPreferences preferences =
5285 ServiceContextUtil.getPortletPreferences(
5286 serviceContext);
5287
5288 sendEmail(
5289 article, articleURL, preferences, msg, serviceContext);
5290 }
5291 catch (Exception e) {
5292 _log.error(
5293 "Unable to send email to notify the change of status " +
5294 " to " + msg + " for article " + article.getId() +
5295 ": " + e.getMessage());
5296 }
5297 }
5298
5299
5300
5301 notifySubscribers(article, serviceContext);
5302 }
5303
5304 return article;
5305 }
5306
5307
5328 @Override
5329 public JournalArticle updateStatus(
5330 long userId, long classPK, int status,
5331 Map<String, Serializable> workflowContext,
5332 ServiceContext serviceContext)
5333 throws PortalException, SystemException {
5334
5335 JournalArticle article = getArticle(classPK);
5336
5337 return updateStatus(
5338 userId, article, status, null, workflowContext, serviceContext);
5339 }
5340
5341
5363 @Override
5364 public JournalArticle updateStatus(
5365 long userId, long groupId, String articleId, double version,
5366 int status, String articleURL,
5367 Map<String, Serializable> workflowContext,
5368 ServiceContext serviceContext)
5369 throws PortalException, SystemException {
5370
5371 JournalArticle article = journalArticlePersistence.findByG_A_V(
5372 groupId, articleId, version);
5373
5374 return updateStatus(
5375 userId, article, status, articleURL, workflowContext,
5376 serviceContext);
5377 }
5378
5379
5394 @Override
5395 public void updateTemplateId(
5396 long groupId, long classNameId, String oldDDMTemplateKey,
5397 String newDDMTemplateKey)
5398 throws SystemException {
5399
5400 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
5401 groupId, classNameId, oldDDMTemplateKey);
5402
5403 for (JournalArticle article : articles) {
5404 article.setTemplateId(newDDMTemplateKey);
5405
5406 journalArticlePersistence.update(article);
5407 }
5408 }
5409
5410 protected void checkArticlesByDisplayDate(Date displayDate)
5411 throws PortalException, SystemException {
5412
5413 List<JournalArticle> articles = journalArticlePersistence.findByLtD_S(
5414 displayDate, WorkflowConstants.STATUS_SCHEDULED);
5415
5416 for (JournalArticle article : articles) {
5417 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5418 JournalArticle.class);
5419
5420 indexer.reindex(article);
5421
5422 ServiceContext serviceContext = new ServiceContext();
5423
5424 serviceContext.setCommand(Constants.UPDATE);
5425
5426 String layoutFullURL = PortalUtil.getLayoutFullURL(
5427 article.getGroupId(), PortletKeys.JOURNAL);
5428
5429 serviceContext.setLayoutFullURL(layoutFullURL);
5430
5431 serviceContext.setScopeGroupId(article.getGroupId());
5432
5433 updateStatus(
5434 article.getUserId(), article, WorkflowConstants.STATUS_APPROVED,
5435 null, new HashMap<String, Serializable>(), serviceContext);
5436 }
5437 }
5438
5439 protected void checkArticlesByExpirationDate(Date expirationDate)
5440 throws PortalException, SystemException {
5441
5442 List<JournalArticle> articles =
5443 journalArticleFinder.findByExpirationDate(
5444 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
5445 new Date(
5446 expirationDate.getTime() + _JOURNAL_ARTICLE_CHECK_INTERVAL),
5447 new QueryDefinition(WorkflowConstants.STATUS_APPROVED));
5448
5449 if (_log.isDebugEnabled()) {
5450 _log.debug("Expiring " + articles.size() + " articles");
5451 }
5452
5453 Set<Long> companyIds = new HashSet<Long>();
5454
5455 for (JournalArticle article : articles) {
5456 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
5457 List<JournalArticle> currentArticles =
5458 journalArticlePersistence.findByG_A(
5459 article.getGroupId(), article.getArticleId(),
5460 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
5461 new ArticleVersionComparator(true));
5462
5463 for (JournalArticle currentArticle : currentArticles) {
5464 currentArticle.setExpirationDate(
5465 article.getExpirationDate());
5466 currentArticle.setStatus(WorkflowConstants.STATUS_EXPIRED);
5467
5468 journalArticlePersistence.update(currentArticle);
5469 }
5470 }
5471 else {
5472 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5473
5474 journalArticlePersistence.update(article);
5475 }
5476
5477 updatePreviousApprovedArticle(article);
5478
5479 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5480 JournalArticle.class);
5481
5482 indexer.reindex(article);
5483
5484 JournalContentUtil.clearCache(
5485 article.getGroupId(), article.getArticleId(),
5486 article.getTemplateId());
5487
5488 companyIds.add(article.getCompanyId());
5489 }
5490
5491 for (long companyId : companyIds) {
5492 CacheUtil.clearCache(companyId);
5493 }
5494
5495 if (_previousCheckDate == null) {
5496 _previousCheckDate = new Date(
5497 expirationDate.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL);
5498 }
5499 }
5500
5501 protected void checkArticlesByReviewDate(Date reviewDate)
5502 throws PortalException, SystemException {
5503
5504 List<JournalArticle> articles = journalArticleFinder.findByReviewDate(
5505 JournalArticleConstants.CLASSNAME_ID_DEFAULT, reviewDate,
5506 _previousCheckDate);
5507
5508 if (_log.isDebugEnabled()) {
5509 _log.debug(
5510 "Sending review notifications for " + articles.size() +
5511 " articles");
5512 }
5513
5514 for (JournalArticle article : articles) {
5515 String articleURL = StringPool.BLANK;
5516
5517 long ownerId = article.getGroupId();
5518 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
5519 long plid = PortletKeys.PREFS_PLID_SHARED;
5520 String portletId = PortletKeys.JOURNAL;
5521
5522 PortletPreferences preferences =
5523 portletPreferencesLocalService.getPreferences(
5524 article.getCompanyId(), ownerId, ownerType, plid,
5525 portletId);
5526
5527 sendEmail(
5528 article, articleURL, preferences, "review",
5529 new ServiceContext());
5530 }
5531 }
5532
5533 protected void checkStructure(Document contentDoc, Element root)
5534 throws PortalException {
5535
5536 for (Element el : root.elements()) {
5537 checkStructureField(el, contentDoc);
5538
5539 checkStructure(contentDoc, el);
5540 }
5541 }
5542
5543 protected void checkStructure(JournalArticle article)
5544 throws PortalException, SystemException {
5545
5546 Group companyGroup = groupLocalService.getCompanyGroup(
5547 article.getCompanyId());
5548
5549 DDMStructure structure = null;
5550
5551 try {
5552 structure = ddmStructurePersistence.findByG_C_S(
5553 article.getGroupId(),
5554 PortalUtil.getClassNameId(JournalArticle.class),
5555 article.getStructureId());
5556 }
5557 catch (NoSuchStructureException nsse) {
5558 structure = ddmStructurePersistence.findByG_C_S(
5559 companyGroup.getGroupId(),
5560 PortalUtil.getClassNameId(JournalArticle.class),
5561 article.getStructureId());
5562 }
5563
5564 String content = GetterUtil.getString(article.getContent());
5565
5566 try {
5567 Document contentDocument = SAXReaderUtil.read(content);
5568 Document xsdDocument = SAXReaderUtil.read(structure.getXsd());
5569
5570 checkStructure(contentDocument, xsdDocument.getRootElement());
5571 }
5572 catch (DocumentException de) {
5573 throw new SystemException(de);
5574 }
5575 catch (StructureXsdException sxsde) {
5576 long groupId = article.getGroupId();
5577 String articleId = article.getArticleId();
5578 double version = article.getVersion();
5579
5580 if (_log.isWarnEnabled()) {
5581 _log.warn(
5582 "Article {groupId=" + groupId + ", articleId=" +
5583 articleId + ", version=" + version +
5584 "} has content that does not match its " +
5585 "structure: " + sxsde.getMessage());
5586 }
5587 }
5588 }
5589
5590 protected void checkStructureField(Element el, Document contentDoc)
5591 throws PortalException {
5592
5593 StringBuilder elPath = new StringBuilder();
5594
5595 elPath.append(el.attributeValue("name"));
5596
5597 Element elParent = el.getParent();
5598
5599 while (true) {
5600 if ((elParent == null) || elParent.getName().equals("root")) {
5601 break;
5602 }
5603
5604 elPath.insert(
5605 0, elParent.attributeValue("name") + StringPool.COMMA);
5606
5607 elParent = elParent.getParent();
5608 }
5609
5610 String[] elPathNames = StringUtil.split(elPath.toString());
5611
5612 Element contentEl = contentDoc.getRootElement();
5613
5614 for (String _elPathName : elPathNames) {
5615 boolean foundEl = false;
5616
5617 for (Element tempEl : contentEl.elements()) {
5618 if (_elPathName.equals(
5619 tempEl.attributeValue("name", StringPool.BLANK))) {
5620
5621 contentEl = tempEl;
5622 foundEl = true;
5623
5624 break;
5625 }
5626 }
5627
5628 if (!foundEl) {
5629 String elType = contentEl.attributeValue(
5630 "type", StringPool.BLANK);
5631
5632 if (!elType.equals("list") && !elType.equals("multi-list")) {
5633 throw new StructureXsdException(elPath.toString());
5634 }
5635
5636 break;
5637 }
5638 }
5639 }
5640
5641 protected void copyArticleImages(
5642 JournalArticle oldArticle, JournalArticle newArticle)
5643 throws Exception {
5644
5645 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
5646
5647 XPath xPathSelector = SAXReaderUtil.createXPath(
5648 "
5649
5650 List<Node> imageNodes = xPathSelector.selectNodes(contentDoc);
5651
5652 for (Node imageNode : imageNodes) {
5653 Element imageEl = (Element)imageNode;
5654
5655 String instanceId = imageEl.attributeValue("instance-id");
5656 String name = imageEl.attributeValue("name");
5657
5658 List<Element> dynamicContentEls = imageEl.elements(
5659 "dynamic-content");
5660
5661 for (Element dynamicContentEl : dynamicContentEls) {
5662 long imageId = GetterUtil.getLong(
5663 dynamicContentEl.attributeValue("id"));
5664 String languageId = dynamicContentEl.attributeValue(
5665 "language-id");
5666
5667 Image oldImage = null;
5668
5669 try {
5670 oldImage = imageLocalService.getImage(imageId);
5671 }
5672 catch (NoSuchImageException nsie) {
5673 continue;
5674 }
5675
5676 imageId = journalArticleImageLocalService.getArticleImageId(
5677 newArticle.getGroupId(), newArticle.getArticleId(),
5678 newArticle.getVersion(), instanceId, name, languageId);
5679
5680 imageLocalService.updateImage(imageId, oldImage.getTextObj());
5681
5682 String elContent =
5683 "/image/journal/article?img_id=" + imageId + "&t=" +
5684 WebServerServletTokenUtil.getToken(imageId);
5685
5686 dynamicContentEl.setText(elContent);
5687 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
5688 }
5689 }
5690
5691 newArticle.setContent(contentDoc.formattedString());
5692 }
5693
5694 protected void format(
5695 User user, long groupId, String articleId, double version,
5696 boolean incrementVersion, Element root, Map<String, byte[]> images)
5697 throws PortalException, SystemException {
5698
5699 for (Element element : root.elements()) {
5700 String elInstanceId = element.attributeValue(
5701 "instance-id", StringPool.BLANK);
5702 String elType = element.attributeValue("type", StringPool.BLANK);
5703
5704 if (elType.equals("image")) {
5705 String elName = element.attributeValue(
5706 "name", StringPool.BLANK);
5707 String elIndex = element.attributeValue(
5708 "index", StringPool.BLANK);
5709
5710 String name = elName + "_" + elIndex;
5711
5712 formatImage(
5713 groupId, articleId, version, incrementVersion, element,
5714 elInstanceId, name, images);
5715 }
5716 else if (elType.equals("text_area") || elType.equals("text") ||
5717 elType.equals("text_box")) {
5718
5719 List<Element> dynamicContentElements = element.elements(
5720 "dynamic-content");
5721
5722 for (Element dynamicContentElement : dynamicContentElements) {
5723 String dynamicContent = dynamicContentElement.getText();
5724
5725 if (Validator.isNotNull(dynamicContent)) {
5726 String contentType = ContentTypes.TEXT_PLAIN;
5727
5728 if (elType.equals("text_area")) {
5729 contentType = ContentTypes.TEXT_HTML;
5730 }
5731
5732 dynamicContent = SanitizerUtil.sanitize(
5733 user.getCompanyId(), groupId, user.getUserId(),
5734 JournalArticle.class.getName(), 0, contentType,
5735 dynamicContent);
5736
5737 dynamicContentElement.clearContent();
5738
5739 dynamicContentElement.addCDATA(dynamicContent);
5740 }
5741 }
5742 }
5743
5744 format(
5745 user, groupId, articleId, version, incrementVersion, element,
5746 images);
5747 }
5748 }
5749
5750 protected String format(
5751 User user, long groupId, String articleId, double version,
5752 boolean incrementVersion, String content, String ddmStructureKey,
5753 Map<String, byte[]> images)
5754 throws PortalException, SystemException {
5755
5756 Document document = null;
5757
5758 try {
5759 document = SAXReaderUtil.read(content);
5760
5761 Element rootElement = document.getRootElement();
5762
5763 if (Validator.isNotNull(ddmStructureKey)) {
5764 format(
5765 user, groupId, articleId, version, incrementVersion,
5766 rootElement, images);
5767 }
5768 else {
5769 List<Element> staticContentElements = rootElement.elements(
5770 "static-content");
5771
5772 for (Element staticContentElement : staticContentElements) {
5773 String staticContent = staticContentElement.getText();
5774
5775 staticContent = SanitizerUtil.sanitize(
5776 user.getCompanyId(), groupId, user.getUserId(),
5777 JournalArticle.class.getName(), 0,
5778 ContentTypes.TEXT_HTML, staticContent);
5779
5780 staticContentElement.clearContent();
5781
5782 staticContentElement.addCDATA(staticContent);
5783 }
5784 }
5785
5786 content = DDMXMLUtil.formatXML(document);
5787 }
5788 catch (DocumentException de) {
5789 _log.error(de, de);
5790 }
5791
5792 content = HtmlUtil.replaceMsWordCharacters(content);
5793
5794 return content;
5795 }
5796
5797 protected void formatImage(
5798 long groupId, String articleId, double version,
5799 boolean incrementVersion, Element el, String elInstanceId,
5800 String elName, Map<String, byte[]> images)
5801 throws PortalException, SystemException {
5802
5803 List<Element> imageContents = el.elements("dynamic-content");
5804
5805 for (Element dynamicContent : imageContents) {
5806 String elLanguage = dynamicContent.attributeValue(
5807 "language-id", StringPool.BLANK);
5808
5809 if (!elLanguage.equals(StringPool.BLANK)) {
5810 elLanguage = "_" + elLanguage;
5811 }
5812
5813 long imageId = journalArticleImageLocalService.getArticleImageId(
5814 groupId, articleId, version, elInstanceId, elName, elLanguage);
5815
5816 if (dynamicContent.getText().equals("delete") ||
5817 Validator.isNull(dynamicContent.getText())) {
5818
5819 dynamicContent.setText(StringPool.BLANK);
5820
5821 imageLocalService.deleteImage(imageId);
5822
5823 String defaultElLanguage = "";
5824
5825 if (Validator.isNull(elLanguage)) {
5826 defaultElLanguage =
5827 "_" +
5828 LocaleUtil.toLanguageId(
5829 LocaleUtil.getSiteDefault());
5830 }
5831
5832 long defaultImageId =
5833 journalArticleImageLocalService.getArticleImageId(
5834 groupId, articleId, version, elInstanceId, elName,
5835 defaultElLanguage);
5836
5837 imageLocalService.deleteImage(defaultImageId);
5838
5839 continue;
5840 }
5841
5842 String elContent =
5843 "/image/journal/article?img_id=" + imageId + "&t=" +
5844 WebServerServletTokenUtil.getToken(imageId);
5845
5846 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
5847
5848 if (ArrayUtil.isNotEmpty(bytes)) {
5849 dynamicContent.setText(elContent);
5850 dynamicContent.addAttribute("id", String.valueOf(imageId));
5851
5852 imageLocalService.updateImage(imageId, bytes);
5853
5854 continue;
5855 }
5856
5857 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
5858 incrementVersion) {
5859
5860 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
5861
5862 long oldImageId = 0;
5863
5864 if ((oldVersion >= 1) && incrementVersion) {
5865 oldImageId =
5866 journalArticleImageLocalService.getArticleImageId(
5867 groupId, articleId, oldVersion, elInstanceId,
5868 elName, elLanguage);
5869 }
5870
5871 Image oldImage = null;
5872
5873 if (oldImageId > 0) {
5874 oldImage = imageLocalService.getImage(oldImageId);
5875 }
5876
5877 if (oldImage != null) {
5878 dynamicContent.setText(elContent);
5879 dynamicContent.addAttribute("id", String.valueOf(imageId));
5880
5881 bytes = oldImage.getTextObj();
5882
5883 imageLocalService.updateImage(imageId, bytes);
5884 }
5885 else if (dynamicContent.getText().equals("update")) {
5886 dynamicContent.setText(StringPool.BLANK);
5887 }
5888
5889 continue;
5890 }
5891
5892 Image image = imageLocalService.getImage(imageId);
5893
5894 if (image != null) {
5895 dynamicContent.setText(elContent);
5896 dynamicContent.addAttribute("id", String.valueOf(imageId));
5897
5898 continue;
5899 }
5900 else if (dynamicContent.getText().equals("update")) {
5901 dynamicContent.setText(StringPool.BLANK);
5902
5903 continue;
5904 }
5905
5906 long contentImageId = GetterUtil.getLong(
5907 HttpUtil.getParameter(dynamicContent.getText(), "img_id"));
5908
5909 if (contentImageId <= 0) {
5910 contentImageId = GetterUtil.getLong(
5911 HttpUtil.getParameter(
5912 dynamicContent.getText(), "img_id", false));
5913 }
5914
5915 if (contentImageId > 0) {
5916 image = imageLocalService.getImage(contentImageId);
5917
5918 if (image != null) {
5919 dynamicContent.addAttribute(
5920 "id", String.valueOf(contentImageId));
5921
5922 continue;
5923 }
5924 }
5925
5926 String defaultElLanguage = "";
5927
5928 if (Validator.isNull(elLanguage)) {
5929 defaultElLanguage =
5930 "_" + LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
5931 }
5932
5933 long defaultImageId =
5934 journalArticleImageLocalService.getArticleImageId(
5935 groupId, articleId, version, elInstanceId, elName,
5936 defaultElLanguage);
5937
5938 Image defaultImage = imageLocalService.getImage(defaultImageId);
5939
5940 if (defaultImage != null) {
5941 dynamicContent.setText(elContent);
5942 dynamicContent.addAttribute(
5943 "id", String.valueOf(defaultImageId));
5944
5945 bytes = defaultImage.getTextObj();
5946
5947 imageLocalService.updateImage(defaultImageId, bytes);
5948
5949 continue;
5950 }
5951
5952 if (Validator.isNotNull(elLanguage)) {
5953 dynamicContent.setText(StringPool.BLANK);
5954 }
5955 }
5956 }
5957
5958 protected List<ObjectValuePair<Long, Integer>> getArticleVersionStatuses(
5959 List<JournalArticle> articles) {
5960
5961 List<ObjectValuePair<Long, Integer>> dlArticleVersionStatusOVPs =
5962 new ArrayList<ObjectValuePair<Long, Integer>>(articles.size());
5963
5964 for (JournalArticle article : articles) {
5965 int status = article.getStatus();
5966
5967 if (status == WorkflowConstants.STATUS_PENDING) {
5968 status = WorkflowConstants.STATUS_DRAFT;
5969 }
5970
5971 ObjectValuePair<Long, Integer> dlFileVersionStatusOVP =
5972 new ObjectValuePair<Long, Integer>(article.getId(), status);
5973
5974 dlArticleVersionStatusOVPs.add(dlFileVersionStatusOVP);
5975 }
5976
5977 return dlArticleVersionStatusOVPs;
5978 }
5979
5980 protected long getClassTypeId(JournalArticle article) {
5981 long classTypeId = 0;
5982
5983 try {
5984 long classNameId = PortalUtil.getClassNameId(JournalArticle.class);
5985
5986 DDMStructure ddmStructure = ddmStructurePersistence.fetchByG_C_S(
5987 article.getGroupId(), classNameId, article.getStructureId());
5988
5989 if (ddmStructure == null) {
5990 Group companyGroup = groupLocalService.getCompanyGroup(
5991 article.getCompanyId());
5992
5993 ddmStructure = ddmStructurePersistence.fetchByG_C_S(
5994 companyGroup.getGroupId(), classNameId,
5995 article.getStructureId());
5996 }
5997
5998 if (ddmStructure != null) {
5999 classTypeId = ddmStructure.getStructureId();
6000 }
6001 }
6002 catch (Exception e) {
6003 _log.error(e, e);
6004 }
6005
6006 return classTypeId;
6007 }
6008
6009 protected Date[] getDateInterval(
6010 long groupId, String articleId, Date earliestDisplayDate,
6011 Date latestExpirationDate)
6012 throws SystemException {
6013
6014 Date[] dateInterval = new Date[2];
6015
6016 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
6017 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6018
6019 boolean expiringArticle = true;
6020
6021 if (latestExpirationDate == null) {
6022 expiringArticle = false;
6023 }
6024
6025 for (JournalArticle article : articles) {
6026 if ((earliestDisplayDate == null) ||
6027 ((article.getDisplayDate() != null) &&
6028 earliestDisplayDate.after(article.getDisplayDate()))) {
6029
6030 earliestDisplayDate = article.getDisplayDate();
6031 }
6032
6033 if (expiringArticle &&
6034 ((latestExpirationDate == null) ||
6035 ((article.getExpirationDate() != null) &&
6036 latestExpirationDate.before(article.getExpirationDate())))) {
6037
6038 latestExpirationDate = article.getExpirationDate();
6039 }
6040
6041 if (expiringArticle && (article.getExpirationDate() == null) &&
6042 (latestExpirationDate != null)) {
6043
6044 expiringArticle = false;
6045 }
6046 }
6047
6048 dateInterval[0] = earliestDisplayDate;
6049 dateInterval[1] = latestExpirationDate;
6050
6051 return dateInterval;
6052 }
6053
6054 protected String getUniqueUrlTitle(
6055 long id, long groupId, String articleId, String title)
6056 throws PortalException, SystemException {
6057
6058 String urlTitle = JournalUtil.getUrlTitle(id, title);
6059
6060 return getUniqueUrlTitle(groupId, articleId, urlTitle);
6061 }
6062
6063 protected String getUniqueUrlTitle(
6064 long id, String articleId, String title, String oldUrlTitle,
6065 ServiceContext serviceContext)
6066 throws PortalException, SystemException {
6067
6068 String serviceContextUrlTitle = ParamUtil.getString(
6069 serviceContext, "urlTitle");
6070
6071 String urlTitle = null;
6072
6073 if (Validator.isNotNull(serviceContextUrlTitle)) {
6074 urlTitle = JournalUtil.getUrlTitle(id, serviceContextUrlTitle);
6075 }
6076 else if (Validator.isNotNull(oldUrlTitle)) {
6077 return oldUrlTitle;
6078 }
6079 else {
6080 urlTitle = getUniqueUrlTitle(
6081 id, serviceContext.getScopeGroupId(), articleId, title);
6082 }
6083
6084 JournalArticle urlTitleArticle = null;
6085
6086 try {
6087 urlTitleArticle = getArticleByUrlTitle(
6088 serviceContext.getScopeGroupId(), urlTitle);
6089 }
6090 catch (NoSuchArticleException nsae) {
6091 }
6092
6093 if ((urlTitleArticle != null) &&
6094 !Validator.equals(
6095 urlTitleArticle.getArticleId(), articleId)) {
6096
6097 urlTitle = getUniqueUrlTitle(
6098 id, serviceContext.getScopeGroupId(), articleId, urlTitle);
6099 }
6100
6101 return urlTitle;
6102 }
6103
6104 protected boolean hasModifiedLatestApprovedVersion(
6105 long groupId, String articleId, double version)
6106 throws PortalException, SystemException {
6107
6108 double latestApprovedVersion;
6109
6110 try {
6111 latestApprovedVersion = getLatestVersion(
6112 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6113
6114 if (version >= latestApprovedVersion) {
6115 return true;
6116 }
6117 else {
6118 return false;
6119 }
6120 }
6121 catch (NoSuchArticleException nsae) {
6122 return true;
6123 }
6124 }
6125
6126 protected void notifySubscribers(
6127 JournalArticle article, ServiceContext serviceContext)
6128 throws PortalException, SystemException {
6129
6130 if (!article.isApproved()) {
6131 return;
6132 }
6133
6134 String articleURL = PortalUtil.getControlPanelFullURL(
6135 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
6136
6137 if (Validator.isNull(articleURL)) {
6138 return;
6139 }
6140
6141 PortletPreferences preferences =
6142 ServiceContextUtil.getPortletPreferences(serviceContext);
6143
6144 if (preferences == null) {
6145 long ownerId = article.getGroupId();
6146 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
6147 long plid = PortletKeys.PREFS_PLID_SHARED;
6148 String portletId = PortletKeys.JOURNAL;
6149 String defaultPreferences = null;
6150
6151 preferences = portletPreferencesLocalService.getPreferences(
6152 article.getCompanyId(), ownerId, ownerType, plid, portletId,
6153 defaultPreferences);
6154 }
6155
6156 if ((article.getVersion() == 1.0) &&
6157 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
6158 }
6159 else if ((article.getVersion() != 1.0) &&
6160 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
6161 }
6162 else {
6163 return;
6164 }
6165
6166 String fromName = JournalUtil.getEmailFromName(
6167 preferences, article.getCompanyId());
6168 String fromAddress = JournalUtil.getEmailFromAddress(
6169 preferences, article.getCompanyId());
6170
6171 String subject = null;
6172 String body = null;
6173
6174 if (article.getVersion() == 1.0) {
6175 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
6176 body = JournalUtil.getEmailArticleAddedBody(preferences);
6177 }
6178 else {
6179 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
6180 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
6181 }
6182
6183 SubscriptionSender subscriptionSender = new SubscriptionSender();
6184
6185 subscriptionSender.setBody(body);
6186 subscriptionSender.setCompanyId(article.getCompanyId());
6187 subscriptionSender.setContextAttributes(
6188 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6189 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6190 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
6191 subscriptionSender.setContextUserPrefix("ARTICLE");
6192 subscriptionSender.setFrom(fromAddress, fromName);
6193 subscriptionSender.setHtmlFormat(true);
6194 subscriptionSender.setMailId("journal_article", article.getId());
6195 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6196 subscriptionSender.setReplyToAddress(fromAddress);
6197 subscriptionSender.setScopeGroupId(article.getGroupId());
6198 subscriptionSender.setServiceContext(serviceContext);
6199 subscriptionSender.setSubject(subject);
6200 subscriptionSender.setUserId(article.getUserId());
6201
6202 subscriptionSender.addPersistedSubscribers(
6203 JournalArticle.class.getName(), article.getResourcePrimKey());
6204
6205 JournalFolder folder = article.getFolder();
6206
6207 List<Long> folderIds = new ArrayList<Long>();
6208
6209 if (folder != null) {
6210 folderIds.add(folder.getFolderId());
6211
6212 folderIds.addAll(folder.getAncestorFolderIds());
6213 }
6214
6215 for (long curFolderId : folderIds) {
6216 subscriptionSender.addPersistedSubscribers(
6217 JournalFolder.class.getName(), curFolderId);
6218 }
6219
6220 subscriptionSender.addPersistedSubscribers(
6221 JournalFolder.class.getName(), article.getGroupId());
6222
6223 subscriptionSender.flushNotificationsAsync();
6224 }
6225
6226 protected void saveImages(
6227 boolean smallImage, long smallImageId, File smallImageFile,
6228 byte[] smallImageBytes)
6229 throws PortalException, SystemException {
6230
6231 if (smallImage) {
6232 if ((smallImageFile != null) && (smallImageBytes != null)) {
6233 imageLocalService.updateImage(smallImageId, smallImageBytes);
6234 }
6235 }
6236 else {
6237 imageLocalService.deleteImage(smallImageId);
6238 }
6239 }
6240
6241 protected void sendEmail(
6242 JournalArticle article, String articleURL,
6243 PortletPreferences preferences, String emailType,
6244 ServiceContext serviceContext)
6245 throws PortalException, SystemException {
6246
6247 if (preferences == null) {
6248 return;
6249 }
6250 else if (emailType.equals("denied") &&
6251 JournalUtil.getEmailArticleApprovalDeniedEnabled(
6252 preferences)) {
6253 }
6254 else if (emailType.equals("granted") &&
6255 JournalUtil.getEmailArticleApprovalGrantedEnabled(
6256 preferences)) {
6257 }
6258 else if (emailType.equals("requested") &&
6259 JournalUtil.getEmailArticleApprovalRequestedEnabled(
6260 preferences)) {
6261 }
6262 else if (emailType.equals("review") &&
6263 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
6264 }
6265 else {
6266 return;
6267 }
6268
6269 Company company = companyPersistence.findByPrimaryKey(
6270 article.getCompanyId());
6271
6272 User user = userPersistence.findByPrimaryKey(article.getUserId());
6273
6274 articleURL +=
6275 "&groupId=" + article.getGroupId() + "&articleId=" +
6276 article.getArticleId() + "&version=" + article.getVersion();
6277
6278 String fromName = JournalUtil.getEmailFromName(
6279 preferences, article.getCompanyId());
6280 String fromAddress = JournalUtil.getEmailFromAddress(
6281 preferences, article.getCompanyId());
6282
6283 String toName = user.getFullName();
6284 String toAddress = user.getEmailAddress();
6285
6286 if (emailType.equals("requested") || emailType.equals("review")) {
6287 String tempToName = fromName;
6288 String tempToAddress = fromAddress;
6289
6290 fromName = toName;
6291 fromAddress = toAddress;
6292
6293 toName = tempToName;
6294 toAddress = tempToAddress;
6295 }
6296
6297 String subject = null;
6298 String body = null;
6299
6300 if (emailType.equals("denied")) {
6301 subject = JournalUtil.getEmailArticleApprovalDeniedSubject(
6302 preferences);
6303 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
6304 }
6305 else if (emailType.equals("granted")) {
6306 subject = JournalUtil.getEmailArticleApprovalGrantedSubject(
6307 preferences);
6308 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
6309 }
6310 else if (emailType.equals("requested")) {
6311 subject = JournalUtil.getEmailArticleApprovalRequestedSubject(
6312 preferences);
6313 body = JournalUtil.getEmailArticleApprovalRequestedBody(
6314 preferences);
6315 }
6316 else if (emailType.equals("review")) {
6317 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
6318 body = JournalUtil.getEmailArticleReviewBody(preferences);
6319 }
6320
6321 SubscriptionSender subscriptionSender = new SubscriptionSender();
6322
6323 subscriptionSender.setBody(body);
6324 subscriptionSender.setCompanyId(company.getCompanyId());
6325 subscriptionSender.setContextAttributes(
6326 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6327 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6328 articleURL, "[$ARTICLE_USER_NAME$]", article.getUserName(),
6329 "[$ARTICLE_VERSION$]", article.getVersion());
6330 subscriptionSender.setContextUserPrefix("ARTICLE");
6331 subscriptionSender.setFrom(fromAddress, fromName);
6332 subscriptionSender.setHtmlFormat(true);
6333 subscriptionSender.setMailId("journal_article", article.getId());
6334 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6335 subscriptionSender.setScopeGroupId(article.getGroupId());
6336 subscriptionSender.setServiceContext(serviceContext);
6337 subscriptionSender.setSubject(subject);
6338 subscriptionSender.setUserId(article.getUserId());
6339
6340 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
6341
6342 subscriptionSender.flushNotificationsAsync();
6343 }
6344
6345 protected void updateDDMStructureXSD(
6346 long ddmStructureId, String content, ServiceContext serviceContext)
6347 throws PortalException, SystemException {
6348
6349 try {
6350 Document document = SAXReaderUtil.read(content);
6351
6352 Element rootElement = document.getRootElement();
6353
6354 List<Element> elements = rootElement.elements();
6355
6356 for (Element element : elements) {
6357 String fieldName = element.attributeValue(
6358 "name", StringPool.BLANK);
6359
6360 List<Element> dynamicContentElements = element.elements(
6361 "dynamic-content");
6362
6363 for (Element dynamicContentElement : dynamicContentElements) {
6364 String value = dynamicContentElement.getText();
6365
6366 ddmStructureLocalService.updateXSDFieldMetadata(
6367 ddmStructureId, fieldName,
6368 FieldConstants.PREDEFINED_VALUE, value, serviceContext);
6369 }
6370 }
6371 }
6372 catch (DocumentException de) {
6373 throw new SystemException(de);
6374 }
6375 }
6376
6377 protected void updatePreviousApprovedArticle(JournalArticle article)
6378 throws PortalException, SystemException {
6379
6380 List<JournalArticle> approvedArticles =
6381 journalArticlePersistence.findByG_A_ST(
6382 article.getGroupId(), article.getArticleId(),
6383 WorkflowConstants.STATUS_APPROVED, 0, 2);
6384
6385 if (approvedArticles.isEmpty() ||
6386 ((approvedArticles.size() == 1) &&
6387 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
6388
6389 assetEntryLocalService.updateVisible(
6390 JournalArticle.class.getName(), article.getResourcePrimKey(),
6391 false);
6392 }
6393 else {
6394 JournalArticle previousApprovedArticle = approvedArticles.get(0);
6395
6396 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
6397 previousApprovedArticle = approvedArticles.get(1);
6398 }
6399
6400 Date[] dateInterval = getDateInterval(
6401 previousApprovedArticle.getGroupId(),
6402 previousApprovedArticle.getArticleId(),
6403 previousApprovedArticle.getDisplayDate(),
6404 previousApprovedArticle.getExpirationDate());
6405
6406 Date displayDate = dateInterval[0];
6407 Date expirationDate = dateInterval[1];
6408
6409 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
6410 JournalArticle.class.getName(), article.getResourcePrimKey(),
6411 displayDate, expirationDate, true);
6412
6413 assetEntry.setModifiedDate(
6414 previousApprovedArticle.getModifiedDate());
6415
6416 assetEntryPersistence.update(assetEntry);
6417 }
6418 }
6419
6420 protected void updateUrlTitles(
6421 long groupId, String articleId, String urlTitle)
6422 throws SystemException {
6423
6424 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
6425 groupId, articleId);
6426
6427 for (JournalArticle article : articles) {
6428 if (!article.getUrlTitle().equals(urlTitle)) {
6429 article.setUrlTitle(urlTitle);
6430
6431 journalArticlePersistence.update(article);
6432 }
6433 }
6434 }
6435
6436 protected void validate(
6437 long companyId, long groupId, long classNameId,
6438 Map<Locale, String> titleMap, String content, String type,
6439 String ddmStructureKey, String ddmTemplateKey, Date expirationDate,
6440 boolean smallImage, String smallImageURL, File smallImageFile,
6441 byte[] smallImageBytes)
6442 throws PortalException, SystemException {
6443
6444 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
6445 LocalizationUtil.getDefaultLanguageId(content));
6446
6447 Locale[] availableLocales = LanguageUtil.getAvailableLocales(groupId);
6448
6449 if (!ArrayUtil.contains(availableLocales, articleDefaultLocale)) {
6450 LocaleException le = new LocaleException(
6451 LocaleException.TYPE_CONTENT,
6452 "The locale " + articleDefaultLocale +
6453 " is not available in site with groupId" + groupId);
6454
6455 Locale[] sourceAvailableLocales = {articleDefaultLocale};
6456
6457 le.setSourceAvailableLocales(sourceAvailableLocales);
6458 le.setTargetAvailableLocales(availableLocales);
6459
6460 throw le;
6461 }
6462
6463 if ((classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
6464 (titleMap.isEmpty() ||
6465 Validator.isNull(titleMap.get(articleDefaultLocale)))) {
6466
6467 throw new ArticleTitleException();
6468 }
6469 else if (Validator.isNull(type)) {
6470 throw new ArticleTypeException();
6471 }
6472
6473 validateContent(content);
6474
6475 if (Validator.isNotNull(ddmStructureKey)) {
6476 Group companyGroup = groupLocalService.getCompanyGroup(companyId);
6477
6478 DDMStructure ddmStructure = null;
6479
6480 try {
6481 ddmStructure = ddmStructurePersistence.findByG_C_S(
6482 groupId, PortalUtil.getClassNameId(JournalArticle.class),
6483 ddmStructureKey);
6484 }
6485 catch (NoSuchStructureException nsse) {
6486 ddmStructure = ddmStructurePersistence.findByG_C_S(
6487 companyGroup.getGroupId(),
6488 PortalUtil.getClassNameId(JournalArticle.class),
6489 ddmStructureKey);
6490 }
6491
6492 DDMTemplate ddmTemplate = null;
6493
6494 if (Validator.isNotNull(ddmTemplateKey)) {
6495 try {
6496 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
6497 groupId, PortalUtil.getClassNameId(DDMStructure.class),
6498 ddmTemplateKey);
6499 }
6500 catch (NoSuchTemplateException nste) {
6501 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
6502 companyGroup.getGroupId(),
6503 PortalUtil.getClassNameId(DDMStructure.class),
6504 ddmTemplateKey);
6505 }
6506
6507 if (ddmTemplate.getClassPK() != ddmStructure.getStructureId()) {
6508 throw new NoSuchTemplateException();
6509 }
6510 }
6511 else if (classNameId ==
6512 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
6513
6514 throw new NoSuchTemplateException();
6515 }
6516 }
6517
6518 if ((expirationDate != null) && expirationDate.before(new Date()) &&
6519 !ExportImportThreadLocal.isImportInProcess()) {
6520
6521 throw new ArticleExpirationDateException();
6522 }
6523
6524 String[] imageExtensions = PrefsPropsUtil.getStringArray(
6525 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
6526
6527 if (!smallImage || Validator.isNotNull(smallImageURL) ||
6528 (smallImageFile == null) || (smallImageBytes == null)) {
6529
6530 return;
6531 }
6532
6533 String smallImageName = smallImageFile.getName();
6534
6535 if (smallImageName != null) {
6536 boolean validSmallImageExtension = false;
6537
6538 for (String _imageExtension : imageExtensions) {
6539 if (StringPool.STAR.equals(_imageExtension) ||
6540 StringUtil.endsWith(smallImageName, _imageExtension)) {
6541
6542 validSmallImageExtension = true;
6543
6544 break;
6545 }
6546 }
6547
6548 if (!validSmallImageExtension) {
6549 throw new ArticleSmallImageNameException(smallImageName);
6550 }
6551 }
6552
6553 long smallImageMaxSize = PrefsPropsUtil.getLong(
6554 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
6555
6556 if ((smallImageMaxSize > 0) &&
6557 ((smallImageBytes == null) ||
6558 (smallImageBytes.length > smallImageMaxSize))) {
6559
6560 throw new ArticleSmallImageSizeException();
6561 }
6562 }
6563
6564 protected void validate(
6565 long companyId, long groupId, long classNameId, String articleId,
6566 boolean autoArticleId, double version, Map<Locale, String> titleMap,
6567 String content, String type, String ddmStructureKey,
6568 String ddmTemplateKey, Date expirationDate, boolean smallImage,
6569 String smallImageURL, File smallImageFile, byte[] smallImageBytes)
6570 throws PortalException, SystemException {
6571
6572 if (!autoArticleId) {
6573 validate(articleId);
6574 }
6575
6576 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
6577 groupId, articleId, version);
6578
6579 if (article != null) {
6580 throw new DuplicateArticleIdException();
6581 }
6582
6583 validate(
6584 companyId, groupId, classNameId, titleMap, content, type,
6585 ddmStructureKey, ddmTemplateKey, expirationDate, smallImage,
6586 smallImageURL, smallImageFile, smallImageBytes);
6587 }
6588
6589 protected void validate(String articleId) throws PortalException {
6590 if (Validator.isNull(articleId) ||
6591 (articleId.indexOf(CharPool.SPACE) != -1)) {
6592
6593 throw new ArticleIdException();
6594 }
6595 }
6596
6597 protected void validateContent(String content) throws PortalException {
6598 if (Validator.isNull(content)) {
6599 throw new ArticleContentException("Content is null");
6600 }
6601
6602 try {
6603 SAXReaderUtil.read(content);
6604 }
6605 catch (DocumentException de) {
6606 if (_log.isDebugEnabled()) {
6607 _log.debug("Invalid content:\n" + content);
6608 }
6609
6610 throw new ArticleContentException(
6611 "Unable to read content with an XML parser", de);
6612 }
6613 }
6614
6615 private static final long _JOURNAL_ARTICLE_CHECK_INTERVAL =
6616 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
6617
6618 private static Log _log = LogFactoryUtil.getLog(
6619 JournalArticleLocalServiceImpl.class);
6620
6621 private Date _previousCheckDate;
6622
6623 }