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.template.TemplateConstants;
043 import com.liferay.portal.kernel.util.ArrayUtil;
044 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
045 import com.liferay.portal.kernel.util.CharPool;
046 import com.liferay.portal.kernel.util.Constants;
047 import com.liferay.portal.kernel.util.ContentTypes;
048 import com.liferay.portal.kernel.util.FileUtil;
049 import com.liferay.portal.kernel.util.GetterUtil;
050 import com.liferay.portal.kernel.util.HtmlUtil;
051 import com.liferay.portal.kernel.util.HttpUtil;
052 import com.liferay.portal.kernel.util.ListUtil;
053 import com.liferay.portal.kernel.util.LocaleUtil;
054 import com.liferay.portal.kernel.util.LocalizationUtil;
055 import com.liferay.portal.kernel.util.MathUtil;
056 import com.liferay.portal.kernel.util.ObjectValuePair;
057 import com.liferay.portal.kernel.util.OrderByComparator;
058 import com.liferay.portal.kernel.util.ParamUtil;
059 import com.liferay.portal.kernel.util.PropsKeys;
060 import com.liferay.portal.kernel.util.StringBundler;
061 import com.liferay.portal.kernel.util.StringPool;
062 import com.liferay.portal.kernel.util.StringUtil;
063 import com.liferay.portal.kernel.util.Time;
064 import com.liferay.portal.kernel.util.TreePathUtil;
065 import com.liferay.portal.kernel.util.UnicodeProperties;
066 import com.liferay.portal.kernel.util.Validator;
067 import com.liferay.portal.kernel.workflow.WorkflowConstants;
068 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
069 import com.liferay.portal.kernel.xml.Document;
070 import com.liferay.portal.kernel.xml.DocumentException;
071 import com.liferay.portal.kernel.xml.Element;
072 import com.liferay.portal.kernel.xml.Node;
073 import com.liferay.portal.kernel.xml.SAXReaderUtil;
074 import com.liferay.portal.kernel.xml.XPath;
075 import com.liferay.portal.model.Company;
076 import com.liferay.portal.model.Group;
077 import com.liferay.portal.model.Image;
078 import com.liferay.portal.model.ResourceConstants;
079 import com.liferay.portal.model.SystemEventConstants;
080 import com.liferay.portal.model.User;
081 import com.liferay.portal.service.ServiceContext;
082 import com.liferay.portal.service.ServiceContextUtil;
083 import com.liferay.portal.servlet.filters.cache.CacheUtil;
084 import com.liferay.portal.theme.ThemeDisplay;
085 import com.liferay.portal.util.PortalUtil;
086 import com.liferay.portal.util.PortletKeys;
087 import com.liferay.portal.util.PrefsPropsUtil;
088 import com.liferay.portal.util.PropsValues;
089 import com.liferay.portal.util.SubscriptionSender;
090 import com.liferay.portal.webserver.WebServerServletTokenUtil;
091 import com.liferay.portlet.asset.model.AssetEntry;
092 import com.liferay.portlet.asset.model.AssetLink;
093 import com.liferay.portlet.asset.model.AssetLinkConstants;
094 import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
095 import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
096 import com.liferay.portlet.dynamicdatamapping.StorageFieldNameException;
097 import com.liferay.portlet.dynamicdatamapping.StorageFieldRequiredException;
098 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
099 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
100 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
101 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
102 import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
103 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
104 import com.liferay.portlet.journal.ArticleContentException;
105 import com.liferay.portlet.journal.ArticleDisplayDateException;
106 import com.liferay.portlet.journal.ArticleExpirationDateException;
107 import com.liferay.portlet.journal.ArticleIdException;
108 import com.liferay.portlet.journal.ArticleReviewDateException;
109 import com.liferay.portlet.journal.ArticleSmallImageNameException;
110 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
111 import com.liferay.portlet.journal.ArticleTitleException;
112 import com.liferay.portlet.journal.ArticleTypeException;
113 import com.liferay.portlet.journal.ArticleVersionException;
114 import com.liferay.portlet.journal.DuplicateArticleIdException;
115 import com.liferay.portlet.journal.NoSuchArticleException;
116 import com.liferay.portlet.journal.StructureXsdException;
117 import com.liferay.portlet.journal.model.JournalArticle;
118 import com.liferay.portlet.journal.model.JournalArticleConstants;
119 import com.liferay.portlet.journal.model.JournalArticleDisplay;
120 import com.liferay.portlet.journal.model.JournalArticleResource;
121 import com.liferay.portlet.journal.model.JournalFolder;
122 import com.liferay.portlet.journal.model.impl.JournalArticleDisplayImpl;
123 import com.liferay.portlet.journal.model.impl.JournalArticleModelImpl;
124 import com.liferay.portlet.journal.model.impl.JournalFolderModelImpl;
125 import com.liferay.portlet.journal.service.base.JournalArticleLocalServiceBaseImpl;
126 import com.liferay.portlet.journal.social.JournalActivityKeys;
127 import com.liferay.portlet.journal.util.JournalUtil;
128 import com.liferay.portlet.journal.util.comparator.ArticleIDComparator;
129 import com.liferay.portlet.journal.util.comparator.ArticleVersionComparator;
130 import com.liferay.portlet.journalcontent.util.JournalContentUtil;
131 import com.liferay.portlet.social.model.SocialActivityConstants;
132 import com.liferay.portlet.trash.model.TrashEntry;
133 import com.liferay.portlet.trash.model.TrashVersion;
134 import com.liferay.portlet.trash.util.TrashUtil;
135
136 import java.io.File;
137 import java.io.IOException;
138 import java.io.Serializable;
139
140 import java.util.ArrayList;
141 import java.util.Calendar;
142 import java.util.Date;
143 import java.util.HashMap;
144 import java.util.HashSet;
145 import java.util.LinkedHashMap;
146 import java.util.List;
147 import java.util.Locale;
148 import java.util.Map;
149 import java.util.Set;
150
151 import javax.portlet.PortletPreferences;
152
153
182 public class JournalArticleLocalServiceImpl
183 extends JournalArticleLocalServiceBaseImpl {
184
185
268 @Indexable(type = IndexableType.REINDEX)
269 @Override
270 public JournalArticle addArticle(
271 long userId, long groupId, long folderId, long classNameId,
272 long classPK, String articleId, boolean autoArticleId,
273 double version, Map<Locale, String> titleMap,
274 Map<Locale, String> descriptionMap, String content, String type,
275 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
276 int displayDateMonth, int displayDateDay, int displayDateYear,
277 int displayDateHour, int displayDateMinute, int expirationDateMonth,
278 int expirationDateDay, int expirationDateYear,
279 int expirationDateHour, int expirationDateMinute,
280 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
281 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
282 boolean neverReview, boolean indexable, boolean smallImage,
283 String smallImageURL, File smallImageFile,
284 Map<String, byte[]> images, String articleURL,
285 ServiceContext serviceContext)
286 throws PortalException, SystemException {
287
288
289
290 User user = userPersistence.findByPrimaryKey(userId);
291 articleId = StringUtil.toUpperCase(articleId.trim());
292
293 Date displayDate = null;
294 Date expirationDate = null;
295 Date reviewDate = null;
296
297 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
298 displayDate = PortalUtil.getDate(
299 displayDateMonth, displayDateDay, displayDateYear,
300 displayDateHour, displayDateMinute, user.getTimeZone(),
301 ArticleDisplayDateException.class);
302
303 if (!neverExpire) {
304 expirationDate = PortalUtil.getDate(
305 expirationDateMonth, expirationDateDay, expirationDateYear,
306 expirationDateHour, expirationDateMinute,
307 user.getTimeZone(), ArticleExpirationDateException.class);
308 }
309
310 if (!neverReview) {
311 reviewDate = PortalUtil.getDate(
312 reviewDateMonth, reviewDateDay, reviewDateYear,
313 reviewDateHour, reviewDateMinute, user.getTimeZone(),
314 ArticleReviewDateException.class);
315 }
316 }
317
318 byte[] smallImageBytes = null;
319
320 try {
321 smallImageBytes = FileUtil.getBytes(smallImageFile);
322 }
323 catch (IOException ioe) {
324 }
325
326 Date now = new Date();
327
328 validate(
329 user.getCompanyId(), groupId, classNameId, articleId, autoArticleId,
330 version, titleMap, content, type, ddmStructureKey, ddmTemplateKey,
331 expirationDate, smallImage, smallImageURL, smallImageFile,
332 smallImageBytes, serviceContext);
333
334 if (autoArticleId) {
335 articleId = String.valueOf(counterLocalService.increment());
336 }
337
338 serviceContext.setAttribute("articleId", articleId);
339
340 long id = counterLocalService.increment();
341
342 long resourcePrimKey =
343 journalArticleResourceLocalService.getArticleResourcePrimKey(
344 serviceContext.getUuid(), groupId, articleId);
345
346 JournalArticle article = journalArticlePersistence.create(id);
347
348 Locale locale = getArticleDefaultLocale(content, serviceContext);
349
350 String title = titleMap.get(locale);
351
352 content = format(
353 user, groupId, articleId, version, false, content, ddmStructureKey,
354 images);
355
356 article.setResourcePrimKey(resourcePrimKey);
357 article.setGroupId(groupId);
358 article.setCompanyId(user.getCompanyId());
359 article.setUserId(user.getUserId());
360 article.setUserName(user.getFullName());
361 article.setCreateDate(serviceContext.getCreateDate(now));
362 article.setModifiedDate(serviceContext.getModifiedDate(now));
363 article.setFolderId(folderId);
364 article.setClassNameId(classNameId);
365 article.setClassPK(classPK);
366 article.setTreePath(article.buildTreePath());
367 article.setArticleId(articleId);
368 article.setVersion(version);
369 article.setTitleMap(titleMap, locale);
370 article.setUrlTitle(
371 getUniqueUrlTitle(id, articleId, title, null, serviceContext));
372 article.setDescriptionMap(descriptionMap, locale);
373 article.setContent(content);
374 article.setType(type);
375 article.setStructureId(ddmStructureKey);
376 article.setTemplateId(ddmTemplateKey);
377 article.setLayoutUuid(layoutUuid);
378 article.setDisplayDate(displayDate);
379 article.setExpirationDate(expirationDate);
380 article.setReviewDate(reviewDate);
381 article.setIndexable(indexable);
382 article.setSmallImage(smallImage);
383 article.setSmallImageId(counterLocalService.increment());
384 article.setSmallImageURL(smallImageURL);
385
386 if ((expirationDate == null) || expirationDate.after(now)) {
387 article.setStatus(WorkflowConstants.STATUS_DRAFT);
388 }
389 else {
390 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
391 }
392
393 article.setStatusByUserId(userId);
394 article.setStatusDate(serviceContext.getModifiedDate(now));
395 article.setExpandoBridgeAttributes(serviceContext);
396
397 journalArticlePersistence.update(article);
398
399
400
401 if (serviceContext.isAddGroupPermissions() ||
402 serviceContext.isAddGuestPermissions()) {
403
404 addArticleResources(
405 article, serviceContext.isAddGroupPermissions(),
406 serviceContext.isAddGuestPermissions());
407 }
408 else {
409 addArticleResources(
410 article, serviceContext.getGroupPermissions(),
411 serviceContext.getGuestPermissions());
412 }
413
414
415
416 saveImages(
417 smallImage, article.getSmallImageId(), smallImageFile,
418 smallImageBytes);
419
420
421
422 updateAsset(
423 userId, article, serviceContext.getAssetCategoryIds(),
424 serviceContext.getAssetTagNames(),
425 serviceContext.getAssetLinkEntryIds());
426
427
428
429 if (PortalUtil.getClassNameId(DDMStructure.class) == classNameId) {
430 updateDDMStructureXSD(classPK, content, serviceContext);
431 }
432
433
434
435 if (PropsValues.JOURNAL_ARTICLE_COMMENTS_ENABLED) {
436 mbMessageLocalService.addDiscussionMessage(
437 userId, article.getUserName(), groupId,
438 JournalArticle.class.getName(), resourcePrimKey,
439 WorkflowConstants.ACTION_PUBLISH);
440 }
441
442
443
444 PortletPreferences preferences =
445 ServiceContextUtil.getPortletPreferences(serviceContext);
446
447 articleURL = buildArticleURL(articleURL, groupId, folderId, articleId);
448
449 serviceContext.setAttribute("articleURL", articleURL);
450
451 sendEmail(
452 article, articleURL, preferences, "requested", serviceContext);
453
454
455
456 if (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
457 WorkflowHandlerRegistryUtil.startWorkflowInstance(
458 user.getCompanyId(), groupId, userId,
459 JournalArticle.class.getName(), article.getId(), article,
460 serviceContext);
461 }
462 else {
463 updateStatus(
464 userId, article, WorkflowConstants.STATUS_APPROVED, null,
465 new HashMap<String, Serializable>(), serviceContext);
466 }
467
468 return journalArticlePersistence.findByPrimaryKey(article.getId());
469 }
470
471
500 @Override
501 public JournalArticle addArticle(
502 long userId, long groupId, long folderId,
503 Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
504 String content, String ddmStructureKey, String ddmTemplateKey,
505 ServiceContext serviceContext)
506 throws PortalException, SystemException {
507
508 User user = userPersistence.findByPrimaryKey(userId);
509
510 Calendar calendar = CalendarFactoryUtil.getCalendar(user.getTimeZone());
511
512 int displayDateMonth = calendar.get(Calendar.MONTH);
513 int displayDateDay = calendar.get(Calendar.DAY_OF_MONTH);
514 int displayDateYear = calendar.get(Calendar.YEAR);
515 int displayDateHour = calendar.get(Calendar.HOUR_OF_DAY);
516 int displayDateMinute = calendar.get(Calendar.MINUTE);
517
518 return journalArticleLocalService.addArticle(
519 userId, groupId, folderId,
520 JournalArticleConstants.CLASSNAME_ID_DEFAULT, 0, StringPool.BLANK,
521 true, 1, titleMap, descriptionMap, content, "general",
522 ddmStructureKey, ddmTemplateKey, null, displayDateMonth,
523 displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
524 0, 0, 0, 0, 0, true, 0, 0, 0, 0, 0, true, true, false, null, null,
525 null, null, serviceContext);
526 }
527
528
538 @Override
539 public void addArticleResources(
540 JournalArticle article, boolean addGroupPermissions,
541 boolean addGuestPermissions)
542 throws PortalException, SystemException {
543
544 resourceLocalService.addResources(
545 article.getCompanyId(), article.getGroupId(), article.getUserId(),
546 JournalArticle.class.getName(), article.getResourcePrimKey(), false,
547 addGroupPermissions, addGuestPermissions);
548 }
549
550
559 @Override
560 public void addArticleResources(
561 JournalArticle article, String[] groupPermissions,
562 String[] guestPermissions)
563 throws PortalException, SystemException {
564
565 resourceLocalService.addModelResources(
566 article.getCompanyId(), article.getGroupId(), article.getUserId(),
567 JournalArticle.class.getName(), article.getResourcePrimKey(),
568 groupPermissions, guestPermissions);
569 }
570
571
581 @Override
582 public void addArticleResources(
583 long groupId, String articleId, boolean addGroupPermissions,
584 boolean addGuestPermissions)
585 throws PortalException, SystemException {
586
587 JournalArticle article = getLatestArticle(groupId, articleId);
588
589 addArticleResources(article, addGroupPermissions, addGuestPermissions);
590 }
591
592
603 @Override
604 public void addArticleResources(
605 long groupId, String articleId, String[] groupPermissions,
606 String[] guestPermissions)
607 throws PortalException, SystemException {
608
609 JournalArticle article = getLatestArticle(groupId, articleId);
610
611 addArticleResources(article, groupPermissions, guestPermissions);
612 }
613
614
627 @Override
628 public JournalArticle checkArticleResourcePrimKey(
629 long groupId, String articleId, double version)
630 throws PortalException, SystemException {
631
632 JournalArticle article = journalArticlePersistence.findByG_A_V(
633 groupId, articleId, version);
634
635 if (article.getResourcePrimKey() > 0) {
636 return article;
637 }
638
639 long resourcePrimKey =
640 journalArticleResourceLocalService.getArticleResourcePrimKey(
641 groupId, articleId);
642
643 article.setResourcePrimKey(resourcePrimKey);
644
645 journalArticlePersistence.update(article);
646
647 return article;
648 }
649
650
657 @Override
658 public void checkArticles() throws PortalException, SystemException {
659 Date now = new Date();
660
661 checkArticlesByExpirationDate(now);
662
663 checkArticlesByReviewDate(now);
664
665 checkArticlesByDisplayDate(now);
666
667 _previousCheckDate = now;
668 }
669
670
682 @Override
683 public void checkNewLine(long groupId, String articleId, double version)
684 throws PortalException, SystemException {
685
686 JournalArticle article = journalArticlePersistence.findByG_A_V(
687 groupId, articleId, version);
688
689 String content = GetterUtil.getString(article.getContent());
690
691 if (content.contains("\\n")) {
692 content = StringUtil.replace(
693 content, new String[] {"\\n", "\\r"},
694 new String[] {"\n", "\r"});
695
696 article.setContent(content);
697
698 journalArticlePersistence.update(article);
699 }
700 }
701
702
715 @Override
716 public void checkStructure(long groupId, String articleId, double version)
717 throws PortalException, SystemException {
718
719 JournalArticle article = journalArticlePersistence.findByG_A_V(
720 groupId, articleId, version);
721
722 if (Validator.isNull(article.getStructureId())) {
723 return;
724 }
725
726 checkStructure(article);
727 }
728
729
745 @Indexable(type = IndexableType.REINDEX)
746 @Override
747 public JournalArticle copyArticle(
748 long userId, long groupId, String oldArticleId, String newArticleId,
749 boolean autoArticleId, double version)
750 throws PortalException, SystemException {
751
752
753
754 User user = userPersistence.findByPrimaryKey(userId);
755 oldArticleId = StringUtil.toUpperCase(oldArticleId.trim());
756 newArticleId = StringUtil.toUpperCase(newArticleId.trim());
757 Date now = new Date();
758
759 JournalArticle oldArticle = journalArticlePersistence.findByG_A_V(
760 groupId, oldArticleId, version);
761
762 if (autoArticleId) {
763 newArticleId = String.valueOf(counterLocalService.increment());
764 }
765 else {
766 validate(newArticleId);
767
768 if (journalArticlePersistence.countByG_A(
769 groupId, newArticleId) > 0) {
770
771 StringBundler sb = new StringBundler(5);
772
773 sb.append("{groupId=");
774 sb.append(groupId);
775 sb.append(", articleId=");
776 sb.append(newArticleId);
777 sb.append("}");
778
779 throw new DuplicateArticleIdException(sb.toString());
780 }
781 }
782
783 long id = counterLocalService.increment();
784
785 long resourcePrimKey =
786 journalArticleResourceLocalService.getArticleResourcePrimKey(
787 groupId, newArticleId);
788
789 JournalArticle newArticle = journalArticlePersistence.create(id);
790
791 newArticle.setResourcePrimKey(resourcePrimKey);
792 newArticle.setGroupId(groupId);
793 newArticle.setCompanyId(user.getCompanyId());
794 newArticle.setUserId(user.getUserId());
795 newArticle.setUserName(user.getFullName());
796 newArticle.setCreateDate(now);
797 newArticle.setModifiedDate(now);
798 newArticle.setFolderId(oldArticle.getFolderId());
799 newArticle.setTreePath(oldArticle.getTreePath());
800 newArticle.setArticleId(newArticleId);
801 newArticle.setVersion(JournalArticleConstants.VERSION_DEFAULT);
802 newArticle.setTitle(oldArticle.getTitle());
803 newArticle.setUrlTitle(
804 getUniqueUrlTitle(
805 id, groupId, newArticleId, oldArticle.getTitleCurrentValue()));
806 newArticle.setDescription(oldArticle.getDescription());
807
808 try {
809 copyArticleImages(oldArticle, newArticle);
810 }
811 catch (Exception e) {
812 newArticle.setContent(oldArticle.getContent());
813 }
814
815 newArticle.setType(oldArticle.getType());
816 newArticle.setStructureId(oldArticle.getStructureId());
817 newArticle.setTemplateId(oldArticle.getTemplateId());
818 newArticle.setLayoutUuid(oldArticle.getLayoutUuid());
819 newArticle.setDisplayDate(oldArticle.getDisplayDate());
820 newArticle.setExpirationDate(oldArticle.getExpirationDate());
821 newArticle.setReviewDate(oldArticle.getReviewDate());
822 newArticle.setIndexable(oldArticle.isIndexable());
823 newArticle.setSmallImage(oldArticle.isSmallImage());
824 newArticle.setSmallImageId(counterLocalService.increment());
825 newArticle.setSmallImageURL(oldArticle.getSmallImageURL());
826
827 if (oldArticle.isPending() ||
828 workflowDefinitionLinkLocalService.hasWorkflowDefinitionLink(
829 user.getCompanyId(), groupId, JournalArticle.class.getName())) {
830
831 newArticle.setStatus(WorkflowConstants.STATUS_DRAFT);
832 }
833 else {
834 newArticle.setStatus(oldArticle.getStatus());
835 }
836
837 newArticle.setExpandoBridgeAttributes(oldArticle);
838
839 journalArticlePersistence.update(newArticle);
840
841
842
843 addArticleResources(newArticle, true, true);
844
845
846
847 if (oldArticle.isSmallImage()) {
848 Image image = imageLocalService.fetchImage(
849 oldArticle.getSmallImageId());
850
851 if (image != null) {
852 byte[] smallImageBytes = image.getTextObj();
853
854 imageLocalService.updateImage(
855 newArticle.getSmallImageId(), smallImageBytes);
856 }
857 }
858
859
860
861 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
862 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
863 String[] assetTagNames = assetTagLocalService.getTagNames(
864 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
865
866 AssetEntry oldAssetEntry = assetEntryLocalService.getEntry(
867 JournalArticle.class.getName(), oldArticle.getResourcePrimKey());
868
869 List<AssetLink> assetLinks = assetLinkLocalService.getDirectLinks(
870 oldAssetEntry.getEntryId());
871
872 long[] assetLinkEntryIds = StringUtil.split(
873 ListUtil.toString(assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
874
875 updateAsset(
876 userId, newArticle, assetCategoryIds, assetTagNames,
877 assetLinkEntryIds);
878
879 return newArticle;
880 }
881
882
889 @Override
890 @SystemEvent(
891 action = SystemEventConstants.ACTION_SKIP, send = false)
892 public JournalArticle deleteArticle(JournalArticle article)
893 throws PortalException, SystemException {
894
895 return journalArticleLocalService.deleteArticle(
896 article, StringPool.BLANK, null);
897 }
898
899
913 @Indexable(type = IndexableType.DELETE)
914 @Override
915 @SystemEvent(
916 action = SystemEventConstants.ACTION_SKIP, send = false)
917 public JournalArticle deleteArticle(
918 JournalArticle article, String articleURL,
919 ServiceContext serviceContext)
920 throws PortalException, SystemException {
921
922 JournalArticleResource articleResource =
923 journalArticleResourceLocalService.fetchArticleResource(
924 article.getGroupId(), article.getArticleId());
925
926 if (article.isApproved() &&
927 isLatestVersion(
928 article.getGroupId(), article.getArticleId(),
929 article.getVersion(), WorkflowConstants.STATUS_APPROVED)) {
930
931 updatePreviousApprovedArticle(article);
932 }
933
934
935
936 if ((serviceContext != null) && Validator.isNotNull(articleURL)) {
937 PortletPreferences preferences =
938 ServiceContextUtil.getPortletPreferences(serviceContext);
939
940 if ((preferences != null) && !article.isApproved() &&
941 isLatestVersion(
942 article.getGroupId(), article.getArticleId(),
943 article.getVersion())) {
944
945 articleURL = buildArticleURL(
946 articleURL, article.getGroupId(), article.getFolderId(),
947 article.getArticleId());
948
949 sendEmail(
950 article, articleURL, preferences, "denied", serviceContext);
951 }
952 }
953
954
955
956 journalArticleImageLocalService.deleteImages(
957 article.getGroupId(), article.getArticleId(), article.getVersion());
958
959
960
961 expandoRowLocalService.deleteRows(article.getId());
962
963
964
965 if (article.isInTrash()) {
966 TrashEntry trashEntry = article.getTrashEntry();
967
968 if (trashEntry != null) {
969 trashVersionLocalService.deleteTrashVersion(
970 trashEntry.getEntryId(), JournalArticle.class.getName(),
971 article.getId());
972 }
973 }
974
975
976
977 if (!article.isDraft()) {
978 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
979 article.getCompanyId(), article.getGroupId(),
980 JournalArticle.class.getName(), article.getId());
981 }
982
983 int articlesCount = journalArticlePersistence.countByG_A(
984 article.getGroupId(), article.getArticleId());
985
986 if (articlesCount == 1) {
987
988
989
990 subscriptionLocalService.deleteSubscriptions(
991 article.getCompanyId(), JournalArticle.class.getName(),
992 article.getResourcePrimKey());
993
994
995
996 ratingsStatsLocalService.deleteStats(
997 JournalArticle.class.getName(), article.getResourcePrimKey());
998
999
1000
1001 mbMessageLocalService.deleteDiscussionMessages(
1002 JournalArticle.class.getName(), article.getResourcePrimKey());
1003
1004
1005
1006 assetEntryLocalService.deleteEntry(
1007 JournalArticle.class.getName(), article.getResourcePrimKey());
1008
1009
1010
1011 journalContentSearchLocalService.deleteArticleContentSearches(
1012 article.getGroupId(), article.getArticleId());
1013
1014
1015
1016 imageLocalService.deleteImage(article.getSmallImageId());
1017
1018
1019
1020 trashEntryLocalService.deleteEntry(
1021 JournalArticle.class.getName(), article.getResourcePrimKey());
1022
1023
1024
1025 resourceLocalService.deleteResource(
1026 article.getCompanyId(), JournalArticle.class.getName(),
1027 ResourceConstants.SCOPE_INDIVIDUAL,
1028 article.getResourcePrimKey());
1029
1030
1031
1032 if (articleResource != null) {
1033 journalArticleResourceLocalService.deleteJournalArticleResource(
1034 articleResource);
1035 }
1036 }
1037
1038
1039
1040 journalArticlePersistence.remove(article);
1041
1042
1043
1044 if (articleResource != null) {
1045 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1046
1047 extraDataJSONObject.put("version", article.getVersion());
1048
1049 systemEventLocalService.addSystemEvent(
1050 0, article.getGroupId(), article.getModelClassName(),
1051 article.getPrimaryKey(), articleResource.getUuid(), null,
1052 SystemEventConstants.TYPE_DELETE,
1053 extraDataJSONObject.toString());
1054 }
1055
1056 return article;
1057 }
1058
1059
1075 @Override
1076 public JournalArticle deleteArticle(
1077 long groupId, String articleId, double version, String articleURL,
1078 ServiceContext serviceContext)
1079 throws PortalException, SystemException {
1080
1081 JournalArticle article = journalArticlePersistence.findByG_A_V(
1082 groupId, articleId, version);
1083
1084 return journalArticleLocalService.deleteArticle(
1085 article, articleURL, serviceContext);
1086 }
1087
1088
1101 @Override
1102 public void deleteArticle(
1103 long groupId, String articleId, ServiceContext serviceContext)
1104 throws PortalException, SystemException {
1105
1106 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1107
1108 JournalArticleResource articleResource =
1109 journalArticleResourceLocalService.fetchArticleResource(
1110 groupId, articleId);
1111
1112 try {
1113 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1114 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1115 new ArticleVersionComparator(true));
1116
1117 for (JournalArticle article : articles) {
1118 journalArticleLocalService.deleteArticle(
1119 article, null, serviceContext);
1120 }
1121 }
1122 finally {
1123 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1124 }
1125
1126 if (articleResource != null) {
1127 systemEventLocalService.addSystemEvent(
1128 0, groupId, JournalArticle.class.getName(),
1129 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1130 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1131 }
1132 }
1133
1134
1141 @Override
1142 public void deleteArticles(long groupId)
1143 throws PortalException, SystemException {
1144
1145 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1146
1147 List<JournalArticleResource> articleResources =
1148 new ArrayList<JournalArticleResource>();
1149
1150 try {
1151 JournalArticleResource articleResource = null;
1152
1153 for (JournalArticle article :
1154 journalArticlePersistence.findByGroupId(groupId)) {
1155
1156 if ((articleResource == null) ||
1157 (articleResource.getPrimaryKey() !=
1158 article.getResourcePrimKey())) {
1159
1160 articleResource =
1161 journalArticleResourceLocalService.getArticleResource(
1162 article.getResourcePrimKey());
1163
1164 articleResources.add(articleResource);
1165 }
1166
1167 journalArticleLocalService.deleteArticle(article, null, null);
1168 }
1169 }
1170 finally {
1171 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1172 }
1173
1174 for (JournalArticleResource articleResource : articleResources) {
1175 systemEventLocalService.addSystemEvent(
1176 0, groupId, JournalArticle.class.getName(),
1177 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1178 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1179 }
1180 }
1181
1182
1191 @Override
1192 public void deleteArticles(long groupId, long folderId)
1193 throws PortalException, SystemException {
1194
1195 deleteArticles(groupId, folderId, true);
1196 }
1197
1198
1209 @Override
1210 public void deleteArticles(
1211 long groupId, long folderId, boolean includeTrashedEntries)
1212 throws PortalException, SystemException {
1213
1214 SystemEventHierarchyEntryThreadLocal.push(JournalArticle.class);
1215
1216 List<JournalArticleResource> articleResources =
1217 new ArrayList<JournalArticleResource>();
1218
1219 try {
1220 JournalArticleResource articleResource = null;
1221
1222 for (JournalArticle article :
1223 journalArticlePersistence.findByG_F(groupId, folderId)) {
1224
1225 if ((articleResource == null) ||
1226 (articleResource.getPrimaryKey() !=
1227 article.getResourcePrimKey())) {
1228
1229 articleResource =
1230 journalArticleResourceLocalService.getArticleResource(
1231 article.getResourcePrimKey());
1232
1233 articleResources.add(articleResource);
1234 }
1235
1236 if (includeTrashedEntries || !article.isInTrashExplicitly()) {
1237 journalArticleLocalService.deleteArticle(
1238 article, null, null);
1239 }
1240 else {
1241 articleResources.remove(articleResource);
1242 }
1243 }
1244 }
1245 finally {
1246 SystemEventHierarchyEntryThreadLocal.pop(JournalArticle.class);
1247 }
1248
1249 for (JournalArticleResource articleResource : articleResources) {
1250 systemEventLocalService.addSystemEvent(
1251 0, groupId, JournalArticle.class.getName(),
1252 articleResource.getResourcePrimKey(), articleResource.getUuid(),
1253 null, SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
1254 }
1255 }
1256
1257
1266 @Override
1267 public void deleteLayoutArticleReferences(long groupId, String layoutUuid)
1268 throws SystemException {
1269
1270 List<JournalArticle> articles = journalArticlePersistence.findByG_L(
1271 groupId, layoutUuid);
1272
1273 for (JournalArticle article : articles) {
1274 article.setLayoutUuid(StringPool.BLANK);
1275
1276 journalArticlePersistence.update(article);
1277 }
1278 }
1279
1280
1303 @Indexable(type = IndexableType.REINDEX)
1304 @Override
1305 public JournalArticle expireArticle(
1306 long userId, long groupId, String articleId, double version,
1307 String articleURL, ServiceContext serviceContext)
1308 throws PortalException, SystemException {
1309
1310 return updateStatus(
1311 userId, groupId, articleId, version,
1312 WorkflowConstants.STATUS_EXPIRED, articleURL,
1313 new HashMap<String, Serializable>(), serviceContext);
1314 }
1315
1316
1339 @Override
1340 public void expireArticle(
1341 long userId, long groupId, String articleId, String articleURL,
1342 ServiceContext serviceContext)
1343 throws PortalException, SystemException {
1344
1345 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
1346 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
1347 groupId, articleId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
1348 new ArticleVersionComparator(true));
1349
1350 for (JournalArticle article : articles) {
1351 journalArticleLocalService.expireArticle(
1352 userId, groupId, article.getArticleId(),
1353 article.getVersion(), articleURL, serviceContext);
1354 }
1355 }
1356 else {
1357 JournalArticle article = getLatestArticle(
1358 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1359
1360 journalArticleLocalService.expireArticle(
1361 userId, groupId, article.getArticleId(), article.getVersion(),
1362 articleURL, serviceContext);
1363 }
1364 }
1365
1366 @Override
1367 public JournalArticle fetchArticle(
1368 long groupId, String articleId, double version)
1369 throws SystemException {
1370
1371 return journalArticlePersistence.fetchByG_A_V(
1372 groupId, articleId, version);
1373 }
1374
1375 @Override
1376 public JournalArticle fetchLatestArticle(
1377 long resourcePrimKey, int[] statuses)
1378 throws SystemException {
1379
1380 OrderByComparator orderByComparator = new ArticleVersionComparator();
1381
1382 List<JournalArticle> articles = journalArticlePersistence.findByR_ST(
1383 resourcePrimKey, statuses, 0, 1, orderByComparator);
1384
1385 if (!articles.isEmpty()) {
1386 return articles.get(0);
1387 }
1388
1389 return null;
1390 }
1391
1392 @Override
1393 public JournalArticle fetchLatestArticle(
1394 long resourcePrimKey, int status, boolean preferApproved)
1395 throws SystemException {
1396
1397 JournalArticle article = null;
1398
1399 OrderByComparator orderByComparator = new ArticleVersionComparator();
1400
1401 if (status == WorkflowConstants.STATUS_ANY) {
1402 if (preferApproved) {
1403 article = journalArticlePersistence.fetchByR_ST_First(
1404 resourcePrimKey, WorkflowConstants.STATUS_APPROVED,
1405 orderByComparator);
1406 }
1407
1408 if (article == null) {
1409 article =
1410 journalArticlePersistence.fetchByResourcePrimKey_First(
1411 resourcePrimKey, orderByComparator);
1412 }
1413 }
1414 else {
1415 article = journalArticlePersistence.fetchByR_ST_First(
1416 resourcePrimKey, status, orderByComparator);
1417 }
1418
1419 return article;
1420 }
1421
1422 @Override
1423 public JournalArticle fetchLatestArticle(
1424 long groupId, String articleId, int status)
1425 throws SystemException {
1426
1427 OrderByComparator orderByComparator = new ArticleVersionComparator();
1428
1429 if (status == WorkflowConstants.STATUS_ANY) {
1430 return journalArticlePersistence.fetchByG_A_NotST_First(
1431 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH,
1432 orderByComparator);
1433 }
1434
1435 return journalArticlePersistence.fetchByG_A_ST_First(
1436 groupId, articleId, status, orderByComparator);
1437 }
1438
1439 @Override
1440 public JournalArticle fetchLatestIndexableArticle(long resourcePrimKey)
1441 throws SystemException {
1442
1443 OrderByComparator orderByComparator = new ArticleVersionComparator();
1444
1445 int[] statuses = new int[] {
1446 WorkflowConstants.STATUS_APPROVED, WorkflowConstants.STATUS_IN_TRASH
1447 };
1448
1449 List<JournalArticle> articles =
1450 journalArticlePersistence.findByR_I_S(
1451 resourcePrimKey, true, statuses, 0, 1, orderByComparator);
1452
1453 if (articles.isEmpty()) {
1454 return null;
1455 }
1456
1457 return articles.get(0);
1458 }
1459
1460
1469 @Override
1470 public JournalArticle getArticle(long id)
1471 throws PortalException, SystemException {
1472
1473 return journalArticlePersistence.findByPrimaryKey(id);
1474 }
1475
1476
1488 @Override
1489 public JournalArticle getArticle(long groupId, String articleId)
1490 throws PortalException, SystemException {
1491
1492
1493
1494
1495 try {
1496 return getLatestArticle(
1497 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
1498 }
1499 catch (NoSuchArticleException nsae) {
1500 return getLatestArticle(
1501 groupId, articleId, WorkflowConstants.STATUS_ANY);
1502 }
1503 }
1504
1505
1517 @Override
1518 public JournalArticle getArticle(
1519 long groupId, String articleId, double version)
1520 throws PortalException, SystemException {
1521
1522 return journalArticlePersistence.findByG_A_V(
1523 groupId, articleId, version);
1524 }
1525
1526
1544 @Override
1545 public JournalArticle getArticle(
1546 long groupId, String className, long classPK)
1547 throws PortalException, SystemException {
1548
1549 long classNameId = PortalUtil.getClassNameId(className);
1550
1551 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
1552 groupId, classNameId, classPK);
1553
1554 if (articles.isEmpty()) {
1555 throw new NoSuchArticleException(
1556 "No approved JournalArticle exists with the key {groupId=" +
1557 groupId + ", className=" + className + ", classPK=" +
1558 classPK + "}");
1559 }
1560
1561 return articles.get(0);
1562 }
1563
1564
1575 @Override
1576 public JournalArticle getArticleByUrlTitle(long groupId, String urlTitle)
1577 throws PortalException, SystemException {
1578
1579
1580
1581
1582 try {
1583 return getLatestArticleByUrlTitle(
1584 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED);
1585 }
1586 catch (NoSuchArticleException nsae) {
1587 return getLatestArticleByUrlTitle(
1588 groupId, urlTitle, WorkflowConstants.STATUS_PENDING);
1589 }
1590 }
1591
1592
1609 @Override
1610 public String getArticleContent(
1611 JournalArticle article, String ddmTemplateKey, String viewMode,
1612 String languageId, ThemeDisplay themeDisplay)
1613 throws PortalException, SystemException {
1614
1615 JournalArticleDisplay articleDisplay = getArticleDisplay(
1616 article, ddmTemplateKey, viewMode, languageId, 1, null,
1617 themeDisplay);
1618
1619 if (articleDisplay == null) {
1620 return StringPool.BLANK;
1621 }
1622 else {
1623 return articleDisplay.getContent();
1624 }
1625 }
1626
1627
1646 @Override
1647 public String getArticleContent(
1648 long groupId, String articleId, double version, String viewMode,
1649 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1650 throws PortalException, SystemException {
1651
1652 JournalArticleDisplay articleDisplay = getArticleDisplay(
1653 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
1654 themeDisplay);
1655
1656 if (articleDisplay == null) {
1657 return StringPool.BLANK;
1658 }
1659 else {
1660 return articleDisplay.getContent();
1661 }
1662 }
1663
1664
1678 @Override
1679 public String getArticleContent(
1680 long groupId, String articleId, double version, String viewMode,
1681 String languageId, ThemeDisplay themeDisplay)
1682 throws PortalException, SystemException {
1683
1684 return getArticleContent(
1685 groupId, articleId, version, viewMode, null, languageId,
1686 themeDisplay);
1687 }
1688
1689
1707 @Override
1708 public String getArticleContent(
1709 long groupId, String articleId, String viewMode,
1710 String ddmTemplateKey, String languageId, ThemeDisplay themeDisplay)
1711 throws PortalException, SystemException {
1712
1713 JournalArticleDisplay articleDisplay = getArticleDisplay(
1714 groupId, articleId, ddmTemplateKey, viewMode, languageId,
1715 themeDisplay);
1716
1717 return articleDisplay.getContent();
1718 }
1719
1720
1733 @Override
1734 public String getArticleContent(
1735 long groupId, String articleId, String viewMode, String languageId,
1736 ThemeDisplay themeDisplay)
1737 throws PortalException, SystemException {
1738
1739 return getArticleContent(
1740 groupId, articleId, viewMode, null, languageId, themeDisplay);
1741 }
1742
1743
1767 @Override
1768 public JournalArticleDisplay getArticleDisplay(
1769 JournalArticle article, String ddmTemplateKey, String viewMode,
1770 String languageId, int page, String xmlRequest,
1771 ThemeDisplay themeDisplay)
1772 throws PortalException, SystemException {
1773
1774 String content = null;
1775
1776 if (page < 1) {
1777 page = 1;
1778 }
1779
1780 int numberOfPages = 1;
1781 boolean paginate = false;
1782 boolean pageFlow = false;
1783
1784 boolean cacheable = true;
1785
1786 if (Validator.isNull(xmlRequest)) {
1787 xmlRequest = "<request />";
1788 }
1789
1790 Map<String, String> tokens = JournalUtil.getTokens(
1791 article.getGroupId(), themeDisplay, xmlRequest);
1792
1793 if ((themeDisplay == null) && xmlRequest.equals("<request />")) {
1794 tokens.put("company_id", String.valueOf(article.getCompanyId()));
1795
1796 Group companyGroup = groupLocalService.getCompanyGroup(
1797 article.getCompanyId());
1798
1799 tokens.put(
1800 "article_group_id", String.valueOf(article.getGroupId()));
1801 tokens.put(
1802 "company_group_id", String.valueOf(companyGroup.getGroupId()));
1803
1804
1805
1806 tokens.put("group_id", String.valueOf(article.getGroupId()));
1807 }
1808
1809 tokens.put(
1810 "article_resource_pk",
1811 String.valueOf(article.getResourcePrimKey()));
1812
1813 String defaultDDMTemplateKey = article.getTemplateId();
1814
1815 if (article.isTemplateDriven()) {
1816 if (Validator.isNull(ddmTemplateKey)) {
1817 ddmTemplateKey = defaultDDMTemplateKey;
1818 }
1819
1820 tokens.put(
1821 TemplateConstants.CLASS_NAME_ID,
1822 String.valueOf(PortalUtil.getClassNameId(DDMStructure.class)));
1823 tokens.put("structure_id", article.getStructureId());
1824 tokens.put("template_id", ddmTemplateKey);
1825 }
1826
1827 String xml = article.getContent();
1828
1829 try {
1830 Document document = null;
1831
1832 Element rootElement = null;
1833
1834 if (article.isTemplateDriven()) {
1835 document = SAXReaderUtil.read(xml);
1836
1837 rootElement = document.getRootElement();
1838
1839 Document requestDocument = SAXReaderUtil.read(xmlRequest);
1840
1841 List<Element> pages = rootElement.elements("page");
1842
1843 if (!pages.isEmpty()) {
1844 pageFlow = true;
1845
1846 String targetPage = requestDocument.valueOf(
1847 "/request/parameters/parameter[name='targetPage']/" +
1848 "value");
1849
1850 Element pageElement = null;
1851
1852 if (Validator.isNotNull(targetPage)) {
1853 targetPage = HtmlUtil.escapeXPathAttribute(targetPage);
1854
1855 XPath xPathSelector = SAXReaderUtil.createXPath(
1856 "/root/page[@id = " + targetPage + "]");
1857
1858 pageElement = (Element)xPathSelector.selectSingleNode(
1859 document);
1860 }
1861
1862 if (pageElement != null) {
1863 document = SAXReaderUtil.createDocument(pageElement);
1864
1865 rootElement = document.getRootElement();
1866
1867 numberOfPages = pages.size();
1868 }
1869 else {
1870 if (page > pages.size()) {
1871 page = 1;
1872 }
1873
1874 pageElement = pages.get(page - 1);
1875
1876 document = SAXReaderUtil.createDocument(pageElement);
1877
1878 rootElement = document.getRootElement();
1879
1880 numberOfPages = pages.size();
1881 paginate = true;
1882 }
1883 }
1884
1885 rootElement.add(requestDocument.getRootElement().createCopy());
1886
1887 JournalUtil.addAllReservedEls(
1888 rootElement, tokens, article, languageId, themeDisplay);
1889
1890 xml = DDMXMLUtil.formatXML(document);
1891 }
1892 }
1893 catch (DocumentException de) {
1894 throw new SystemException(de);
1895 }
1896
1897 try {
1898 if (_log.isDebugEnabled()) {
1899 _log.debug(
1900 "Transforming " + article.getArticleId() + " " +
1901 article.getVersion() + " " + languageId);
1902 }
1903
1904 String script = null;
1905 String langType = null;
1906
1907 if (article.isTemplateDriven()) {
1908
1909
1910
1911
1912
1913
1914
1915 DDMTemplate ddmTemplate = null;
1916
1917 try {
1918 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1919 PortalUtil.getSiteGroupId(article.getGroupId()),
1920 PortalUtil.getClassNameId(DDMStructure.class),
1921 ddmTemplateKey);
1922 }
1923 catch (NoSuchTemplateException nste1) {
1924 try {
1925 Group companyGroup = groupLocalService.getCompanyGroup(
1926 article.getCompanyId());
1927
1928 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1929 companyGroup.getGroupId(),
1930 PortalUtil.getClassNameId(DDMStructure.class),
1931 ddmTemplateKey);
1932
1933 tokens.put(
1934 "company_group_id",
1935 String.valueOf(companyGroup.getGroupId()));
1936 }
1937 catch (NoSuchTemplateException nste2) {
1938 if (!defaultDDMTemplateKey.equals(ddmTemplateKey)) {
1939 ddmTemplate = ddmTemplatePersistence.findByG_C_T(
1940 PortalUtil.getSiteGroupId(article.getGroupId()),
1941 PortalUtil.getClassNameId(DDMStructure.class),
1942 defaultDDMTemplateKey);
1943 }
1944 else {
1945 throw nste1;
1946 }
1947 }
1948 }
1949
1950 script = ddmTemplate.getScript();
1951 langType = ddmTemplate.getLanguage();
1952 cacheable = ddmTemplate.isCacheable();
1953 }
1954
1955 content = JournalUtil.transform(
1956 themeDisplay, tokens, viewMode, languageId, xml, script,
1957 langType);
1958
1959 if (!pageFlow) {
1960 String[] pieces = StringUtil.split(
1961 content, PropsValues.JOURNAL_ARTICLE_TOKEN_PAGE_BREAK);
1962
1963 if (pieces.length > 1) {
1964 if (page > pieces.length) {
1965 page = 1;
1966 }
1967
1968 content = pieces[page - 1];
1969 numberOfPages = pieces.length;
1970 paginate = true;
1971 }
1972 }
1973 }
1974 catch (Exception e) {
1975 throw new SystemException(e);
1976 }
1977
1978 return new JournalArticleDisplayImpl(
1979 article.getCompanyId(), article.getId(),
1980 article.getResourcePrimKey(), article.getGroupId(),
1981 article.getUserId(), article.getArticleId(), article.getVersion(),
1982 article.getTitle(languageId), article.getUrlTitle(),
1983 article.getDescription(languageId),
1984 article.getAvailableLanguageIds(), content, article.getType(),
1985 article.getStructureId(), ddmTemplateKey, article.isSmallImage(),
1986 article.getSmallImageId(), article.getSmallImageURL(),
1987 numberOfPages, page, paginate, cacheable);
1988 }
1989
1990
2017 @Override
2018 public JournalArticleDisplay getArticleDisplay(
2019 long groupId, String articleId, double version,
2020 String ddmTemplateKey, String viewMode, String languageId, int page,
2021 String xmlRequest, ThemeDisplay themeDisplay)
2022 throws PortalException, SystemException {
2023
2024 Date now = new Date();
2025
2026 JournalArticle article = journalArticlePersistence.findByG_A_V(
2027 groupId, articleId, version);
2028
2029 if (article.isExpired()) {
2030 Date expirationDate = article.getExpirationDate();
2031
2032 if ((expirationDate != null) && expirationDate.before(now)) {
2033 return null;
2034 }
2035 }
2036
2037 Date displayDate = article.getDisplayDate();
2038
2039 if (displayDate.after(now)) {
2040 return null;
2041 }
2042
2043 return getArticleDisplay(
2044 article, ddmTemplateKey, viewMode, languageId, page, xmlRequest,
2045 themeDisplay);
2046 }
2047
2048
2072 @Override
2073 public JournalArticleDisplay getArticleDisplay(
2074 long groupId, String articleId, double version,
2075 String ddmTemplateKey, String viewMode, String languageId,
2076 ThemeDisplay themeDisplay)
2077 throws PortalException, SystemException {
2078
2079 return getArticleDisplay(
2080 groupId, articleId, version, ddmTemplateKey, viewMode, languageId,
2081 1, null, themeDisplay);
2082 }
2083
2084
2106 @Override
2107 public JournalArticleDisplay getArticleDisplay(
2108 long groupId, String articleId, String viewMode, String languageId,
2109 int page, String xmlRequest, ThemeDisplay themeDisplay)
2110 throws PortalException, SystemException {
2111
2112 return getArticleDisplay(
2113 groupId, articleId, null, viewMode, languageId, page, xmlRequest,
2114 themeDisplay);
2115 }
2116
2117
2144 @Override
2145 public JournalArticleDisplay getArticleDisplay(
2146 long groupId, String articleId, String ddmTemplateKey,
2147 String viewMode, String languageId, int page, String xmlRequest,
2148 ThemeDisplay themeDisplay)
2149 throws PortalException, SystemException {
2150
2151 JournalArticle article = getDisplayArticle(groupId, articleId);
2152
2153 return getArticleDisplay(
2154 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2155 languageId, page, xmlRequest, themeDisplay);
2156 }
2157
2158
2181 @Override
2182 public JournalArticleDisplay getArticleDisplay(
2183 long groupId, String articleId, String ddmTemplateKey,
2184 String viewMode, String languageId, ThemeDisplay themeDisplay)
2185 throws PortalException, SystemException {
2186
2187 JournalArticle article = getDisplayArticle(groupId, articleId);
2188
2189 return getArticleDisplay(
2190 groupId, articleId, article.getVersion(), ddmTemplateKey, viewMode,
2191 languageId, themeDisplay);
2192 }
2193
2194
2212 @Override
2213 public JournalArticleDisplay getArticleDisplay(
2214 long groupId, String articleId, String viewMode, String languageId,
2215 ThemeDisplay themeDisplay)
2216 throws PortalException, SystemException {
2217
2218 return getArticleDisplay(
2219 groupId, articleId, null, viewMode, languageId, themeDisplay);
2220 }
2221
2222
2228 @Override
2229 public List<JournalArticle> getArticles() throws SystemException {
2230 return journalArticlePersistence.findAll();
2231 }
2232
2233
2240 @Override
2241 public List<JournalArticle> getArticles(long groupId)
2242 throws SystemException {
2243
2244 return journalArticlePersistence.findByGroupId(groupId);
2245 }
2246
2247
2267 @Override
2268 public List<JournalArticle> getArticles(long groupId, int start, int end)
2269 throws SystemException {
2270
2271 return journalArticlePersistence.findByGroupId(groupId, start, end);
2272 }
2273
2274
2297 @Override
2298 public List<JournalArticle> getArticles(
2299 long groupId, int start, int end, OrderByComparator obc)
2300 throws SystemException {
2301
2302 return journalArticlePersistence.findByGroupId(
2303 groupId, start, end, obc);
2304 }
2305
2306
2314 @Override
2315 public List<JournalArticle> getArticles(long groupId, long folderId)
2316 throws SystemException {
2317
2318 return journalArticlePersistence.findByG_F(groupId, folderId);
2319 }
2320
2321
2343 @Override
2344 public List<JournalArticle> getArticles(
2345 long groupId, long folderId, int start, int end)
2346 throws SystemException {
2347
2348 return journalArticlePersistence.findByG_F(
2349 groupId, folderId, start, end);
2350 }
2351
2352 @Override
2353 public List<JournalArticle> getArticles(
2354 long groupId, long folderId, int status, int start, int end)
2355 throws SystemException {
2356
2357 return journalArticlePersistence.findByG_F_ST(
2358 groupId, folderId, status, start, end);
2359 }
2360
2361
2386 @Override
2387 public List<JournalArticle> getArticles(
2388 long groupId, long folderId, int start, int end,
2389 OrderByComparator orderByComparator)
2390 throws SystemException {
2391
2392 return journalArticlePersistence.findByG_F(
2393 groupId, folderId, start, end, orderByComparator);
2394 }
2395
2396
2404 @Override
2405 public List<JournalArticle> getArticles(long groupId, String articleId)
2406 throws SystemException {
2407
2408 return journalArticlePersistence.findByG_A(groupId, articleId);
2409 }
2410
2411 @Override
2412 public List<JournalArticle> getArticlesByResourcePrimKey(
2413 long resourcePrimKey)
2414 throws SystemException {
2415
2416 return journalArticlePersistence.findByResourcePrimKey(resourcePrimKey);
2417 }
2418
2419
2427 @Override
2428 public List<JournalArticle> getArticlesBySmallImageId(long smallImageId)
2429 throws SystemException {
2430
2431 return journalArticlePersistence.findBySmallImageId(smallImageId);
2432 }
2433
2434
2441 @Override
2442 public int getArticlesCount(long groupId) throws SystemException {
2443 return journalArticlePersistence.countByGroupId(groupId);
2444 }
2445
2446
2454 @Override
2455 public int getArticlesCount(long groupId, long folderId)
2456 throws SystemException {
2457
2458 return journalArticlePersistence.countByG_F(groupId, folderId);
2459 }
2460
2461 @Override
2462 public int getArticlesCount(long groupId, long folderId, int status)
2463 throws SystemException {
2464
2465 return journalArticlePersistence.countByG_F_ST(
2466 groupId, folderId, status);
2467 }
2468
2469
2494 @Override
2495 public List<JournalArticle> getCompanyArticles(
2496 long companyId, double version, int status, int start, int end)
2497 throws SystemException {
2498
2499 if (status == WorkflowConstants.STATUS_ANY) {
2500 return journalArticlePersistence.findByC_V(
2501 companyId, version, start, end, new ArticleIDComparator(true));
2502 }
2503 else {
2504 return journalArticlePersistence.findByC_V_ST(
2505 companyId, version, status, start, end,
2506 new ArticleIDComparator(true));
2507 }
2508 }
2509
2510
2534 @Override
2535 public List<JournalArticle> getCompanyArticles(
2536 long companyId, int status, int start, int end)
2537 throws SystemException {
2538
2539 if (status == WorkflowConstants.STATUS_ANY) {
2540 return journalArticlePersistence.findByCompanyId(
2541 companyId, start, end, new ArticleIDComparator(true));
2542 }
2543 else {
2544 return journalArticlePersistence.findByC_ST(
2545 companyId, status, start, end, new ArticleIDComparator(true));
2546 }
2547 }
2548
2549
2574 @Override
2575 public int getCompanyArticlesCount(
2576 long companyId, double version, int status, int start, int end)
2577 throws SystemException {
2578
2579 if (status == WorkflowConstants.STATUS_ANY) {
2580 return journalArticlePersistence.countByC_V(companyId, version);
2581 }
2582 else {
2583 return journalArticlePersistence.countByC_V_ST(
2584 companyId, version, status);
2585 }
2586 }
2587
2588
2599 @Override
2600 public int getCompanyArticlesCount(long companyId, int status)
2601 throws SystemException {
2602
2603 if (status == WorkflowConstants.STATUS_ANY) {
2604 return journalArticlePersistence.countByCompanyId(companyId);
2605 }
2606 else {
2607 return journalArticlePersistence.countByC_ST(companyId, status);
2608 }
2609 }
2610
2611
2624 @Override
2625 public JournalArticle getDisplayArticle(long groupId, String articleId)
2626 throws PortalException, SystemException {
2627
2628 List<JournalArticle> articles = journalArticlePersistence.findByG_A_ST(
2629 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
2630
2631 if (articles.isEmpty()) {
2632 throw new NoSuchArticleException(
2633 "No approved JournalArticle exists with the key {groupId=" +
2634 groupId + ", " + "articleId=" + articleId + "}");
2635 }
2636
2637 Date now = new Date();
2638
2639 for (int i = 0; i < articles.size(); i++) {
2640 JournalArticle article = articles.get(i);
2641
2642 Date displayDate = article.getDisplayDate();
2643 Date expirationDate = article.getExpirationDate();
2644
2645 if (((displayDate == null) || displayDate.before(now)) &&
2646 ((expirationDate == null) || expirationDate.after(now))) {
2647
2648 return article;
2649 }
2650 }
2651
2652 return articles.get(0);
2653 }
2654
2655
2668 @Override
2669 public JournalArticle getDisplayArticleByUrlTitle(
2670 long groupId, String urlTitle)
2671 throws PortalException, SystemException {
2672
2673 List<JournalArticle> articles = null;
2674
2675 OrderByComparator orderByComparator = new ArticleVersionComparator();
2676
2677 articles = journalArticlePersistence.findByG_UT_ST(
2678 groupId, urlTitle, WorkflowConstants.STATUS_APPROVED,
2679 QueryUtil.ALL_POS, QueryUtil.ALL_POS, orderByComparator);
2680
2681 if (articles.isEmpty()) {
2682 throw new NoSuchArticleException(
2683 "No JournalArticle exists with the key {groupId=" + groupId +
2684 ", urlTitle=" + urlTitle + "}");
2685 }
2686
2687 Date now = new Date();
2688
2689 for (JournalArticle article : articles) {
2690 Date displayDate = article.getDisplayDate();
2691 Date expirationDate = article.getExpirationDate();
2692
2693 if (((displayDate != null) && displayDate.before(now)) &&
2694 ((expirationDate == null) || expirationDate.after(now)) ) {
2695
2696 return article;
2697 }
2698 }
2699
2700 return articles.get(0);
2701 }
2702
2703 @Override
2704 public List<JournalArticle> getIndexableArticlesByResourcePrimKey(
2705 long resourcePrimKey)
2706 throws SystemException {
2707
2708 return journalArticlePersistence.findByR_I(resourcePrimKey, true);
2709 }
2710
2711
2722 @Override
2723 public JournalArticle getLatestArticle(long resourcePrimKey)
2724 throws PortalException, SystemException {
2725
2726 return getLatestArticle(resourcePrimKey, WorkflowConstants.STATUS_ANY);
2727 }
2728
2729
2744 @Override
2745 public JournalArticle getLatestArticle(long resourcePrimKey, int status)
2746 throws PortalException, SystemException {
2747
2748 return getLatestArticle(resourcePrimKey, status, true);
2749 }
2750
2751
2771 @Override
2772 public JournalArticle getLatestArticle(
2773 long resourcePrimKey, int status, boolean preferApproved)
2774 throws PortalException, SystemException {
2775
2776 List<JournalArticle> articles = null;
2777
2778 OrderByComparator orderByComparator = new ArticleVersionComparator();
2779
2780 if (status == WorkflowConstants.STATUS_ANY) {
2781 if (preferApproved) {
2782 articles = journalArticlePersistence.findByR_ST(
2783 resourcePrimKey, WorkflowConstants.STATUS_APPROVED, 0, 1,
2784 orderByComparator);
2785 }
2786
2787 if ((articles == null) || (articles.size() == 0)) {
2788 articles = journalArticlePersistence.findByResourcePrimKey(
2789 resourcePrimKey, 0, 1, orderByComparator);
2790 }
2791 }
2792 else {
2793 articles = journalArticlePersistence.findByR_ST(
2794 resourcePrimKey, status, 0, 1, orderByComparator);
2795 }
2796
2797 if (articles.isEmpty()) {
2798 throw new NoSuchArticleException(
2799 "No JournalArticle exists with the key {resourcePrimKey=" +
2800 resourcePrimKey + "}");
2801 }
2802
2803 return articles.get(0);
2804 }
2805
2806
2816 @Override
2817 public JournalArticle getLatestArticle(long groupId, String articleId)
2818 throws PortalException, SystemException {
2819
2820 return getLatestArticle(
2821 groupId, articleId, WorkflowConstants.STATUS_ANY);
2822 }
2823
2824
2838 @Override
2839 public JournalArticle getLatestArticle(
2840 long groupId, String articleId, int status)
2841 throws PortalException, SystemException {
2842
2843 return getFirstArticle(
2844 groupId, articleId, status, new ArticleVersionComparator());
2845 }
2846
2847
2865 @Override
2866 public JournalArticle getLatestArticle(
2867 long groupId, String className, long classPK)
2868 throws PortalException, SystemException {
2869
2870 long classNameId = PortalUtil.getClassNameId(className);
2871
2872 List<JournalArticle> articles = journalArticlePersistence.findByG_C_C(
2873 groupId, classNameId, classPK, 0, 1,
2874 new ArticleVersionComparator());
2875
2876 if (articles.isEmpty()) {
2877 throw new NoSuchArticleException(
2878 "No JournalArticle exists with the key {groupId=" + groupId +
2879 ", className=" + className + ", classPK =" + classPK + "}");
2880 }
2881
2882 return articles.get(0);
2883 }
2884
2885
2899 @Override
2900 public JournalArticle getLatestArticleByUrlTitle(
2901 long groupId, String urlTitle, int status)
2902 throws PortalException, SystemException {
2903
2904 List<JournalArticle> articles = null;
2905
2906 OrderByComparator orderByComparator = new ArticleVersionComparator();
2907
2908 if (status == WorkflowConstants.STATUS_ANY) {
2909 articles = journalArticlePersistence.findByG_UT(
2910 groupId, urlTitle, 0, 1, orderByComparator);
2911 }
2912 else {
2913 articles = journalArticlePersistence.findByG_UT_ST(
2914 groupId, urlTitle, status, 0, 1, orderByComparator);
2915 }
2916
2917 if (articles.isEmpty()) {
2918 throw new NoSuchArticleException(
2919 "No JournalArticle exists with the key {groupId=" + groupId +
2920 ", urlTitle=" + urlTitle + ", status=" + status + "}");
2921 }
2922
2923 return articles.get(0);
2924 }
2925
2926
2937 @Override
2938 public double getLatestVersion(long groupId, String articleId)
2939 throws PortalException, SystemException {
2940
2941 JournalArticle article = getLatestArticle(groupId, articleId);
2942
2943 return article.getVersion();
2944 }
2945
2946
2960 @Override
2961 public double getLatestVersion(long groupId, String articleId, int status)
2962 throws PortalException, SystemException {
2963
2964 JournalArticle article = getLatestArticle(groupId, articleId, status);
2965
2966 return article.getVersion();
2967 }
2968
2969
2977 @Override
2978 public int getNotInTrashArticlesCount(long groupId, long folderId)
2979 throws SystemException {
2980
2981 QueryDefinition queryDefinition = new QueryDefinition(
2982 WorkflowConstants.STATUS_ANY);
2983
2984 List<Long> folderIds = new ArrayList<Long>();
2985
2986 folderIds.add(folderId);
2987
2988 return journalArticleFinder.countByG_F(
2989 groupId, folderIds, queryDefinition);
2990 }
2991
2992 @Override
2993 public JournalArticle getOldestArticle(long groupId, String articleId)
2994 throws PortalException, SystemException {
2995
2996 return getOldestArticle(
2997 groupId, articleId, WorkflowConstants.STATUS_ANY);
2998 }
2999
3000 @Override
3001 public JournalArticle getOldestArticle(
3002 long groupId, String articleId, int status)
3003 throws PortalException, SystemException {
3004
3005 return getFirstArticle(
3006 groupId, articleId, status, new ArticleVersionComparator(false));
3007 }
3008
3009
3019 @Override
3020 public List<JournalArticle> getStructureArticles(
3021 long groupId, String ddmStructureKey)
3022 throws SystemException {
3023
3024 return journalArticlePersistence.findByG_S(groupId, ddmStructureKey);
3025 }
3026
3027
3052 @Override
3053 public List<JournalArticle> getStructureArticles(
3054 long groupId, String ddmStructureKey, int start, int end,
3055 OrderByComparator obc)
3056 throws SystemException {
3057
3058 return journalArticlePersistence.findByG_S(
3059 groupId, ddmStructureKey, start, end, obc);
3060 }
3061
3062 @Override
3063 public List<JournalArticle> getStructureArticles(String[] ddmStructureKeys)
3064 throws SystemException {
3065
3066 return journalArticlePersistence.findByStructureId(ddmStructureKeys);
3067 }
3068
3069
3079 @Override
3080 public int getStructureArticlesCount(long groupId, String ddmStructureKey)
3081 throws SystemException {
3082
3083 return journalArticlePersistence.countByG_S(groupId, ddmStructureKey);
3084 }
3085
3086
3097 @Override
3098 public List<JournalArticle> getTemplateArticles(
3099 long groupId, String ddmTemplateKey)
3100 throws SystemException {
3101
3102 return journalArticlePersistence.findByG_T(groupId, ddmTemplateKey);
3103 }
3104
3105
3132 @Override
3133 public List<JournalArticle> getTemplateArticles(
3134 long groupId, String ddmTemplateKey, int start, int end,
3135 OrderByComparator obc)
3136 throws SystemException {
3137
3138 return journalArticlePersistence.findByG_T(
3139 groupId, ddmTemplateKey, start, end, obc);
3140 }
3141
3142
3154 @Override
3155 public int getTemplateArticlesCount(long groupId, String ddmTemplateKey)
3156 throws SystemException {
3157
3158 return journalArticlePersistence.countByG_T(groupId, ddmTemplateKey);
3159 }
3160
3161 @Override
3162 public String getUniqueUrlTitle(
3163 long groupId, String articleId, String urlTitle)
3164 throws PortalException, SystemException {
3165
3166 for (int i = 1;; i++) {
3167 JournalArticle article = null;
3168
3169 try {
3170 article = getArticleByUrlTitle(groupId, urlTitle);
3171 }
3172 catch (NoSuchArticleException nsae) {
3173 }
3174
3175 if ((article == null) || articleId.equals(article.getArticleId())) {
3176 break;
3177 }
3178 else {
3179 String suffix = StringPool.DASH + i;
3180
3181 String prefix = urlTitle;
3182
3183 if (urlTitle.length() > suffix.length()) {
3184 prefix = urlTitle.substring(
3185 0, urlTitle.length() - suffix.length());
3186 }
3187
3188 urlTitle = prefix + suffix;
3189 }
3190 }
3191
3192 return urlTitle;
3193 }
3194
3195
3204 @Override
3205 public boolean hasArticle(long groupId, String articleId)
3206 throws SystemException {
3207
3208 try {
3209 getArticle(groupId, articleId);
3210
3211 return true;
3212 }
3213 catch (PortalException pe) {
3214 return false;
3215 }
3216 }
3217
3218
3231 @Override
3232 public boolean isLatestVersion(
3233 long groupId, String articleId, double version)
3234 throws PortalException, SystemException {
3235
3236 if (getLatestVersion(groupId, articleId) == version) {
3237 return true;
3238 }
3239 else {
3240 return false;
3241 }
3242 }
3243
3244
3260 @Override
3261 public boolean isLatestVersion(
3262 long groupId, String articleId, double version, int status)
3263 throws PortalException, SystemException {
3264
3265 if (getLatestVersion(groupId, articleId, status) == version) {
3266 return true;
3267 }
3268 else {
3269 return false;
3270 }
3271 }
3272
3273
3286 @Indexable(type = IndexableType.REINDEX)
3287 @Override
3288 public JournalArticle moveArticle(
3289 long groupId, String articleId, long newFolderId)
3290 throws PortalException, SystemException {
3291
3292 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3293 groupId, articleId);
3294
3295 for (JournalArticle article : articles) {
3296 article.setFolderId(newFolderId);
3297 article.setTreePath(article.buildTreePath());
3298
3299 journalArticlePersistence.update(article);
3300 }
3301
3302 return getArticle(groupId, articleId);
3303 }
3304
3305
3328 @Indexable(type = IndexableType.REINDEX)
3329 @Override
3330 public JournalArticle moveArticleFromTrash(
3331 long userId, long groupId, JournalArticle article, long newFolderId,
3332 ServiceContext serviceContext)
3333 throws PortalException, SystemException {
3334
3335 if (article.isInTrashExplicitly()) {
3336 restoreArticleFromTrash(userId, article);
3337 }
3338 else {
3339
3340
3341
3342 TrashEntry trashEntry = article.getTrashEntry();
3343
3344 TrashVersion trashVersion =
3345 trashVersionLocalService.fetchVersion(
3346 trashEntry.getEntryId(), JournalArticle.class.getName(),
3347 article.getResourcePrimKey());
3348
3349 int status = WorkflowConstants.STATUS_APPROVED;
3350
3351 if (trashVersion != null) {
3352 status = trashVersion.getStatus();
3353 }
3354
3355 updateStatus(
3356 userId, article, status, null,
3357 new HashMap<String, Serializable>(), serviceContext);
3358
3359
3360
3361 if (trashVersion != null) {
3362 trashVersionLocalService.deleteTrashVersion(trashVersion);
3363 }
3364 }
3365
3366 return moveArticle(groupId, article.getArticleId(), newFolderId);
3367 }
3368
3369
3382 @Indexable(type = IndexableType.REINDEX)
3383 @Override
3384 public JournalArticle moveArticleToTrash(
3385 long userId, JournalArticle article)
3386 throws PortalException, SystemException {
3387
3388
3389
3390 int oldStatus = article.getStatus();
3391
3392 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3393 article.setStatus(WorkflowConstants.STATUS_DRAFT);
3394
3395 journalArticlePersistence.update(article);
3396 }
3397
3398 List<JournalArticle> articleVersions =
3399 journalArticlePersistence.findByG_A(
3400 article.getGroupId(), article.getArticleId());
3401
3402 articleVersions = ListUtil.sort(
3403 articleVersions, new ArticleVersionComparator());
3404
3405 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
3406 new ArrayList<ObjectValuePair<Long, Integer>>();
3407
3408 if ((articleVersions != null) && !articleVersions.isEmpty()) {
3409 articleVersionStatusOVPs = getArticleVersionStatuses(
3410 articleVersions);
3411 }
3412
3413 article = updateStatus(
3414 userId, article.getId(), WorkflowConstants.STATUS_IN_TRASH,
3415 new HashMap<String, Serializable>(), new ServiceContext());
3416
3417
3418
3419 JournalArticleResource articleResource =
3420 journalArticleResourceLocalService.getArticleResource(
3421 article.getResourcePrimKey());
3422
3423 UnicodeProperties typeSettingsProperties = new UnicodeProperties();
3424
3425 typeSettingsProperties.put("title", article.getArticleId());
3426
3427 TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
3428 userId, article.getGroupId(), JournalArticle.class.getName(),
3429 article.getResourcePrimKey(), articleResource.getUuid(), null,
3430 oldStatus, articleVersionStatusOVPs, typeSettingsProperties);
3431
3432 String trashArticleId = TrashUtil.getTrashTitle(
3433 trashEntry.getEntryId());
3434
3435 for (JournalArticle articleVersion : articleVersions) {
3436 articleVersion.setArticleId(trashArticleId);
3437 articleVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
3438
3439 journalArticlePersistence.update(articleVersion);
3440 }
3441
3442 articleResource.setArticleId(trashArticleId);
3443
3444 journalArticleResourcePersistence.update(articleResource);
3445
3446 article.setArticleId(trashArticleId);
3447
3448 article = journalArticlePersistence.update(article);
3449
3450
3451
3452 assetEntryLocalService.updateVisible(
3453 JournalArticle.class.getName(), article.getResourcePrimKey(),
3454 false);
3455
3456
3457
3458 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3459
3460 extraDataJSONObject.put("title", article.getTitle());
3461
3462 socialActivityLocalService.addActivity(
3463 userId, article.getGroupId(), JournalArticle.class.getName(),
3464 article.getResourcePrimKey(),
3465 SocialActivityConstants.TYPE_MOVE_TO_TRASH,
3466 extraDataJSONObject.toString(), 0);
3467
3468 if (oldStatus == WorkflowConstants.STATUS_PENDING) {
3469 workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
3470 article.getCompanyId(), article.getGroupId(),
3471 JournalArticle.class.getName(), article.getId());
3472 }
3473
3474 return article;
3475 }
3476
3477
3491 @Override
3492 public JournalArticle moveArticleToTrash(
3493 long userId, long groupId, String articleId)
3494 throws PortalException, SystemException {
3495
3496 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
3497 groupId, articleId, 0, 1, new ArticleVersionComparator());
3498
3499 if (!articles.isEmpty()) {
3500 return journalArticleLocalService.moveArticleToTrash(
3501 userId, articles.get(0));
3502 }
3503
3504 return null;
3505 }
3506
3507 @Override
3508 public void rebuildTree(long companyId) throws SystemException {
3509 journalFolderLocalService.rebuildTree(companyId);
3510
3511 Session session = journalArticlePersistence.openSession();
3512
3513 try {
3514 TreePathUtil.rebuildTree(
3515 session, companyId, JournalArticleModelImpl.TABLE_NAME,
3516 JournalFolderModelImpl.TABLE_NAME, "folderId", true);
3517 }
3518 finally {
3519 journalArticlePersistence.closeSession(session);
3520
3521 journalArticlePersistence.clearCache();
3522 }
3523 }
3524
3525
3538 @Indexable(type = IndexableType.REINDEX)
3539 @Override
3540 public JournalArticle removeArticleLocale(
3541 long groupId, String articleId, double version, String languageId)
3542 throws PortalException, SystemException {
3543
3544 JournalArticle article = journalArticlePersistence.findByG_A_V(
3545 groupId, articleId, version);
3546
3547 String title = article.getTitle();
3548
3549 title = LocalizationUtil.removeLocalization(
3550 title, "static-content", languageId, true);
3551
3552 article.setTitle(title);
3553
3554 String description = article.getDescription();
3555
3556 description = LocalizationUtil.removeLocalization(
3557 description, "static-content", languageId, true);
3558
3559 article.setDescription(description);
3560
3561 String content = article.getContent();
3562
3563 if (article.isTemplateDriven()) {
3564 content = JournalUtil.removeArticleLocale(content, languageId);
3565 }
3566 else {
3567 content = LocalizationUtil.removeLocalization(
3568 content, "static-content", languageId, true);
3569 }
3570
3571 article.setContent(content);
3572
3573 journalArticlePersistence.update(article);
3574
3575 return article;
3576 }
3577
3578
3590 @Indexable(type = IndexableType.REINDEX)
3591 @Override
3592 public JournalArticle restoreArticleFromTrash(
3593 long userId, JournalArticle article)
3594 throws PortalException, SystemException {
3595
3596
3597
3598 String trashArticleId = TrashUtil.getOriginalTitle(
3599 article.getArticleId());
3600
3601 List<JournalArticle> articleVersions =
3602 journalArticlePersistence.findByG_A(
3603 article.getGroupId(), article.getArticleId());
3604
3605 for (JournalArticle articleVersion : articleVersions) {
3606 articleVersion.setArticleId(trashArticleId);
3607
3608 journalArticlePersistence.update(articleVersion);
3609 }
3610
3611 article.setArticleId(trashArticleId);
3612
3613 journalArticlePersistence.update(article);
3614
3615 JournalArticleResource articleResource =
3616 journalArticleResourcePersistence.fetchByPrimaryKey(
3617 article.getResourcePrimKey());
3618
3619 articleResource.setArticleId(trashArticleId);
3620
3621 journalArticleResourcePersistence.update(articleResource);
3622
3623 TrashEntry trashEntry = trashEntryLocalService.getEntry(
3624 JournalArticle.class.getName(), article.getResourcePrimKey());
3625
3626 ServiceContext serviceContext = new ServiceContext();
3627
3628 serviceContext.setScopeGroupId(article.getGroupId());
3629
3630 updateStatus(
3631 userId, article, trashEntry.getStatus(), null,
3632 new HashMap<String, Serializable>(), serviceContext);
3633
3634
3635
3636 List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
3637 trashEntry.getEntryId());
3638
3639 for (TrashVersion trashVersion : trashVersions) {
3640 JournalArticle trashArticleVersion =
3641 journalArticlePersistence.findByPrimaryKey(
3642 trashVersion.getClassPK());
3643
3644 trashArticleVersion.setStatus(trashVersion.getStatus());
3645
3646 journalArticlePersistence.update(trashArticleVersion);
3647 }
3648
3649 trashEntryLocalService.deleteEntry(
3650 JournalArticle.class.getName(), article.getResourcePrimKey());
3651
3652
3653
3654 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
3655
3656 extraDataJSONObject.put("title", article.getTitle());
3657
3658 socialActivityLocalService.addActivity(
3659 userId, article.getGroupId(), JournalArticle.class.getName(),
3660 article.getResourcePrimKey(),
3661 SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
3662 extraDataJSONObject.toString(), 0);
3663
3664 return article;
3665 }
3666
3667 @Override
3668 public List<JournalArticle> search(
3669 long groupId, List<Long> folderIds, int status, int start, int end)
3670 throws SystemException {
3671
3672 QueryDefinition queryDefinition = new QueryDefinition(
3673 status, start, end, null);
3674
3675 return journalArticleFinder.findByG_F(
3676 groupId, folderIds, queryDefinition);
3677 }
3678
3679 @Override
3680 public List<JournalArticle> search(
3681 long groupId, long folderId, int status, int start, int end)
3682 throws SystemException {
3683
3684 List<Long> folderIds = new ArrayList<Long>();
3685
3686 folderIds.add(folderId);
3687
3688 return search(groupId, folderIds, status, start, end);
3689 }
3690
3691
3753 @Override
3754 public List<JournalArticle> search(
3755 long companyId, long groupId, List<Long> folderIds,
3756 long classNameId, String keywords, Double version, String type,
3757 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3758 Date displayDateLT, int status, Date reviewDate, int start, int end,
3759 OrderByComparator obc)
3760 throws SystemException {
3761
3762 return journalArticleFinder.findByKeywords(
3763 companyId, groupId, folderIds, classNameId, keywords, version, type,
3764 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
3765 status, reviewDate, start, end, obc);
3766 }
3767
3768
3837 @Override
3838 public List<JournalArticle> search(
3839 long companyId, long groupId, List<Long> folderIds,
3840 long classNameId, String articleId, Double version, String title,
3841 String description, String content, String type,
3842 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
3843 Date displayDateLT, int status, Date reviewDate,
3844 boolean andOperator, int start, int end, OrderByComparator obc)
3845 throws SystemException {
3846
3847 QueryDefinition queryDefinition = new QueryDefinition(
3848 status, start, end, obc);
3849
3850 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3851 companyId, groupId, folderIds, classNameId, articleId, version,
3852 title, description, content, type, ddmStructureKey, ddmTemplateKey,
3853 displayDateGT, displayDateLT, reviewDate, andOperator,
3854 queryDefinition);
3855 }
3856
3857
3923 @Override
3924 public List<JournalArticle> search(
3925 long companyId, long groupId, List<Long> folderIds,
3926 long classNameId, String articleId, Double version, String title,
3927 String description, String content, String type,
3928 String[] ddmStructureKeys, String[] ddmTemplateKeys,
3929 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
3930 boolean andOperator, int start, int end, OrderByComparator obc)
3931 throws SystemException {
3932
3933 QueryDefinition queryDefinition = new QueryDefinition(
3934 status, start, end, obc);
3935
3936 return journalArticleFinder.findByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
3937 companyId, groupId, folderIds, classNameId, articleId, version,
3938 title, description, content, type, ddmStructureKeys,
3939 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
3940 andOperator, queryDefinition);
3941 }
3942
3943
3990 @Override
3991 public Hits search(
3992 long companyId, long groupId, List<Long> folderIds,
3993 long classNameId, String ddmStructureKey, String ddmTemplateKey,
3994 String keywords, LinkedHashMap<String, Object> params, int start,
3995 int end, Sort sort)
3996 throws SystemException {
3997
3998 String articleId = null;
3999 String title = null;
4000 String description = null;
4001 String content = null;
4002 boolean andOperator = false;
4003
4004 if (Validator.isNotNull(keywords)) {
4005 articleId = keywords;
4006 title = keywords;
4007 description = keywords;
4008 content = keywords;
4009 }
4010 else {
4011 andOperator = true;
4012 }
4013
4014 String status = String.valueOf(WorkflowConstants.STATUS_ANY);
4015
4016 if (params != null) {
4017 params.put("keywords", keywords);
4018 }
4019
4020 return search(
4021 companyId, groupId, folderIds, classNameId, articleId, title,
4022 description, content, null, status, ddmStructureKey, ddmTemplateKey,
4023 params, andOperator, start, end, sort);
4024 }
4025
4026
4087 @Override
4088 public Hits search(
4089 long companyId, long groupId, List<Long> folderIds,
4090 long classNameId, String articleId, String title,
4091 String description, String content, String type, String status,
4092 String ddmStructureKey, String ddmTemplateKey,
4093 LinkedHashMap<String, Object> params, boolean andSearch, int start,
4094 int end, Sort sort)
4095 throws SystemException {
4096
4097 try {
4098 SearchContext searchContext = new SearchContext();
4099
4100 searchContext.setAndSearch(andSearch);
4101
4102 Map<String, Serializable> attributes =
4103 new HashMap<String, Serializable>();
4104
4105 attributes.put(Field.CLASS_NAME_ID, classNameId);
4106 attributes.put(Field.CONTENT, content);
4107 attributes.put(Field.DESCRIPTION, description);
4108 attributes.put(Field.STATUS, status);
4109 attributes.put(Field.TITLE, title);
4110 attributes.put(Field.TYPE, type);
4111 attributes.put("articleId", articleId);
4112 attributes.put("ddmStructureKey", ddmStructureKey);
4113 attributes.put("ddmTemplateKey", ddmTemplateKey);
4114 attributes.put("params", params);
4115
4116 searchContext.setAttributes(attributes);
4117
4118 searchContext.setCompanyId(companyId);
4119 searchContext.setEnd(end);
4120 searchContext.setFolderIds(folderIds);
4121 searchContext.setGroupIds(new long[] {groupId});
4122 searchContext.setIncludeDiscussions(
4123 GetterUtil.getBoolean(params.get("includeDiscussions")));
4124
4125 if (params != null) {
4126 String keywords = (String)params.remove("keywords");
4127
4128 if (Validator.isNotNull(keywords)) {
4129 searchContext.setKeywords(keywords);
4130 }
4131 }
4132
4133 QueryConfig queryConfig = new QueryConfig();
4134
4135 queryConfig.setHighlightEnabled(false);
4136 queryConfig.setScoreEnabled(false);
4137
4138 searchContext.setQueryConfig(queryConfig);
4139
4140 if (sort != null) {
4141 searchContext.setSorts(sort);
4142 }
4143
4144 searchContext.setStart(start);
4145
4146 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
4147 JournalArticle.class);
4148
4149 return indexer.search(searchContext);
4150 }
4151 catch (Exception e) {
4152 throw new SystemException(e);
4153 }
4154 }
4155
4156 @Override
4157 public Hits search(
4158 long groupId, long userId, long creatorUserId, int status,
4159 int start, int end)
4160 throws PortalException, SystemException {
4161
4162 Indexer indexer = IndexerRegistryUtil.getIndexer(
4163 JournalArticle.class.getName());
4164
4165 SearchContext searchContext = new SearchContext();
4166
4167 searchContext.setAttribute(Field.STATUS, status);
4168
4169 searchContext.setAttribute("paginationType", "none");
4170
4171 if (creatorUserId > 0) {
4172 searchContext.setAttribute(
4173 Field.USER_ID, String.valueOf(creatorUserId));
4174 }
4175
4176 Group group = groupLocalService.getGroup(groupId);
4177
4178 searchContext.setCompanyId(group.getCompanyId());
4179
4180 searchContext.setEnd(end);
4181 searchContext.setGroupIds(new long[] {groupId});
4182 searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true));
4183 searchContext.setStart(start);
4184 searchContext.setUserId(userId);
4185
4186 return indexer.search(searchContext);
4187 }
4188
4189 @Override
4190 public int searchCount(long groupId, List<Long> folderIds, int status)
4191 throws SystemException {
4192
4193 QueryDefinition queryDefinition = new QueryDefinition(status);
4194
4195 return journalArticleFinder.countByG_F(
4196 groupId, folderIds, queryDefinition);
4197 }
4198
4199 @Override
4200 public int searchCount(long groupId, long folderId, int status)
4201 throws SystemException {
4202
4203 List<Long> folderIds = new ArrayList<Long>();
4204
4205 folderIds.add(folderId);
4206
4207 return searchCount(groupId, folderIds, status);
4208 }
4209
4210
4254 @Override
4255 public int searchCount(
4256 long companyId, long groupId, List<Long> folderIds,
4257 long classNameId, String keywords, Double version, String type,
4258 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4259 Date displayDateLT, int status, Date reviewDate)
4260 throws SystemException {
4261
4262 return journalArticleFinder.countByKeywords(
4263 companyId, groupId, folderIds, classNameId, keywords, version, type,
4264 ddmStructureKey, ddmTemplateKey, displayDateGT, displayDateLT,
4265 status, reviewDate);
4266 }
4267
4268
4318 @Override
4319 public int searchCount(
4320 long companyId, long groupId, List<Long> folderIds,
4321 long classNameId, String articleId, Double version, String title,
4322 String description, String content, String type,
4323 String ddmStructureKey, String ddmTemplateKey, Date displayDateGT,
4324 Date displayDateLT, int status, Date reviewDate,
4325 boolean andOperator)
4326 throws SystemException {
4327
4328 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4329 companyId, groupId, folderIds, classNameId, articleId, version,
4330 title, description, content, type, ddmStructureKey, ddmTemplateKey,
4331 displayDateGT, displayDateLT, reviewDate, andOperator,
4332 new QueryDefinition(status));
4333 }
4334
4335
4385 @Override
4386 public int searchCount(
4387 long companyId, long groupId, List<Long> folderIds,
4388 long classNameId, String articleId, Double version, String title,
4389 String description, String content, String type,
4390 String[] ddmStructureKeys, String[] ddmTemplateKeys,
4391 Date displayDateGT, Date displayDateLT, int status, Date reviewDate,
4392 boolean andOperator)
4393 throws SystemException {
4394
4395 return journalArticleFinder.countByC_G_F_C_A_V_T_D_C_T_S_T_D_R(
4396 companyId, groupId, folderIds, classNameId, articleId, version,
4397 title, description, content, type, ddmStructureKeys,
4398 ddmTemplateKeys, displayDateGT, displayDateLT, reviewDate,
4399 andOperator, new QueryDefinition(status));
4400 }
4401
4402
4412 @Override
4413 public void subscribe(long userId, long groupId)
4414 throws PortalException, SystemException {
4415
4416 subscriptionLocalService.addSubscription(
4417 userId, groupId, JournalArticle.class.getName(), groupId);
4418 }
4419
4420
4430 @Override
4431 public void unsubscribe(long userId, long groupId)
4432 throws PortalException, SystemException {
4433
4434 subscriptionLocalService.deleteSubscription(
4435 userId, JournalArticle.class.getName(), groupId);
4436 }
4437
4438
4472 @Override
4473 public JournalArticle updateArticle(
4474 long userId, long groupId, long folderId, String articleId,
4475 double version, Map<Locale, String> titleMap,
4476 Map<Locale, String> descriptionMap, String content,
4477 String layoutUuid, ServiceContext serviceContext)
4478 throws PortalException, SystemException {
4479
4480 User user = userPersistence.findByPrimaryKey(userId);
4481
4482 JournalArticle article = journalArticlePersistence.findByG_A_V(
4483 groupId, articleId, version);
4484
4485 Date displayDate = article.getDisplayDate();
4486
4487 int displayDateMonth = 0;
4488 int displayDateDay = 0;
4489 int displayDateYear = 0;
4490 int displayDateHour = 0;
4491 int displayDateMinute = 0;
4492
4493 if (displayDate != null) {
4494 Calendar displayCal = CalendarFactoryUtil.getCalendar(
4495 user.getTimeZone());
4496
4497 displayCal.setTime(displayDate);
4498
4499 displayDateMonth = displayCal.get(Calendar.MONTH);
4500 displayDateDay = displayCal.get(Calendar.DATE);
4501 displayDateYear = displayCal.get(Calendar.YEAR);
4502 displayDateHour = displayCal.get(Calendar.HOUR);
4503 displayDateMinute = displayCal.get(Calendar.MINUTE);
4504
4505 if (displayCal.get(Calendar.AM_PM) == Calendar.PM) {
4506 displayDateHour += 12;
4507 }
4508 }
4509
4510 Date expirationDate = article.getExpirationDate();
4511
4512 int expirationDateMonth = 0;
4513 int expirationDateDay = 0;
4514 int expirationDateYear = 0;
4515 int expirationDateHour = 0;
4516 int expirationDateMinute = 0;
4517 boolean neverExpire = true;
4518
4519 if (expirationDate != null) {
4520 Calendar expirationCal = CalendarFactoryUtil.getCalendar(
4521 user.getTimeZone());
4522
4523 expirationCal.setTime(expirationDate);
4524
4525 expirationDateMonth = expirationCal.get(Calendar.MONTH);
4526 expirationDateDay = expirationCal.get(Calendar.DATE);
4527 expirationDateYear = expirationCal.get(Calendar.YEAR);
4528 expirationDateHour = expirationCal.get(Calendar.HOUR);
4529 expirationDateMinute = expirationCal.get(Calendar.MINUTE);
4530 neverExpire = false;
4531
4532 if (expirationCal.get(Calendar.AM_PM) == Calendar.PM) {
4533 expirationDateHour += 12;
4534 }
4535 }
4536
4537 Date reviewDate = article.getReviewDate();
4538
4539 int reviewDateMonth = 0;
4540 int reviewDateDay = 0;
4541 int reviewDateYear = 0;
4542 int reviewDateHour = 0;
4543 int reviewDateMinute = 0;
4544 boolean neverReview = true;
4545
4546 if (reviewDate != null) {
4547 Calendar reviewCal = CalendarFactoryUtil.getCalendar(
4548 user.getTimeZone());
4549
4550 reviewCal.setTime(reviewDate);
4551
4552 reviewDateMonth = reviewCal.get(Calendar.MONTH);
4553 reviewDateDay = reviewCal.get(Calendar.DATE);
4554 reviewDateYear = reviewCal.get(Calendar.YEAR);
4555 reviewDateHour = reviewCal.get(Calendar.HOUR);
4556 reviewDateMinute = reviewCal.get(Calendar.MINUTE);
4557 neverReview = false;
4558
4559 if (reviewCal.get(Calendar.AM_PM) == Calendar.PM) {
4560 reviewDateHour += 12;
4561 }
4562 }
4563
4564 return journalArticleLocalService.updateArticle(
4565 userId, groupId, folderId, articleId, version, titleMap,
4566 descriptionMap, content, article.getType(),
4567 article.getStructureId(), article.getTemplateId(), layoutUuid,
4568 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
4569 displayDateMinute, expirationDateMonth, expirationDateDay,
4570 expirationDateYear, expirationDateHour, expirationDateMinute,
4571 neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
4572 reviewDateHour, reviewDateMinute, neverReview,
4573 article.getIndexable(), article.isSmallImage(),
4574 article.getSmallImageURL(), null, null, null, serviceContext);
4575 }
4576
4577
4664 @Indexable(type = IndexableType.REINDEX)
4665 @Override
4666 public JournalArticle updateArticle(
4667 long userId, long groupId, long folderId, String articleId,
4668 double version, Map<Locale, String> titleMap,
4669 Map<Locale, String> descriptionMap, String content, String type,
4670 String ddmStructureKey, String ddmTemplateKey, String layoutUuid,
4671 int displayDateMonth, int displayDateDay, int displayDateYear,
4672 int displayDateHour, int displayDateMinute, int expirationDateMonth,
4673 int expirationDateDay, int expirationDateYear,
4674 int expirationDateHour, int expirationDateMinute,
4675 boolean neverExpire, int reviewDateMonth, int reviewDateDay,
4676 int reviewDateYear, int reviewDateHour, int reviewDateMinute,
4677 boolean neverReview, boolean indexable, boolean smallImage,
4678 String smallImageURL, File smallImageFile,
4679 Map<String, byte[]> images, String articleURL,
4680 ServiceContext serviceContext)
4681 throws PortalException, SystemException {
4682
4683
4684
4685 User user = userPersistence.findByPrimaryKey(userId);
4686 articleId = StringUtil.toUpperCase(articleId.trim());
4687
4688 byte[] smallImageBytes = null;
4689
4690 try {
4691 smallImageBytes = FileUtil.getBytes(smallImageFile);
4692 }
4693 catch (IOException ioe) {
4694 }
4695
4696 JournalArticle latestArticle = getLatestArticle(
4697 groupId, articleId, WorkflowConstants.STATUS_ANY);
4698
4699 JournalArticle article = latestArticle;
4700
4701 boolean imported = ExportImportThreadLocal.isImportInProcess();
4702
4703 double latestVersion = latestArticle.getVersion();
4704
4705 boolean addNewVersion = false;
4706
4707 if (imported) {
4708 if (latestVersion > version) {
4709 JournalArticle existingArticle =
4710 journalArticlePersistence.fetchByG_A_V(
4711 groupId, articleId, version);
4712
4713 if (existingArticle != null) {
4714 article = existingArticle;
4715 }
4716 else {
4717 addNewVersion = true;
4718 }
4719 }
4720 else if (latestVersion < version) {
4721 addNewVersion = true;
4722 }
4723 }
4724 else {
4725 if ((version > 0) && (version != latestVersion)) {
4726 throw new ArticleVersionException();
4727 }
4728
4729 serviceContext.validateModifiedDate(
4730 latestArticle, ArticleVersionException.class);
4731
4732 if (latestArticle.isApproved() || latestArticle.isExpired() ||
4733 latestArticle.isScheduled()) {
4734
4735 addNewVersion = true;
4736
4737 version = MathUtil.format(latestVersion + 0.1, 1, 1);
4738 }
4739 }
4740
4741 Date displayDate = null;
4742 Date expirationDate = null;
4743 Date reviewDate = null;
4744
4745 if (article.getClassNameId() ==
4746 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
4747
4748 displayDate = PortalUtil.getDate(
4749 displayDateMonth, displayDateDay, displayDateYear,
4750 displayDateHour, displayDateMinute, user.getTimeZone(),
4751 ArticleDisplayDateException.class);
4752
4753 if (!neverExpire) {
4754 expirationDate = PortalUtil.getDate(
4755 expirationDateMonth, expirationDateDay, expirationDateYear,
4756 expirationDateHour, expirationDateMinute,
4757 user.getTimeZone(), ArticleExpirationDateException.class);
4758 }
4759
4760 if (!neverReview) {
4761 reviewDate = PortalUtil.getDate(
4762 reviewDateMonth, reviewDateDay, reviewDateYear,
4763 reviewDateHour, reviewDateMinute, user.getTimeZone(),
4764 ArticleReviewDateException.class);
4765 }
4766 }
4767
4768 Date now = new Date();
4769
4770 boolean expired = false;
4771
4772 if ((expirationDate != null) && expirationDate.before(now)) {
4773 expired = true;
4774 }
4775
4776 validate(
4777 user.getCompanyId(), groupId, latestArticle.getClassNameId(),
4778 titleMap, content, type, ddmStructureKey, ddmTemplateKey,
4779 expirationDate, smallImage, smallImageURL, smallImageFile,
4780 smallImageBytes, serviceContext);
4781
4782 if (addNewVersion) {
4783 long id = counterLocalService.increment();
4784
4785 article = journalArticlePersistence.create(id);
4786
4787 article.setResourcePrimKey(latestArticle.getResourcePrimKey());
4788 article.setGroupId(latestArticle.getGroupId());
4789 article.setCompanyId(latestArticle.getCompanyId());
4790 article.setUserId(user.getUserId());
4791 article.setUserName(user.getFullName());
4792 article.setCreateDate(latestArticle.getCreateDate());
4793 article.setClassNameId(latestArticle.getClassNameId());
4794 article.setClassPK(latestArticle.getClassPK());
4795 article.setArticleId(articleId);
4796 article.setVersion(version);
4797 article.setSmallImageId(latestArticle.getSmallImageId());
4798 }
4799
4800 Locale locale = getArticleDefaultLocale(content, serviceContext);
4801
4802 String title = titleMap.get(locale);
4803
4804 content = format(
4805 user, groupId, articleId, article.getVersion(), addNewVersion,
4806 content, ddmStructureKey, images);
4807
4808 article.setModifiedDate(serviceContext.getModifiedDate(now));
4809 article.setFolderId(folderId);
4810 article.setTreePath(article.buildTreePath());
4811 article.setTitleMap(titleMap, locale);
4812 article.setUrlTitle(
4813 getUniqueUrlTitle(
4814 article.getId(), article.getArticleId(), title,
4815 latestArticle.getUrlTitle(), serviceContext));
4816 article.setDescriptionMap(descriptionMap, locale);
4817 article.setContent(content);
4818 article.setType(type);
4819 article.setStructureId(ddmStructureKey);
4820 article.setTemplateId(ddmTemplateKey);
4821 article.setLayoutUuid(layoutUuid);
4822 article.setDisplayDate(displayDate);
4823 article.setExpirationDate(expirationDate);
4824 article.setReviewDate(reviewDate);
4825 article.setIndexable(indexable);
4826 article.setSmallImage(smallImage);
4827
4828 if (smallImage) {
4829 if ((smallImageFile != null) && (smallImageBytes != null)) {
4830 article.setSmallImageId(counterLocalService.increment());
4831 }
4832 }
4833 else {
4834 article.setSmallImageId(0);
4835 }
4836
4837 article.setSmallImageURL(smallImageURL);
4838
4839 if (latestArticle.isPending()) {
4840 article.setStatus(latestArticle.getStatus());
4841 }
4842 else if (!expired) {
4843 article.setStatus(WorkflowConstants.STATUS_DRAFT);
4844 }
4845 else {
4846 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
4847 }
4848
4849 article.setExpandoBridgeAttributes(serviceContext);
4850
4851 journalArticlePersistence.update(article);
4852
4853
4854
4855 updateAsset(
4856 userId, article, serviceContext.getAssetCategoryIds(),
4857 serviceContext.getAssetTagNames(),
4858 serviceContext.getAssetLinkEntryIds());
4859
4860
4861
4862 if (PortalUtil.getClassNameId(DDMStructure.class) ==
4863 article.getClassNameId()) {
4864
4865 updateDDMStructureXSD(
4866 article.getClassPK(), content, serviceContext);
4867 }
4868
4869
4870
4871 saveImages(
4872 smallImage, article.getSmallImageId(), smallImageFile,
4873 smallImageBytes);
4874
4875
4876
4877 PortletPreferences preferences =
4878 ServiceContextUtil.getPortletPreferences(serviceContext);
4879
4880
4881
4882 if (expired && imported) {
4883 updateStatus(
4884 userId, article, article.getStatus(), articleURL,
4885 new HashMap<String, Serializable>(), serviceContext);
4886 }
4887
4888 if (serviceContext.getWorkflowAction() ==
4889 WorkflowConstants.ACTION_PUBLISH) {
4890
4891 articleURL = buildArticleURL(
4892 articleURL, groupId, folderId, articleId);
4893
4894 serviceContext.setAttribute("articleURL", articleURL);
4895
4896 sendEmail(
4897 article, articleURL, preferences, "requested", serviceContext);
4898
4899 WorkflowHandlerRegistryUtil.startWorkflowInstance(
4900 user.getCompanyId(), groupId, userId,
4901 JournalArticle.class.getName(), article.getId(), article,
4902 serviceContext);
4903 }
4904
4905 return journalArticlePersistence.findByPrimaryKey(article.getId());
4906 }
4907
4908
4937 @Override
4938 public JournalArticle updateArticle(
4939 long userId, long groupId, long folderId, String articleId,
4940 double version, String content, ServiceContext serviceContext)
4941 throws PortalException, SystemException {
4942
4943 JournalArticle article = journalArticlePersistence.findByG_A_V(
4944 groupId, articleId, version);
4945
4946 return journalArticleLocalService.updateArticle(
4947 userId, groupId, folderId, articleId, version,
4948 article.getTitleMap(), article.getDescriptionMap(), content,
4949 article.getLayoutUuid(), serviceContext);
4950 }
4951
4952
4957 @Override
4958 public JournalArticle updateArticleTranslation(
4959 long groupId, String articleId, double version, Locale locale,
4960 String title, String description, String content,
4961 Map<String, byte[]> images)
4962 throws PortalException, SystemException {
4963
4964 return journalArticleLocalService.updateArticleTranslation(
4965 groupId, articleId, version, locale, title, description, content,
4966 images, null);
4967 }
4968
4969
4991 @Indexable(type = IndexableType.REINDEX)
4992 @Override
4993 public JournalArticle updateArticleTranslation(
4994 long groupId, String articleId, double version, Locale locale,
4995 String title, String description, String content,
4996 Map<String, byte[]> images, ServiceContext serviceContext)
4997 throws PortalException, SystemException {
4998
4999 validateContent(content);
5000
5001 JournalArticle oldArticle = getLatestArticle(
5002 groupId, articleId, WorkflowConstants.STATUS_ANY);
5003
5004 double oldVersion = oldArticle.getVersion();
5005
5006 if ((version > 0) && (version != oldVersion)) {
5007 throw new ArticleVersionException();
5008 }
5009
5010 boolean incrementVersion = false;
5011
5012 if (oldArticle.isApproved() || oldArticle.isExpired()) {
5013 incrementVersion = true;
5014 }
5015
5016 if (serviceContext != null) {
5017 serviceContext.validateModifiedDate(
5018 oldArticle, ArticleVersionException.class);
5019 }
5020
5021 JournalArticle article = null;
5022
5023 User user = userPersistence.fetchByPrimaryKey(
5024 serviceContext.getUserId());
5025
5026 if (user == null) {
5027 user = userPersistence.fetchByC_U(
5028 oldArticle.getCompanyId(), oldArticle.getUserId());
5029
5030 if (user == null) {
5031 user = userPersistence.fetchByC_DU(
5032 oldArticle.getCompanyId(), true);
5033 }
5034 }
5035
5036 Locale defaultLocale = getArticleDefaultLocale(content, serviceContext);
5037
5038 if (incrementVersion) {
5039 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
5040
5041 long id = counterLocalService.increment();
5042
5043 article = journalArticlePersistence.create(id);
5044
5045 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
5046 article.setGroupId(oldArticle.getGroupId());
5047 article.setCompanyId(oldArticle.getCompanyId());
5048 article.setUserId(user.getUserId());
5049 article.setUserName(user.getFullName());
5050 article.setCreateDate(new Date());
5051 article.setModifiedDate(new Date());
5052 article.setClassNameId(oldArticle.getClassNameId());
5053 article.setClassPK(oldArticle.getClassPK());
5054 article.setArticleId(articleId);
5055 article.setVersion(newVersion);
5056 article.setTitleMap(oldArticle.getTitleMap(), defaultLocale);
5057 article.setUrlTitle(
5058 getUniqueUrlTitle(
5059 id, articleId, title, oldArticle.getUrlTitle(),
5060 serviceContext));
5061 article.setDescriptionMap(oldArticle.getDescriptionMap());
5062 article.setType(oldArticle.getType());
5063 article.setStructureId(oldArticle.getStructureId());
5064 article.setTemplateId(oldArticle.getTemplateId());
5065 article.setLayoutUuid(oldArticle.getLayoutUuid());
5066 article.setDisplayDate(oldArticle.getDisplayDate());
5067 article.setExpirationDate(oldArticle.getExpirationDate());
5068 article.setReviewDate(oldArticle.getReviewDate());
5069 article.setIndexable(oldArticle.getIndexable());
5070 article.setSmallImage(oldArticle.getSmallImage());
5071 article.setSmallImageId(oldArticle.getSmallImageId());
5072
5073 if (article.getSmallImageId() == 0) {
5074 article.setSmallImageId(counterLocalService.increment());
5075 }
5076
5077 article.setSmallImageURL(oldArticle.getSmallImageURL());
5078
5079 article.setStatus(WorkflowConstants.STATUS_DRAFT);
5080 article.setStatusDate(new Date());
5081 article.setExpandoBridgeAttributes(oldArticle);
5082 }
5083 else {
5084 article = oldArticle;
5085 }
5086
5087 Map<Locale, String> titleMap = article.getTitleMap();
5088
5089 titleMap.put(locale, title);
5090
5091 article.setTitleMap(titleMap, defaultLocale);
5092
5093 Map<Locale, String> descriptionMap = article.getDescriptionMap();
5094
5095 descriptionMap.put(locale, description);
5096
5097 article.setDescriptionMap(descriptionMap);
5098
5099 content = format(
5100 user, groupId, articleId, article.getVersion(),
5101 !oldArticle.isDraft(), content, oldArticle.getStructureId(),
5102 images);
5103
5104 article.setContent(content);
5105
5106 journalArticlePersistence.update(article);
5107
5108 return article;
5109 }
5110
5111
5124 @Override
5125 public void updateAsset(
5126 long userId, JournalArticle article, long[] assetCategoryIds,
5127 String[] assetTagNames, long[] assetLinkEntryIds)
5128 throws PortalException, SystemException {
5129
5130 boolean visible = article.isApproved();
5131
5132 if (article.getClassNameId() !=
5133 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5134
5135 visible = false;
5136 }
5137
5138 boolean addDraftAssetEntry = false;
5139
5140 if (!article.isApproved() &&
5141 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
5142
5143 int approvedArticlesCount = journalArticlePersistence.countByG_A_ST(
5144 article.getGroupId(), article.getArticleId(),
5145 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
5146
5147 if (approvedArticlesCount > 0) {
5148 addDraftAssetEntry = true;
5149 }
5150 }
5151
5152 AssetEntry assetEntry = null;
5153
5154 if (addDraftAssetEntry) {
5155 assetEntry = assetEntryLocalService.updateEntry(
5156 userId, article.getGroupId(), article.getCreateDate(),
5157 article.getModifiedDate(), JournalArticle.class.getName(),
5158 article.getPrimaryKey(), article.getUuid(),
5159 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
5160 null, null, null, ContentTypes.TEXT_HTML, article.getTitle(),
5161 article.getDescription(), article.getDescription(), null,
5162 article.getLayoutUuid(), 0, 0, null, false);
5163 }
5164 else {
5165 JournalArticleResource journalArticleResource =
5166 journalArticleResourceLocalService.getArticleResource(
5167 article.getResourcePrimKey());
5168
5169 assetEntry = assetEntryLocalService.updateEntry(
5170 userId, article.getGroupId(), article.getCreateDate(),
5171 article.getModifiedDate(), JournalArticle.class.getName(),
5172 journalArticleResource.getResourcePrimKey(),
5173 journalArticleResource.getUuid(), getClassTypeId(article),
5174 assetCategoryIds, assetTagNames, visible, null, null, null,
5175 ContentTypes.TEXT_HTML, article.getTitle(),
5176 article.getDescription(), article.getDescription(), null,
5177 article.getLayoutUuid(), 0, 0, null, false);
5178 }
5179
5180 assetLinkLocalService.updateLinks(
5181 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5182 AssetLinkConstants.TYPE_RELATED);
5183 }
5184
5185
5200 @Indexable(type = IndexableType.REINDEX)
5201 @Override
5202 public JournalArticle updateContent(
5203 long groupId, String articleId, double version, String content)
5204 throws PortalException, SystemException {
5205
5206 JournalArticle article = journalArticlePersistence.findByG_A_V(
5207 groupId, articleId, version);
5208
5209 article.setContent(content);
5210
5211 journalArticlePersistence.update(article);
5212
5213 return article;
5214 }
5215
5216
5239 @Indexable(type = IndexableType.REINDEX)
5240 @Override
5241 public JournalArticle updateStatus(
5242 long userId, JournalArticle article, int status, String articleURL,
5243 Map<String, Serializable> workflowContext,
5244 ServiceContext serviceContext)
5245 throws PortalException, SystemException {
5246
5247
5248
5249 User user = userPersistence.findByPrimaryKey(userId);
5250 Date now = new Date();
5251
5252 if ((status == WorkflowConstants.STATUS_APPROVED) &&
5253 (article.getClassNameId() ==
5254 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5255 (article.getDisplayDate() != null) &&
5256 now.before(article.getDisplayDate())) {
5257
5258 status = WorkflowConstants.STATUS_SCHEDULED;
5259 }
5260
5261 int oldStatus = article.getStatus();
5262
5263 if (status == WorkflowConstants.STATUS_APPROVED) {
5264 Date expirationDate = article.getExpirationDate();
5265
5266 if ((expirationDate != null) && expirationDate.before(now)) {
5267 article.setExpirationDate(null);
5268 }
5269 }
5270
5271 if (status == WorkflowConstants.STATUS_EXPIRED) {
5272 article.setExpirationDate(now);
5273 }
5274
5275 article.setStatus(status);
5276 article.setStatusByUserId(user.getUserId());
5277 article.setStatusByUserName(user.getFullName());
5278 article.setStatusDate(serviceContext.getModifiedDate(now));
5279
5280 journalArticlePersistence.update(article);
5281
5282 if (hasModifiedLatestApprovedVersion(
5283 article.getGroupId(), article.getArticleId(),
5284 article.getVersion())) {
5285
5286 if (status == WorkflowConstants.STATUS_APPROVED) {
5287 updateUrlTitles(
5288 article.getGroupId(), article.getArticleId(),
5289 article.getUrlTitle());
5290
5291
5292
5293 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
5294 (article.getVersion() !=
5295 JournalArticleConstants.VERSION_DEFAULT)) {
5296
5297 AssetEntry draftAssetEntry =
5298 assetEntryLocalService.fetchEntry(
5299 JournalArticle.class.getName(),
5300 article.getPrimaryKey());
5301
5302 if (draftAssetEntry != null) {
5303 long[] assetCategoryIds =
5304 draftAssetEntry.getCategoryIds();
5305 String[] assetTagNames = draftAssetEntry.getTagNames();
5306
5307 List<AssetLink> assetLinks =
5308 assetLinkLocalService.getDirectLinks(
5309 draftAssetEntry.getEntryId(),
5310 AssetLinkConstants.TYPE_RELATED);
5311
5312 long[] assetLinkEntryIds = StringUtil.split(
5313 ListUtil.toString(
5314 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
5315
5316 AssetEntry assetEntry =
5317 assetEntryLocalService.updateEntry(
5318 userId, article.getGroupId(),
5319 article.getCreateDate(),
5320 article.getModifiedDate(),
5321 JournalArticle.class.getName(),
5322 article.getResourcePrimKey(), article.getUuid(),
5323 getClassTypeId(article), assetCategoryIds,
5324 assetTagNames, false, null, null, null,
5325 ContentTypes.TEXT_HTML, article.getTitle(),
5326 article.getDescription(),
5327 article.getDescription(), null,
5328 article.getLayoutUuid(), 0, 0, null, false);
5329
5330 assetLinkLocalService.updateLinks(
5331 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5332 AssetLinkConstants.TYPE_RELATED);
5333
5334 SystemEventHierarchyEntryThreadLocal.push(
5335 JournalArticle.class);
5336
5337 try {
5338 assetEntryLocalService.deleteEntry(
5339 JournalArticle.class.getName(),
5340 article.getPrimaryKey());
5341 }
5342 finally {
5343 SystemEventHierarchyEntryThreadLocal.pop(
5344 JournalArticle.class);
5345 }
5346 }
5347 }
5348
5349 if (article.getClassNameId() ==
5350 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5351
5352 assetEntryLocalService.updateEntry(
5353 JournalArticle.class.getName(),
5354 article.getResourcePrimKey(), article.getDisplayDate(),
5355 article.getExpirationDate(), true);
5356 }
5357
5358
5359
5360 JSONObject extraDataJSONObject =
5361 JSONFactoryUtil.createJSONObject();
5362
5363 extraDataJSONObject.put("title", article.getTitle());
5364
5365 if (serviceContext.isCommandUpdate()) {
5366 socialActivityLocalService.addActivity(
5367 user.getUserId(), article.getGroupId(),
5368 JournalArticle.class.getName(),
5369 article.getResourcePrimKey(),
5370 JournalActivityKeys.UPDATE_ARTICLE,
5371 extraDataJSONObject.toString(), 0);
5372 }
5373 else {
5374 socialActivityLocalService.addUniqueActivity(
5375 user.getUserId(), article.getGroupId(),
5376 JournalArticle.class.getName(),
5377 article.getResourcePrimKey(),
5378 JournalActivityKeys.ADD_ARTICLE,
5379 extraDataJSONObject.toString(), 0);
5380 }
5381 }
5382 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
5383 updatePreviousApprovedArticle(article);
5384 }
5385 }
5386
5387 if ((article.getClassNameId() ==
5388 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5389 (oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
5390 (status != WorkflowConstants.STATUS_IN_TRASH)) {
5391
5392
5393
5394 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
5395 ((status == WorkflowConstants.STATUS_APPROVED) ||
5396 (status == WorkflowConstants.STATUS_DENIED))) {
5397
5398 String msg = "granted";
5399
5400 if (status == WorkflowConstants.STATUS_DENIED) {
5401 msg = "denied";
5402 }
5403
5404 try {
5405 PortletPreferences preferences =
5406 ServiceContextUtil.getPortletPreferences(
5407 serviceContext);
5408
5409 articleURL = buildArticleURL(
5410 articleURL, article.getGroupId(), article.getFolderId(),
5411 article.getArticleId());
5412
5413 sendEmail(
5414 article, articleURL, preferences, msg, serviceContext);
5415 }
5416 catch (Exception e) {
5417 _log.error(
5418 "Unable to send email to notify the change of status " +
5419 " to " + msg + " for article " + article.getId() +
5420 ": " + e.getMessage());
5421 }
5422 }
5423
5424
5425
5426 notifySubscribers(article, serviceContext);
5427 }
5428
5429 return article;
5430 }
5431
5432
5453 @Override
5454 public JournalArticle updateStatus(
5455 long userId, long classPK, int status,
5456 Map<String, Serializable> workflowContext,
5457 ServiceContext serviceContext)
5458 throws PortalException, SystemException {
5459
5460 JournalArticle article = getArticle(classPK);
5461
5462 return journalArticleLocalService.updateStatus(
5463 userId, article, status, null, workflowContext, serviceContext);
5464 }
5465
5466
5488 @Override
5489 public JournalArticle updateStatus(
5490 long userId, long groupId, String articleId, double version,
5491 int status, String articleURL,
5492 Map<String, Serializable> workflowContext,
5493 ServiceContext serviceContext)
5494 throws PortalException, SystemException {
5495
5496 JournalArticle article = journalArticlePersistence.findByG_A_V(
5497 groupId, articleId, version);
5498
5499 return journalArticleLocalService.updateStatus(
5500 userId, article, status, articleURL, workflowContext,
5501 serviceContext);
5502 }
5503
5504
5519 @Override
5520 public void updateTemplateId(
5521 long groupId, long classNameId, String oldDDMTemplateKey,
5522 String newDDMTemplateKey)
5523 throws SystemException {
5524
5525 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
5526 groupId, classNameId, oldDDMTemplateKey);
5527
5528 for (JournalArticle article : articles) {
5529 article.setTemplateId(newDDMTemplateKey);
5530
5531 journalArticlePersistence.update(article);
5532 }
5533 }
5534
5535 protected String buildArticleURL(
5536 String articleURL, long groupId, long folderId, String articleId) {
5537
5538 StringBundler sb = new StringBundler(13);
5539
5540 sb.append(articleURL);
5541 sb.append(StringPool.AMPERSAND);
5542 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5543 sb.append("groupId=");
5544 sb.append(groupId);
5545 sb.append(StringPool.AMPERSAND);
5546 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5547 sb.append("folderId=");
5548 sb.append(folderId);
5549 sb.append(StringPool.AMPERSAND);
5550 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5551 sb.append("articleId=");
5552 sb.append(articleId);
5553
5554 return sb.toString();
5555 }
5556
5557 protected void checkArticlesByDisplayDate(Date displayDate)
5558 throws PortalException, SystemException {
5559
5560 List<JournalArticle> articles = journalArticlePersistence.findByLtD_S(
5561 displayDate, WorkflowConstants.STATUS_SCHEDULED);
5562
5563 for (JournalArticle article : articles) {
5564 ServiceContext serviceContext = new ServiceContext();
5565
5566 serviceContext.setCommand(Constants.UPDATE);
5567
5568 String layoutFullURL = PortalUtil.getLayoutFullURL(
5569 article.getGroupId(), PortletKeys.JOURNAL);
5570
5571 serviceContext.setLayoutFullURL(layoutFullURL);
5572
5573 serviceContext.setScopeGroupId(article.getGroupId());
5574
5575 journalArticleLocalService.updateStatus(
5576 article.getUserId(), article, WorkflowConstants.STATUS_APPROVED,
5577 null, new HashMap<String, Serializable>(), serviceContext);
5578 }
5579 }
5580
5581 protected void checkArticlesByExpirationDate(Date expirationDate)
5582 throws PortalException, SystemException {
5583
5584 List<JournalArticle> articles =
5585 journalArticleFinder.findByExpirationDate(
5586 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
5587 new Date(
5588 expirationDate.getTime() + _JOURNAL_ARTICLE_CHECK_INTERVAL),
5589 new QueryDefinition(WorkflowConstants.STATUS_APPROVED));
5590
5591 if (_log.isDebugEnabled()) {
5592 _log.debug("Expiring " + articles.size() + " articles");
5593 }
5594
5595 Set<Long> companyIds = new HashSet<Long>();
5596
5597 for (JournalArticle article : articles) {
5598 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
5599 List<JournalArticle> currentArticles =
5600 journalArticlePersistence.findByG_A(
5601 article.getGroupId(), article.getArticleId(),
5602 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
5603 new ArticleVersionComparator(true));
5604
5605 for (JournalArticle currentArticle : currentArticles) {
5606 currentArticle.setExpirationDate(
5607 article.getExpirationDate());
5608 currentArticle.setStatus(WorkflowConstants.STATUS_EXPIRED);
5609
5610 journalArticlePersistence.update(currentArticle);
5611 }
5612 }
5613 else {
5614 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5615
5616 journalArticlePersistence.update(article);
5617 }
5618
5619 updatePreviousApprovedArticle(article);
5620
5621 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5622 JournalArticle.class);
5623
5624 indexer.reindex(article);
5625
5626 JournalContentUtil.clearCache(
5627 article.getGroupId(), article.getArticleId(),
5628 article.getTemplateId());
5629
5630 companyIds.add(article.getCompanyId());
5631 }
5632
5633 for (long companyId : companyIds) {
5634 CacheUtil.clearCache(companyId);
5635 }
5636
5637 if (_previousCheckDate == null) {
5638 _previousCheckDate = new Date(
5639 expirationDate.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL);
5640 }
5641 }
5642
5643 protected void checkArticlesByReviewDate(Date reviewDate)
5644 throws PortalException, SystemException {
5645
5646 List<JournalArticle> latestArticles = new ArrayList<JournalArticle>();
5647
5648 List<JournalArticle> articles = journalArticleFinder.findByReviewDate(
5649 JournalArticleConstants.CLASSNAME_ID_DEFAULT, reviewDate,
5650 _previousCheckDate);
5651
5652 for (JournalArticle article : articles) {
5653 long groupId = article.getGroupId();
5654 String articleId = article.getArticleId();
5655 double version = article.getVersion();
5656
5657 if (!journalArticleLocalService.isLatestVersion(
5658 groupId, articleId, version)) {
5659
5660 article = journalArticleLocalService.getLatestArticle(
5661 groupId, articleId);
5662 }
5663
5664 if (!latestArticles.contains(article)) {
5665 if (_log.isDebugEnabled()) {
5666 _log.debug(
5667 "Sending review notification for article " +
5668 article.getId());
5669 }
5670
5671 latestArticles.add(article);
5672
5673 String articleURL = StringPool.BLANK;
5674
5675 long ownerId = article.getGroupId();
5676 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
5677 long plid = PortletKeys.PREFS_PLID_SHARED;
5678 String portletId = PortletKeys.JOURNAL;
5679
5680 PortletPreferences preferences =
5681 portletPreferencesLocalService.getPreferences(
5682 article.getCompanyId(), ownerId, ownerType, plid,
5683 portletId);
5684
5685 sendEmail(
5686 article, articleURL, preferences, "review",
5687 new ServiceContext());
5688 }
5689 }
5690 }
5691
5692 protected void checkStructure(Document contentDoc, Element root)
5693 throws PortalException {
5694
5695 for (Element el : root.elements()) {
5696 checkStructureField(el, contentDoc);
5697
5698 checkStructure(contentDoc, el);
5699 }
5700 }
5701
5702 protected void checkStructure(JournalArticle article)
5703 throws PortalException, SystemException {
5704
5705 Group companyGroup = groupLocalService.getCompanyGroup(
5706 article.getCompanyId());
5707
5708 DDMStructure structure = null;
5709
5710 try {
5711 structure = ddmStructurePersistence.findByG_C_S(
5712 PortalUtil.getSiteGroupId(article.getGroupId()),
5713 PortalUtil.getClassNameId(JournalArticle.class),
5714 article.getStructureId());
5715 }
5716 catch (NoSuchStructureException nsse) {
5717 structure = ddmStructurePersistence.findByG_C_S(
5718 companyGroup.getGroupId(),
5719 PortalUtil.getClassNameId(JournalArticle.class),
5720 article.getStructureId());
5721 }
5722
5723 String content = GetterUtil.getString(article.getContent());
5724
5725 try {
5726 Document contentDocument = SAXReaderUtil.read(content);
5727 Document xsdDocument = SAXReaderUtil.read(structure.getXsd());
5728
5729 checkStructure(contentDocument, xsdDocument.getRootElement());
5730 }
5731 catch (DocumentException de) {
5732 throw new SystemException(de);
5733 }
5734 catch (StructureXsdException sxsde) {
5735 long groupId = article.getGroupId();
5736 String articleId = article.getArticleId();
5737 double version = article.getVersion();
5738
5739 if (_log.isWarnEnabled()) {
5740 _log.warn(
5741 "Article {groupId=" + groupId + ", articleId=" +
5742 articleId + ", version=" + version +
5743 "} has content that does not match its " +
5744 "structure: " + sxsde.getMessage());
5745 }
5746 }
5747 }
5748
5749 protected void checkStructureField(Element el, Document contentDoc)
5750 throws PortalException {
5751
5752 StringBuilder elPath = new StringBuilder();
5753
5754 elPath.append(el.attributeValue("name"));
5755
5756 Element elParent = el.getParent();
5757
5758 while (true) {
5759 if ((elParent == null) || elParent.getName().equals("root")) {
5760 break;
5761 }
5762
5763 elPath.insert(
5764 0, elParent.attributeValue("name") + StringPool.COMMA);
5765
5766 elParent = elParent.getParent();
5767 }
5768
5769 String[] elPathNames = StringUtil.split(elPath.toString());
5770
5771 Element contentEl = contentDoc.getRootElement();
5772
5773 for (String _elPathName : elPathNames) {
5774 boolean foundEl = false;
5775
5776 for (Element tempEl : contentEl.elements()) {
5777 if (_elPathName.equals(
5778 tempEl.attributeValue("name", StringPool.BLANK))) {
5779
5780 contentEl = tempEl;
5781 foundEl = true;
5782
5783 break;
5784 }
5785 }
5786
5787 if (!foundEl) {
5788 String elType = contentEl.attributeValue(
5789 "type", StringPool.BLANK);
5790
5791 if (!elType.equals("list") && !elType.equals("multi-list")) {
5792 throw new StructureXsdException(elPath.toString());
5793 }
5794
5795 break;
5796 }
5797 }
5798 }
5799
5800 protected void copyArticleImages(
5801 JournalArticle oldArticle, JournalArticle newArticle)
5802 throws Exception {
5803
5804 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
5805
5806 XPath xPathSelector = SAXReaderUtil.createXPath(
5807 "
5808
5809 List<Node> imageNodes = xPathSelector.selectNodes(contentDoc);
5810
5811 for (Node imageNode : imageNodes) {
5812 Element imageEl = (Element)imageNode;
5813
5814 String elInstanceId = imageEl.attributeValue("instance-id");
5815 String elName = imageEl.attributeValue("name");
5816 String elIndex = imageEl.attributeValue("index");
5817
5818 String name = elName + StringPool.UNDERLINE + elIndex;
5819
5820 List<Element> dynamicContentEls = imageEl.elements(
5821 "dynamic-content");
5822
5823 for (Element dynamicContentEl : dynamicContentEls) {
5824 long imageId = GetterUtil.getLong(
5825 dynamicContentEl.attributeValue("id"));
5826 String languageId = dynamicContentEl.attributeValue(
5827 "language-id");
5828
5829 Image oldImage = null;
5830
5831 try {
5832 oldImage = imageLocalService.getImage(imageId);
5833 }
5834 catch (NoSuchImageException nsie) {
5835 continue;
5836 }
5837
5838 imageId = journalArticleImageLocalService.getArticleImageId(
5839 newArticle.getGroupId(), newArticle.getArticleId(),
5840 newArticle.getVersion(), elInstanceId, name, languageId);
5841
5842 imageLocalService.updateImage(imageId, oldImage.getTextObj());
5843
5844 String elContent =
5845 "/image/journal/article?img_id=" + imageId + "&t=" +
5846 WebServerServletTokenUtil.getToken(imageId);
5847
5848 dynamicContentEl.setText(elContent);
5849 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
5850 }
5851 }
5852
5853 newArticle.setContent(contentDoc.formattedString());
5854 }
5855
5856 protected void format(
5857 User user, long groupId, String articleId, double version,
5858 boolean incrementVersion, Element root, Map<String, byte[]> images)
5859 throws PortalException, SystemException {
5860
5861 for (Element element : root.elements()) {
5862 String elInstanceId = element.attributeValue(
5863 "instance-id", StringPool.BLANK);
5864 String elType = element.attributeValue("type", StringPool.BLANK);
5865
5866 if (elType.equals("image")) {
5867 String elName = element.attributeValue(
5868 "name", StringPool.BLANK);
5869 String elIndex = element.attributeValue(
5870 "index", StringPool.BLANK);
5871
5872 String name = elName + StringPool.UNDERLINE + elIndex;
5873
5874 formatImage(
5875 groupId, articleId, version, incrementVersion, element,
5876 elInstanceId, name, images);
5877 }
5878 else if (elType.equals("text_area") || elType.equals("text") ||
5879 elType.equals("text_box")) {
5880
5881 List<Element> dynamicContentElements = element.elements(
5882 "dynamic-content");
5883
5884 for (Element dynamicContentElement : dynamicContentElements) {
5885 String dynamicContent = dynamicContentElement.getText();
5886
5887 if (Validator.isNotNull(dynamicContent)) {
5888 String contentType = ContentTypes.TEXT_PLAIN;
5889
5890 if (elType.equals("text_area")) {
5891 contentType = ContentTypes.TEXT_HTML;
5892 }
5893
5894 dynamicContent = SanitizerUtil.sanitize(
5895 user.getCompanyId(), groupId, user.getUserId(),
5896 JournalArticle.class.getName(), 0, contentType,
5897 dynamicContent);
5898
5899 dynamicContentElement.clearContent();
5900
5901 dynamicContentElement.addCDATA(dynamicContent);
5902 }
5903 }
5904 }
5905
5906 format(
5907 user, groupId, articleId, version, incrementVersion, element,
5908 images);
5909 }
5910 }
5911
5912 protected String format(
5913 User user, long groupId, String articleId, double version,
5914 boolean incrementVersion, String content, String ddmStructureKey,
5915 Map<String, byte[]> images)
5916 throws PortalException, SystemException {
5917
5918 Document document = null;
5919
5920 try {
5921 document = SAXReaderUtil.read(content);
5922
5923 Element rootElement = document.getRootElement();
5924
5925 if (Validator.isNotNull(ddmStructureKey)) {
5926 format(
5927 user, groupId, articleId, version, incrementVersion,
5928 rootElement, images);
5929 }
5930 else {
5931 List<Element> staticContentElements = rootElement.elements(
5932 "static-content");
5933
5934 for (Element staticContentElement : staticContentElements) {
5935 String staticContent = staticContentElement.getText();
5936
5937 staticContent = SanitizerUtil.sanitize(
5938 user.getCompanyId(), groupId, user.getUserId(),
5939 JournalArticle.class.getName(), 0,
5940 ContentTypes.TEXT_HTML, staticContent);
5941
5942 staticContentElement.clearContent();
5943
5944 staticContentElement.addCDATA(staticContent);
5945 }
5946 }
5947
5948 content = DDMXMLUtil.formatXML(document);
5949 }
5950 catch (DocumentException de) {
5951 _log.error(de, de);
5952 }
5953
5954 return content;
5955 }
5956
5957 protected void formatImage(
5958 long groupId, String articleId, double version,
5959 boolean incrementVersion, Element el, String elInstanceId,
5960 String elName, Map<String, byte[]> images)
5961 throws PortalException, SystemException {
5962
5963 List<Element> imageContents = el.elements("dynamic-content");
5964
5965 for (Element dynamicContent : imageContents) {
5966 String elLanguage = dynamicContent.attributeValue(
5967 "language-id", StringPool.BLANK);
5968
5969 if (!elLanguage.equals(StringPool.BLANK)) {
5970 elLanguage = "_" + elLanguage;
5971 }
5972
5973 long imageId = journalArticleImageLocalService.getArticleImageId(
5974 groupId, articleId, version, elInstanceId, elName, elLanguage);
5975
5976 if (dynamicContent.getText().equals("delete") ||
5977 Validator.isNull(dynamicContent.getText())) {
5978
5979 dynamicContent.setText(StringPool.BLANK);
5980
5981 imageLocalService.deleteImage(imageId);
5982
5983 String defaultElLanguage = "";
5984
5985 if (Validator.isNull(elLanguage)) {
5986 defaultElLanguage =
5987 "_" +
5988 LocaleUtil.toLanguageId(
5989 LocaleUtil.getSiteDefault());
5990 }
5991
5992 long defaultImageId =
5993 journalArticleImageLocalService.getArticleImageId(
5994 groupId, articleId, version, elInstanceId, elName,
5995 defaultElLanguage);
5996
5997 imageLocalService.deleteImage(defaultImageId);
5998
5999 continue;
6000 }
6001
6002 String elContent =
6003 "/image/journal/article?img_id=" + imageId + "&t=" +
6004 WebServerServletTokenUtil.getToken(imageId);
6005
6006 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
6007
6008 if (ArrayUtil.isNotEmpty(bytes)) {
6009 dynamicContent.setText(elContent);
6010 dynamicContent.addAttribute("id", String.valueOf(imageId));
6011
6012 imageLocalService.updateImage(imageId, bytes);
6013
6014 continue;
6015 }
6016
6017 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
6018 incrementVersion) {
6019
6020 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
6021
6022 long oldImageId = 0;
6023
6024 if ((oldVersion >= 1) && incrementVersion) {
6025 oldImageId =
6026 journalArticleImageLocalService.getArticleImageId(
6027 groupId, articleId, oldVersion, elInstanceId,
6028 elName, elLanguage);
6029 }
6030
6031 Image oldImage = null;
6032
6033 if (oldImageId > 0) {
6034 oldImage = imageLocalService.getImage(oldImageId);
6035 }
6036
6037 if (oldImage != null) {
6038 dynamicContent.setText(elContent);
6039 dynamicContent.addAttribute("id", String.valueOf(imageId));
6040
6041 bytes = oldImage.getTextObj();
6042
6043 imageLocalService.updateImage(imageId, bytes);
6044 }
6045 else if (dynamicContent.getText().equals("update")) {
6046 dynamicContent.setText(StringPool.BLANK);
6047 }
6048
6049 continue;
6050 }
6051
6052 Image image = imageLocalService.getImage(imageId);
6053
6054 if (image != null) {
6055 dynamicContent.setText(elContent);
6056 dynamicContent.addAttribute("id", String.valueOf(imageId));
6057
6058 continue;
6059 }
6060 else if (dynamicContent.getText().equals("update")) {
6061 dynamicContent.setText(StringPool.BLANK);
6062
6063 continue;
6064 }
6065
6066 long contentImageId = GetterUtil.getLong(
6067 HttpUtil.getParameter(dynamicContent.getText(), "img_id"));
6068
6069 if (contentImageId <= 0) {
6070 contentImageId = GetterUtil.getLong(
6071 HttpUtil.getParameter(
6072 dynamicContent.getText(), "img_id", false));
6073 }
6074
6075 if (contentImageId > 0) {
6076 image = imageLocalService.getImage(contentImageId);
6077
6078 if (image != null) {
6079 dynamicContent.addAttribute(
6080 "id", String.valueOf(contentImageId));
6081
6082 continue;
6083 }
6084 }
6085
6086 String defaultElLanguage = "";
6087
6088 if (Validator.isNull(elLanguage)) {
6089 defaultElLanguage =
6090 "_" + LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
6091 }
6092
6093 long defaultImageId =
6094 journalArticleImageLocalService.getArticleImageId(
6095 groupId, articleId, version, elInstanceId, elName,
6096 defaultElLanguage);
6097
6098 Image defaultImage = imageLocalService.getImage(defaultImageId);
6099
6100 if (defaultImage != null) {
6101 dynamicContent.setText(elContent);
6102 dynamicContent.addAttribute(
6103 "id", String.valueOf(defaultImageId));
6104
6105 bytes = defaultImage.getTextObj();
6106
6107 imageLocalService.updateImage(defaultImageId, bytes);
6108
6109 continue;
6110 }
6111
6112 if (Validator.isNotNull(elLanguage)) {
6113 dynamicContent.setText(StringPool.BLANK);
6114 }
6115 }
6116 }
6117
6118 protected Locale getArticleDefaultLocale(
6119 String content, ServiceContext serviceContext) {
6120
6121 String defaultLanguageId = ParamUtil.getString(
6122 serviceContext, "defaultLanguageId");
6123
6124 if (Validator.isNull(defaultLanguageId)) {
6125 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
6126 }
6127
6128 if (Validator.isNotNull(defaultLanguageId)) {
6129 return LocaleUtil.fromLanguageId(defaultLanguageId);
6130 }
6131
6132 return LocaleUtil.getSiteDefault();
6133 }
6134
6135 protected List<ObjectValuePair<Long, Integer>> getArticleVersionStatuses(
6136 List<JournalArticle> articles) {
6137
6138 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
6139 new ArrayList<ObjectValuePair<Long, Integer>>(articles.size());
6140
6141 for (JournalArticle article : articles) {
6142 int status = article.getStatus();
6143
6144 if (status == WorkflowConstants.STATUS_PENDING) {
6145 status = WorkflowConstants.STATUS_DRAFT;
6146 }
6147
6148 ObjectValuePair<Long, Integer> articleVersionStatusOVP =
6149 new ObjectValuePair<Long, Integer>(article.getId(), status);
6150
6151 articleVersionStatusOVPs.add(articleVersionStatusOVP);
6152 }
6153
6154 return articleVersionStatusOVPs;
6155 }
6156
6157 protected long getClassTypeId(JournalArticle article) {
6158 long classTypeId = 0;
6159
6160 try {
6161 long classNameId = PortalUtil.getClassNameId(JournalArticle.class);
6162
6163 DDMStructure ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6164 article.getGroupId(), classNameId, article.getStructureId());
6165
6166 if (ddmStructure == null) {
6167 Group companyGroup = groupLocalService.getCompanyGroup(
6168 article.getCompanyId());
6169
6170 ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6171 companyGroup.getGroupId(), classNameId,
6172 article.getStructureId());
6173 }
6174
6175 if (ddmStructure != null) {
6176 classTypeId = ddmStructure.getStructureId();
6177 }
6178 }
6179 catch (Exception e) {
6180 _log.error(e, e);
6181 }
6182
6183 return classTypeId;
6184 }
6185
6186 protected JournalArticle getFirstArticle(
6187 long groupId, String articleId, int status,
6188 OrderByComparator orderByComparator)
6189 throws PortalException, SystemException {
6190
6191 if (status == WorkflowConstants.STATUS_ANY) {
6192 return journalArticlePersistence.findByG_A_NotST_First(
6193 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH,
6194 orderByComparator);
6195 }
6196 else {
6197 return journalArticlePersistence.findByG_A_ST_First(
6198 groupId, articleId, status, orderByComparator);
6199 }
6200 }
6201
6202 protected String getUniqueUrlTitle(
6203 long id, long groupId, String articleId, String title)
6204 throws PortalException, SystemException {
6205
6206 String urlTitle = JournalUtil.getUrlTitle(id, title);
6207
6208 return getUniqueUrlTitle(groupId, articleId, urlTitle);
6209 }
6210
6211 protected String getUniqueUrlTitle(
6212 long id, String articleId, String title, String oldUrlTitle,
6213 ServiceContext serviceContext)
6214 throws PortalException, SystemException {
6215
6216 String serviceContextUrlTitle = ParamUtil.getString(
6217 serviceContext, "urlTitle");
6218
6219 String urlTitle = null;
6220
6221 if (Validator.isNotNull(serviceContextUrlTitle)) {
6222 urlTitle = JournalUtil.getUrlTitle(id, serviceContextUrlTitle);
6223 }
6224 else if (Validator.isNotNull(oldUrlTitle)) {
6225 return oldUrlTitle;
6226 }
6227 else {
6228 urlTitle = getUniqueUrlTitle(
6229 id, serviceContext.getScopeGroupId(), articleId, title);
6230 }
6231
6232 JournalArticle urlTitleArticle = null;
6233
6234 try {
6235 urlTitleArticle = getArticleByUrlTitle(
6236 serviceContext.getScopeGroupId(), urlTitle);
6237 }
6238 catch (NoSuchArticleException nsae) {
6239 }
6240
6241 if ((urlTitleArticle != null) &&
6242 !Validator.equals(
6243 urlTitleArticle.getArticleId(), articleId)) {
6244
6245 urlTitle = getUniqueUrlTitle(
6246 id, serviceContext.getScopeGroupId(), articleId, urlTitle);
6247 }
6248
6249 return urlTitle;
6250 }
6251
6252 protected boolean hasModifiedLatestApprovedVersion(
6253 long groupId, String articleId, double version)
6254 throws PortalException, SystemException {
6255
6256 double latestApprovedVersion;
6257
6258 try {
6259 latestApprovedVersion = getLatestVersion(
6260 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6261
6262 if (version >= latestApprovedVersion) {
6263 return true;
6264 }
6265 else {
6266 return false;
6267 }
6268 }
6269 catch (NoSuchArticleException nsae) {
6270 return true;
6271 }
6272 }
6273
6274 protected void notifySubscribers(
6275 JournalArticle article, ServiceContext serviceContext)
6276 throws PortalException, SystemException {
6277
6278 if (!article.isApproved()) {
6279 return;
6280 }
6281
6282 String articleURL = PortalUtil.getControlPanelFullURL(
6283 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
6284
6285 if (Validator.isNull(articleURL)) {
6286 return;
6287 }
6288
6289 articleURL = buildArticleURL(
6290 articleURL, article.getGroupId(), article.getFolderId(),
6291 article.getArticleId());
6292
6293 PortletPreferences preferences =
6294 ServiceContextUtil.getPortletPreferences(serviceContext);
6295
6296 if (preferences == null) {
6297 long ownerId = article.getGroupId();
6298 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
6299 long plid = PortletKeys.PREFS_PLID_SHARED;
6300 String portletId = PortletKeys.JOURNAL;
6301 String defaultPreferences = null;
6302
6303 preferences = portletPreferencesLocalService.getPreferences(
6304 article.getCompanyId(), ownerId, ownerType, plid, portletId,
6305 defaultPreferences);
6306 }
6307
6308 if ((article.getVersion() == 1.0) &&
6309 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
6310 }
6311 else if ((article.getVersion() != 1.0) &&
6312 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
6313 }
6314 else {
6315 return;
6316 }
6317
6318 String fromName = JournalUtil.getEmailFromName(
6319 preferences, article.getCompanyId());
6320 String fromAddress = JournalUtil.getEmailFromAddress(
6321 preferences, article.getCompanyId());
6322
6323 String subject = null;
6324 String body = null;
6325
6326 if (article.getVersion() == 1.0) {
6327 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
6328 body = JournalUtil.getEmailArticleAddedBody(preferences);
6329 }
6330 else {
6331 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
6332 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
6333 }
6334
6335 SubscriptionSender subscriptionSender = new SubscriptionSender();
6336
6337 subscriptionSender.setBody(body);
6338 subscriptionSender.setCompanyId(article.getCompanyId());
6339 subscriptionSender.setContextAttributes(
6340 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6341 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6342 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
6343 subscriptionSender.setContextUserPrefix("ARTICLE");
6344 subscriptionSender.setFrom(fromAddress, fromName);
6345 subscriptionSender.setHtmlFormat(true);
6346 subscriptionSender.setMailId("journal_article", article.getId());
6347 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6348 subscriptionSender.setReplyToAddress(fromAddress);
6349 subscriptionSender.setScopeGroupId(article.getGroupId());
6350 subscriptionSender.setServiceContext(serviceContext);
6351 subscriptionSender.setSubject(subject);
6352 subscriptionSender.setUserId(article.getUserId());
6353
6354 subscriptionSender.addPersistedSubscribers(
6355 JournalArticle.class.getName(), article.getResourcePrimKey());
6356
6357 JournalFolder folder = article.getFolder();
6358
6359 List<Long> folderIds = new ArrayList<Long>();
6360
6361 if (folder != null) {
6362 folderIds.add(folder.getFolderId());
6363
6364 folderIds.addAll(folder.getAncestorFolderIds());
6365 }
6366
6367 for (long curFolderId : folderIds) {
6368 subscriptionSender.addPersistedSubscribers(
6369 JournalFolder.class.getName(), curFolderId);
6370 }
6371
6372 subscriptionSender.addPersistedSubscribers(
6373 JournalArticle.class.getName(), article.getGroupId());
6374
6375 subscriptionSender.flushNotificationsAsync();
6376 }
6377
6378 protected void saveImages(
6379 boolean smallImage, long smallImageId, File smallImageFile,
6380 byte[] smallImageBytes)
6381 throws PortalException, SystemException {
6382
6383 if (smallImage) {
6384 if ((smallImageFile != null) && (smallImageBytes != null)) {
6385 imageLocalService.updateImage(smallImageId, smallImageBytes);
6386 }
6387 }
6388 else {
6389 imageLocalService.deleteImage(smallImageId);
6390 }
6391 }
6392
6393 protected void sendEmail(
6394 JournalArticle article, String articleURL,
6395 PortletPreferences preferences, String emailType,
6396 ServiceContext serviceContext)
6397 throws PortalException, SystemException {
6398
6399 if (preferences == null) {
6400 return;
6401 }
6402 else if (emailType.equals("denied") &&
6403 JournalUtil.getEmailArticleApprovalDeniedEnabled(
6404 preferences)) {
6405 }
6406 else if (emailType.equals("granted") &&
6407 JournalUtil.getEmailArticleApprovalGrantedEnabled(
6408 preferences)) {
6409 }
6410 else if (emailType.equals("requested") &&
6411 JournalUtil.getEmailArticleApprovalRequestedEnabled(
6412 preferences)) {
6413 }
6414 else if (emailType.equals("review") &&
6415 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
6416 }
6417 else {
6418 return;
6419 }
6420
6421 Company company = companyPersistence.findByPrimaryKey(
6422 article.getCompanyId());
6423
6424 User user = userPersistence.findByPrimaryKey(article.getUserId());
6425
6426 String fromName = JournalUtil.getEmailFromName(
6427 preferences, article.getCompanyId());
6428 String fromAddress = JournalUtil.getEmailFromAddress(
6429 preferences, article.getCompanyId());
6430
6431 String toName = user.getFullName();
6432 String toAddress = user.getEmailAddress();
6433
6434 if (emailType.equals("requested")) {
6435 String tempToName = fromName;
6436 String tempToAddress = fromAddress;
6437
6438 fromName = toName;
6439 fromAddress = toAddress;
6440
6441 toName = tempToName;
6442 toAddress = tempToAddress;
6443 }
6444
6445 String subject = null;
6446 String body = null;
6447
6448 if (emailType.equals("denied")) {
6449 subject = JournalUtil.getEmailArticleApprovalDeniedSubject(
6450 preferences);
6451 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
6452 }
6453 else if (emailType.equals("granted")) {
6454 subject = JournalUtil.getEmailArticleApprovalGrantedSubject(
6455 preferences);
6456 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
6457 }
6458 else if (emailType.equals("requested")) {
6459 subject = JournalUtil.getEmailArticleApprovalRequestedSubject(
6460 preferences);
6461 body = JournalUtil.getEmailArticleApprovalRequestedBody(
6462 preferences);
6463 }
6464 else if (emailType.equals("review")) {
6465 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
6466 body = JournalUtil.getEmailArticleReviewBody(preferences);
6467 }
6468
6469 SubscriptionSender subscriptionSender = new SubscriptionSender();
6470
6471 subscriptionSender.setBody(body);
6472 subscriptionSender.setCompanyId(company.getCompanyId());
6473 subscriptionSender.setContextAttributes(
6474 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6475 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6476 articleURL, "[$ARTICLE_USER_NAME$]", article.getUserName(),
6477 "[$ARTICLE_VERSION$]", article.getVersion());
6478 subscriptionSender.setContextUserPrefix("ARTICLE");
6479 subscriptionSender.setFrom(fromAddress, fromName);
6480 subscriptionSender.setHtmlFormat(true);
6481 subscriptionSender.setMailId("journal_article", article.getId());
6482 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6483 subscriptionSender.setScopeGroupId(article.getGroupId());
6484 subscriptionSender.setServiceContext(serviceContext);
6485 subscriptionSender.setSubject(subject);
6486 subscriptionSender.setUserId(article.getUserId());
6487
6488 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
6489
6490 subscriptionSender.flushNotificationsAsync();
6491 }
6492
6493 protected void updateDDMStructureXSD(
6494 long ddmStructureId, String content, ServiceContext serviceContext)
6495 throws PortalException, SystemException {
6496
6497 try {
6498 DDMStructure ddmStructure =
6499 ddmStructureLocalService.fetchDDMStructure(ddmStructureId);
6500
6501 if (ddmStructure == null) {
6502 return;
6503 }
6504
6505 Document documentXSD = SAXReaderUtil.read(ddmStructure.getXsd());
6506
6507 Document document = SAXReaderUtil.read(content);
6508
6509 Element rootElement = document.getRootElement();
6510
6511 List<Element> elements = rootElement.elements();
6512
6513 for (Element element : elements) {
6514 String fieldName = element.attributeValue(
6515 "name", StringPool.BLANK);
6516
6517 List<Element> dynamicContentElements = element.elements(
6518 "dynamic-content");
6519
6520 for (Element dynamicContentElement : dynamicContentElements) {
6521 String value = dynamicContentElement.getText();
6522
6523 documentXSD = updateDDMStructureXSDFieldMetadata(
6524 documentXSD, fieldName, FieldConstants.PREDEFINED_VALUE,
6525 value);
6526 }
6527 }
6528
6529 ddmStructureLocalService.updateXSD(
6530 ddmStructureId, documentXSD.asXML(), serviceContext);
6531 }
6532 catch (DocumentException de) {
6533 throw new SystemException(de);
6534 }
6535 }
6536
6537 protected Document updateDDMStructureXSDFieldMetadata(
6538 Document document, String fieldName, String metadataEntryName,
6539 String metadataEntryValue)
6540 throws DocumentException {
6541
6542 Element rootElement = document.getRootElement();
6543
6544 List<Element> dynamicElementElements = rootElement.elements(
6545 "dynamic-element");
6546
6547 for (Element dynamicElementElement : dynamicElementElements) {
6548 String dynamicElementElementFieldName = GetterUtil.getString(
6549 dynamicElementElement.attributeValue("name"));
6550
6551 if (!dynamicElementElementFieldName.equals(fieldName)) {
6552 continue;
6553 }
6554
6555 List<Element> metadataElements = dynamicElementElement.elements(
6556 "meta-data");
6557
6558 for (Element metadataElement : metadataElements) {
6559 List<Element> metadataEntryElements =
6560 metadataElement.elements();
6561
6562 for (Element metadataEntryElement : metadataEntryElements) {
6563 String metadataEntryElementName = GetterUtil.getString(
6564 metadataEntryElement.attributeValue("name"));
6565
6566 if (metadataEntryElementName.equals(metadataEntryName)) {
6567 metadataEntryElement.setText(metadataEntryValue);
6568 }
6569 }
6570 }
6571 }
6572
6573 return document;
6574 }
6575
6576 protected void updatePreviousApprovedArticle(JournalArticle article)
6577 throws PortalException, SystemException {
6578
6579 List<JournalArticle> approvedArticles =
6580 journalArticlePersistence.findByG_A_ST(
6581 article.getGroupId(), article.getArticleId(),
6582 WorkflowConstants.STATUS_APPROVED, 0, 2);
6583
6584 if (approvedArticles.isEmpty() ||
6585 ((approvedArticles.size() == 1) &&
6586 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
6587
6588 assetEntryLocalService.updateVisible(
6589 JournalArticle.class.getName(), article.getResourcePrimKey(),
6590 false);
6591 }
6592 else {
6593 JournalArticle previousApprovedArticle = approvedArticles.get(0);
6594
6595 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
6596 previousApprovedArticle = approvedArticles.get(1);
6597 }
6598
6599 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
6600 JournalArticle.class.getName(), article.getResourcePrimKey(),
6601 previousApprovedArticle.getDisplayDate(),
6602 previousApprovedArticle.getExpirationDate(), true);
6603
6604 assetEntry.setModifiedDate(
6605 previousApprovedArticle.getModifiedDate());
6606 assetEntry.setTitle(previousApprovedArticle.getTitle());
6607
6608 assetEntryPersistence.update(assetEntry);
6609 }
6610 }
6611
6612 protected void updateUrlTitles(
6613 long groupId, String articleId, String urlTitle)
6614 throws PortalException, SystemException {
6615
6616 JournalArticle firstArticle = journalArticlePersistence.findByG_A_First(
6617 groupId, articleId, new ArticleVersionComparator(false));
6618
6619 if (firstArticle.getUrlTitle().equals(urlTitle)) {
6620 return;
6621 }
6622
6623 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
6624 groupId, articleId);
6625
6626 for (JournalArticle article : articles) {
6627 if (!article.getUrlTitle().equals(urlTitle)) {
6628 article.setUrlTitle(urlTitle);
6629
6630 journalArticlePersistence.update(article);
6631 }
6632 }
6633 }
6634
6635 protected void validate(
6636 long companyId, long groupId, long classNameId,
6637 Map<Locale, String> titleMap, String content, String type,
6638 String ddmStructureKey, String ddmTemplateKey, Date expirationDate,
6639 boolean smallImage, String smallImageURL, File smallImageFile,
6640 byte[] smallImageBytes, ServiceContext serviceContext)
6641 throws PortalException, SystemException {
6642
6643 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
6644 LocalizationUtil.getDefaultLanguageId(content));
6645
6646 Locale[] availableLocales = LanguageUtil.getAvailableLocales(groupId);
6647
6648 if (!ArrayUtil.contains(availableLocales, articleDefaultLocale)) {
6649 LocaleException le = new LocaleException(
6650 LocaleException.TYPE_CONTENT,
6651 "The locale " + articleDefaultLocale +
6652 " is not available in site with groupId" + groupId);
6653
6654 Locale[] sourceAvailableLocales = {articleDefaultLocale};
6655
6656 le.setSourceAvailableLocales(sourceAvailableLocales);
6657 le.setTargetAvailableLocales(availableLocales);
6658
6659 throw le;
6660 }
6661
6662 if ((classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
6663 (titleMap.isEmpty() ||
6664 Validator.isNull(titleMap.get(articleDefaultLocale)))) {
6665
6666 throw new ArticleTitleException();
6667 }
6668 else if (Validator.isNull(type)) {
6669 throw new ArticleTypeException();
6670 }
6671
6672 validateContent(content);
6673
6674 if (Validator.isNotNull(ddmStructureKey)) {
6675 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
6676 PortalUtil.getSiteGroupId(groupId),
6677 PortalUtil.getClassNameId(JournalArticle.class),
6678 ddmStructureKey, true);
6679
6680 validateDDMStructureFields(
6681 ddmStructure, classNameId, serviceContext);
6682
6683 if (Validator.isNotNull(ddmTemplateKey)) {
6684 DDMTemplate ddmTemplate = ddmTemplateLocalService.getTemplate(
6685 PortalUtil.getSiteGroupId(groupId),
6686 PortalUtil.getClassNameId(DDMStructure.class),
6687 ddmTemplateKey, true);
6688
6689 if (ddmTemplate.getClassPK() != ddmStructure.getStructureId()) {
6690 throw new NoSuchTemplateException(
6691 "{templateKey=" + ddmTemplateKey + "}");
6692 }
6693 }
6694 else if (classNameId ==
6695 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
6696
6697 throw new NoSuchTemplateException();
6698 }
6699 }
6700
6701 if ((expirationDate != null) && expirationDate.before(new Date()) &&
6702 !ExportImportThreadLocal.isImportInProcess()) {
6703
6704 throw new ArticleExpirationDateException();
6705 }
6706
6707 String[] imageExtensions = PrefsPropsUtil.getStringArray(
6708 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
6709
6710 if (!smallImage || Validator.isNotNull(smallImageURL) ||
6711 (smallImageFile == null) || (smallImageBytes == null)) {
6712
6713 return;
6714 }
6715
6716 String smallImageName = smallImageFile.getName();
6717
6718 if (smallImageName != null) {
6719 boolean validSmallImageExtension = false;
6720
6721 for (String _imageExtension : imageExtensions) {
6722 if (StringPool.STAR.equals(_imageExtension) ||
6723 StringUtil.endsWith(smallImageName, _imageExtension)) {
6724
6725 validSmallImageExtension = true;
6726
6727 break;
6728 }
6729 }
6730
6731 if (!validSmallImageExtension) {
6732 throw new ArticleSmallImageNameException(smallImageName);
6733 }
6734 }
6735
6736 long smallImageMaxSize = PrefsPropsUtil.getLong(
6737 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
6738
6739 if ((smallImageMaxSize > 0) &&
6740 ((smallImageBytes == null) ||
6741 (smallImageBytes.length > smallImageMaxSize))) {
6742
6743 throw new ArticleSmallImageSizeException();
6744 }
6745 }
6746
6747 protected void validate(
6748 long companyId, long groupId, long classNameId, String articleId,
6749 boolean autoArticleId, double version, Map<Locale, String> titleMap,
6750 String content, String type, String ddmStructureKey,
6751 String ddmTemplateKey, Date expirationDate, boolean smallImage,
6752 String smallImageURL, File smallImageFile, byte[] smallImageBytes,
6753 ServiceContext serviceContext)
6754 throws PortalException, SystemException {
6755
6756 if (!autoArticleId) {
6757 validate(articleId);
6758 }
6759
6760 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
6761 groupId, articleId, version);
6762
6763 if (article != null) {
6764 StringBundler sb = new StringBundler(7);
6765
6766 sb.append("{groupId=");
6767 sb.append(groupId);
6768 sb.append(", articleId=");
6769 sb.append(articleId);
6770 sb.append(", version=");
6771 sb.append(version);
6772 sb.append("}");
6773
6774 throw new DuplicateArticleIdException(sb.toString());
6775 }
6776
6777 validate(
6778 companyId, groupId, classNameId, titleMap, content, type,
6779 ddmStructureKey, ddmTemplateKey, expirationDate, smallImage,
6780 smallImageURL, smallImageFile, smallImageBytes, serviceContext);
6781 }
6782
6783 protected void validate(String articleId) throws PortalException {
6784 if (Validator.isNull(articleId) ||
6785 (articleId.indexOf(CharPool.COMMA) != -1) ||
6786 (articleId.indexOf(CharPool.SPACE) != -1)) {
6787
6788 throw new ArticleIdException();
6789 }
6790 }
6791
6792 protected void validateContent(String content) throws PortalException {
6793 if (Validator.isNull(content)) {
6794 throw new ArticleContentException("Content is null");
6795 }
6796
6797 try {
6798 SAXReaderUtil.read(content);
6799 }
6800 catch (DocumentException de) {
6801 if (_log.isDebugEnabled()) {
6802 _log.debug("Invalid content:\n" + content);
6803 }
6804
6805 throw new ArticleContentException(
6806 "Unable to read content with an XML parser", de);
6807 }
6808 }
6809
6810 protected void validateDDMStructureFields(
6811 DDMStructure ddmStructure, long classNameId,
6812 ServiceContext serviceContext)
6813 throws PortalException, SystemException {
6814
6815 Fields fields = DDMUtil.getFields(
6816 ddmStructure.getStructureId(), serviceContext);
6817
6818 for (com.liferay.portlet.dynamicdatamapping.storage.Field field :
6819 fields) {
6820
6821 if (!ddmStructure.hasField(field.getName())) {
6822 throw new StorageFieldNameException();
6823 }
6824
6825 if (ddmStructure.getFieldRequired(field.getName()) &&
6826 Validator.isNull(field.getValue()) &&
6827 (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT)) {
6828
6829 throw new StorageFieldRequiredException();
6830 }
6831 }
6832 }
6833
6834 private static final long _JOURNAL_ARTICLE_CHECK_INTERVAL =
6835 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
6836
6837 private static Log _log = LogFactoryUtil.getLog(
6838 JournalArticleLocalServiceImpl.class);
6839
6840 private Date _previousCheckDate;
6841
6842 }