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