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.setCreateDate(serviceContext.getModifiedDate(now));
4791 article.setClassNameId(latestArticle.getClassNameId());
4792 article.setClassPK(latestArticle.getClassPK());
4793 article.setArticleId(articleId);
4794 article.setVersion(version);
4795 article.setSmallImageId(latestArticle.getSmallImageId());
4796 }
4797
4798 Locale locale = getArticleDefaultLocale(content, serviceContext);
4799
4800 String title = titleMap.get(locale);
4801
4802 content = format(
4803 user, groupId, articleId, article.getVersion(), addNewVersion,
4804 content, ddmStructureKey, images);
4805
4806 article.setUserId(user.getUserId());
4807 article.setUserName(user.getFullName());
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.findByPrimaryKey(oldArticle.getUserId());
5024
5025 Locale defaultLocale = getArticleDefaultLocale(content, serviceContext);
5026
5027 if (incrementVersion) {
5028 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
5029
5030 long id = counterLocalService.increment();
5031
5032 article = journalArticlePersistence.create(id);
5033
5034 article.setResourcePrimKey(oldArticle.getResourcePrimKey());
5035 article.setGroupId(oldArticle.getGroupId());
5036 article.setCompanyId(oldArticle.getCompanyId());
5037 article.setUserId(oldArticle.getUserId());
5038 article.setUserName(user.getFullName());
5039 article.setCreateDate(new Date());
5040 article.setModifiedDate(new Date());
5041 article.setClassNameId(oldArticle.getClassNameId());
5042 article.setClassPK(oldArticle.getClassPK());
5043 article.setArticleId(articleId);
5044 article.setVersion(newVersion);
5045 article.setTitleMap(oldArticle.getTitleMap(), defaultLocale);
5046 article.setUrlTitle(
5047 getUniqueUrlTitle(
5048 id, articleId, title, oldArticle.getUrlTitle(),
5049 serviceContext));
5050 article.setDescriptionMap(oldArticle.getDescriptionMap());
5051 article.setType(oldArticle.getType());
5052 article.setStructureId(oldArticle.getStructureId());
5053 article.setTemplateId(oldArticle.getTemplateId());
5054 article.setLayoutUuid(oldArticle.getLayoutUuid());
5055 article.setDisplayDate(oldArticle.getDisplayDate());
5056 article.setExpirationDate(oldArticle.getExpirationDate());
5057 article.setReviewDate(oldArticle.getReviewDate());
5058 article.setIndexable(oldArticle.getIndexable());
5059 article.setSmallImage(oldArticle.getSmallImage());
5060 article.setSmallImageId(oldArticle.getSmallImageId());
5061
5062 if (article.getSmallImageId() == 0) {
5063 article.setSmallImageId(counterLocalService.increment());
5064 }
5065
5066 article.setSmallImageURL(oldArticle.getSmallImageURL());
5067
5068 article.setStatus(WorkflowConstants.STATUS_DRAFT);
5069 article.setStatusDate(new Date());
5070 article.setExpandoBridgeAttributes(oldArticle);
5071 }
5072 else {
5073 article = oldArticle;
5074 }
5075
5076 Map<Locale, String> titleMap = article.getTitleMap();
5077
5078 titleMap.put(locale, title);
5079
5080 article.setTitleMap(titleMap, defaultLocale);
5081
5082 Map<Locale, String> descriptionMap = article.getDescriptionMap();
5083
5084 descriptionMap.put(locale, description);
5085
5086 article.setDescriptionMap(descriptionMap);
5087
5088 content = format(
5089 user, groupId, articleId, article.getVersion(),
5090 !oldArticle.isDraft(), content, oldArticle.getStructureId(),
5091 images);
5092
5093 article.setContent(content);
5094
5095 journalArticlePersistence.update(article);
5096
5097 return article;
5098 }
5099
5100
5113 @Override
5114 public void updateAsset(
5115 long userId, JournalArticle article, long[] assetCategoryIds,
5116 String[] assetTagNames, long[] assetLinkEntryIds)
5117 throws PortalException, SystemException {
5118
5119 boolean visible = article.isApproved();
5120
5121 if (article.getClassNameId() !=
5122 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5123
5124 visible = false;
5125 }
5126
5127 boolean addDraftAssetEntry = false;
5128
5129 if (!article.isApproved() &&
5130 (article.getVersion() != JournalArticleConstants.VERSION_DEFAULT)) {
5131
5132 int approvedArticlesCount = journalArticlePersistence.countByG_A_ST(
5133 article.getGroupId(), article.getArticleId(),
5134 JournalArticleConstants.ASSET_ENTRY_CREATION_STATUSES);
5135
5136 if (approvedArticlesCount > 0) {
5137 addDraftAssetEntry = true;
5138 }
5139 }
5140
5141 AssetEntry assetEntry = null;
5142
5143 if (addDraftAssetEntry) {
5144 assetEntry = assetEntryLocalService.updateEntry(
5145 userId, article.getGroupId(), article.getCreateDate(),
5146 article.getModifiedDate(), JournalArticle.class.getName(),
5147 article.getPrimaryKey(), article.getUuid(),
5148 getClassTypeId(article), assetCategoryIds, assetTagNames, false,
5149 null, null, null, ContentTypes.TEXT_HTML, article.getTitle(),
5150 article.getDescription(), article.getDescription(), null,
5151 article.getLayoutUuid(), 0, 0, null, false);
5152 }
5153 else {
5154 JournalArticleResource journalArticleResource =
5155 journalArticleResourceLocalService.getArticleResource(
5156 article.getResourcePrimKey());
5157
5158 assetEntry = assetEntryLocalService.updateEntry(
5159 userId, article.getGroupId(), article.getCreateDate(),
5160 article.getModifiedDate(), JournalArticle.class.getName(),
5161 journalArticleResource.getResourcePrimKey(),
5162 journalArticleResource.getUuid(), getClassTypeId(article),
5163 assetCategoryIds, assetTagNames, visible, null, null, null,
5164 ContentTypes.TEXT_HTML, article.getTitle(),
5165 article.getDescription(), article.getDescription(), null,
5166 article.getLayoutUuid(), 0, 0, null, false);
5167 }
5168
5169 assetLinkLocalService.updateLinks(
5170 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5171 AssetLinkConstants.TYPE_RELATED);
5172 }
5173
5174
5189 @Indexable(type = IndexableType.REINDEX)
5190 @Override
5191 public JournalArticle updateContent(
5192 long groupId, String articleId, double version, String content)
5193 throws PortalException, SystemException {
5194
5195 JournalArticle article = journalArticlePersistence.findByG_A_V(
5196 groupId, articleId, version);
5197
5198 article.setContent(content);
5199
5200 journalArticlePersistence.update(article);
5201
5202 return article;
5203 }
5204
5205
5228 @Indexable(type = IndexableType.REINDEX)
5229 @Override
5230 public JournalArticle updateStatus(
5231 long userId, JournalArticle article, int status, String articleURL,
5232 Map<String, Serializable> workflowContext,
5233 ServiceContext serviceContext)
5234 throws PortalException, SystemException {
5235
5236
5237
5238 User user = userPersistence.findByPrimaryKey(userId);
5239 Date now = new Date();
5240
5241 if ((status == WorkflowConstants.STATUS_APPROVED) &&
5242 (article.getClassNameId() ==
5243 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5244 (article.getDisplayDate() != null) &&
5245 now.before(article.getDisplayDate())) {
5246
5247 status = WorkflowConstants.STATUS_SCHEDULED;
5248 }
5249
5250 int oldStatus = article.getStatus();
5251
5252 if (status == WorkflowConstants.STATUS_APPROVED) {
5253 Date expirationDate = article.getExpirationDate();
5254
5255 if ((expirationDate != null) && expirationDate.before(now)) {
5256 article.setExpirationDate(null);
5257 }
5258 }
5259
5260 if (status == WorkflowConstants.STATUS_EXPIRED) {
5261 article.setExpirationDate(now);
5262 }
5263
5264 article.setStatus(status);
5265 article.setStatusByUserId(user.getUserId());
5266 article.setStatusByUserName(user.getFullName());
5267 article.setStatusDate(serviceContext.getModifiedDate(now));
5268
5269 journalArticlePersistence.update(article);
5270
5271 if (hasModifiedLatestApprovedVersion(
5272 article.getGroupId(), article.getArticleId(),
5273 article.getVersion())) {
5274
5275 if (status == WorkflowConstants.STATUS_APPROVED) {
5276 updateUrlTitles(
5277 article.getGroupId(), article.getArticleId(),
5278 article.getUrlTitle());
5279
5280
5281
5282 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
5283 (article.getVersion() !=
5284 JournalArticleConstants.VERSION_DEFAULT)) {
5285
5286 AssetEntry draftAssetEntry =
5287 assetEntryLocalService.fetchEntry(
5288 JournalArticle.class.getName(),
5289 article.getPrimaryKey());
5290
5291 if (draftAssetEntry != null) {
5292 long[] assetCategoryIds =
5293 draftAssetEntry.getCategoryIds();
5294 String[] assetTagNames = draftAssetEntry.getTagNames();
5295
5296 List<AssetLink> assetLinks =
5297 assetLinkLocalService.getDirectLinks(
5298 draftAssetEntry.getEntryId(),
5299 AssetLinkConstants.TYPE_RELATED);
5300
5301 long[] assetLinkEntryIds = StringUtil.split(
5302 ListUtil.toString(
5303 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
5304
5305 AssetEntry assetEntry =
5306 assetEntryLocalService.updateEntry(
5307 userId, article.getGroupId(),
5308 article.getCreateDate(),
5309 article.getModifiedDate(),
5310 JournalArticle.class.getName(),
5311 article.getResourcePrimKey(), article.getUuid(),
5312 getClassTypeId(article), assetCategoryIds,
5313 assetTagNames, false, null, null, null,
5314 ContentTypes.TEXT_HTML, article.getTitle(),
5315 article.getDescription(),
5316 article.getDescription(), null,
5317 article.getLayoutUuid(), 0, 0, null, false);
5318
5319 assetLinkLocalService.updateLinks(
5320 userId, assetEntry.getEntryId(), assetLinkEntryIds,
5321 AssetLinkConstants.TYPE_RELATED);
5322
5323 SystemEventHierarchyEntryThreadLocal.push(
5324 JournalArticle.class);
5325
5326 try {
5327 assetEntryLocalService.deleteEntry(
5328 JournalArticle.class.getName(),
5329 article.getPrimaryKey());
5330 }
5331 finally {
5332 SystemEventHierarchyEntryThreadLocal.pop(
5333 JournalArticle.class);
5334 }
5335 }
5336 }
5337
5338 if (article.getClassNameId() ==
5339 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
5340
5341 assetEntryLocalService.updateEntry(
5342 JournalArticle.class.getName(),
5343 article.getResourcePrimKey(), article.getDisplayDate(),
5344 article.getExpirationDate(), true);
5345 }
5346
5347
5348
5349 JSONObject extraDataJSONObject =
5350 JSONFactoryUtil.createJSONObject();
5351
5352 extraDataJSONObject.put("title", article.getTitle());
5353
5354 if (serviceContext.isCommandUpdate()) {
5355 socialActivityLocalService.addActivity(
5356 user.getUserId(), article.getGroupId(),
5357 JournalArticle.class.getName(),
5358 article.getResourcePrimKey(),
5359 JournalActivityKeys.UPDATE_ARTICLE,
5360 extraDataJSONObject.toString(), 0);
5361 }
5362 else {
5363 socialActivityLocalService.addUniqueActivity(
5364 user.getUserId(), article.getGroupId(),
5365 JournalArticle.class.getName(),
5366 article.getResourcePrimKey(),
5367 JournalActivityKeys.ADD_ARTICLE,
5368 extraDataJSONObject.toString(), 0);
5369 }
5370 }
5371 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
5372 updatePreviousApprovedArticle(article);
5373 }
5374 }
5375
5376 if ((article.getClassNameId() ==
5377 JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
5378 (oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
5379 (status != WorkflowConstants.STATUS_IN_TRASH)) {
5380
5381
5382
5383 if ((oldStatus == WorkflowConstants.STATUS_PENDING) &&
5384 ((status == WorkflowConstants.STATUS_APPROVED) ||
5385 (status == WorkflowConstants.STATUS_DENIED))) {
5386
5387 String msg = "granted";
5388
5389 if (status == WorkflowConstants.STATUS_DENIED) {
5390 msg = "denied";
5391 }
5392
5393 try {
5394 PortletPreferences preferences =
5395 ServiceContextUtil.getPortletPreferences(
5396 serviceContext);
5397
5398 articleURL = buildArticleURL(
5399 articleURL, article.getGroupId(), article.getFolderId(),
5400 article.getArticleId());
5401
5402 sendEmail(
5403 article, articleURL, preferences, msg, serviceContext);
5404 }
5405 catch (Exception e) {
5406 _log.error(
5407 "Unable to send email to notify the change of status " +
5408 " to " + msg + " for article " + article.getId() +
5409 ": " + e.getMessage());
5410 }
5411 }
5412
5413
5414
5415 notifySubscribers(article, serviceContext);
5416 }
5417
5418 return article;
5419 }
5420
5421
5442 @Override
5443 public JournalArticle updateStatus(
5444 long userId, long classPK, int status,
5445 Map<String, Serializable> workflowContext,
5446 ServiceContext serviceContext)
5447 throws PortalException, SystemException {
5448
5449 JournalArticle article = getArticle(classPK);
5450
5451 return journalArticleLocalService.updateStatus(
5452 userId, article, status, null, workflowContext, serviceContext);
5453 }
5454
5455
5477 @Override
5478 public JournalArticle updateStatus(
5479 long userId, long groupId, String articleId, double version,
5480 int status, String articleURL,
5481 Map<String, Serializable> workflowContext,
5482 ServiceContext serviceContext)
5483 throws PortalException, SystemException {
5484
5485 JournalArticle article = journalArticlePersistence.findByG_A_V(
5486 groupId, articleId, version);
5487
5488 return journalArticleLocalService.updateStatus(
5489 userId, article, status, articleURL, workflowContext,
5490 serviceContext);
5491 }
5492
5493
5508 @Override
5509 public void updateTemplateId(
5510 long groupId, long classNameId, String oldDDMTemplateKey,
5511 String newDDMTemplateKey)
5512 throws SystemException {
5513
5514 List<JournalArticle> articles = journalArticlePersistence.findByG_C_T(
5515 groupId, classNameId, oldDDMTemplateKey);
5516
5517 for (JournalArticle article : articles) {
5518 article.setTemplateId(newDDMTemplateKey);
5519
5520 journalArticlePersistence.update(article);
5521 }
5522 }
5523
5524 protected String buildArticleURL(
5525 String articleURL, long groupId, long folderId, String articleId) {
5526
5527 StringBundler sb = new StringBundler(13);
5528
5529 sb.append(articleURL);
5530 sb.append(StringPool.AMPERSAND);
5531 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5532 sb.append("groupId=");
5533 sb.append(groupId);
5534 sb.append(StringPool.AMPERSAND);
5535 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5536 sb.append("folderId=");
5537 sb.append(folderId);
5538 sb.append(StringPool.AMPERSAND);
5539 sb.append(PortalUtil.getPortletNamespace(PortletKeys.JOURNAL));
5540 sb.append("articleId=");
5541 sb.append(articleId);
5542
5543 return sb.toString();
5544 }
5545
5546 protected void checkArticlesByDisplayDate(Date displayDate)
5547 throws PortalException, SystemException {
5548
5549 List<JournalArticle> articles = journalArticlePersistence.findByLtD_S(
5550 displayDate, WorkflowConstants.STATUS_SCHEDULED);
5551
5552 for (JournalArticle article : articles) {
5553 ServiceContext serviceContext = new ServiceContext();
5554
5555 serviceContext.setCommand(Constants.UPDATE);
5556
5557 String layoutFullURL = PortalUtil.getLayoutFullURL(
5558 article.getGroupId(), PortletKeys.JOURNAL);
5559
5560 serviceContext.setLayoutFullURL(layoutFullURL);
5561
5562 serviceContext.setScopeGroupId(article.getGroupId());
5563
5564 journalArticleLocalService.updateStatus(
5565 article.getUserId(), article, WorkflowConstants.STATUS_APPROVED,
5566 null, new HashMap<String, Serializable>(), serviceContext);
5567 }
5568 }
5569
5570 protected void checkArticlesByExpirationDate(Date expirationDate)
5571 throws PortalException, SystemException {
5572
5573 List<JournalArticle> articles =
5574 journalArticleFinder.findByExpirationDate(
5575 JournalArticleConstants.CLASSNAME_ID_DEFAULT,
5576 new Date(
5577 expirationDate.getTime() + _JOURNAL_ARTICLE_CHECK_INTERVAL),
5578 new QueryDefinition(WorkflowConstants.STATUS_APPROVED));
5579
5580 if (_log.isDebugEnabled()) {
5581 _log.debug("Expiring " + articles.size() + " articles");
5582 }
5583
5584 Set<Long> companyIds = new HashSet<Long>();
5585
5586 for (JournalArticle article : articles) {
5587 if (PropsValues.JOURNAL_ARTICLE_EXPIRE_ALL_VERSIONS) {
5588 List<JournalArticle> currentArticles =
5589 journalArticlePersistence.findByG_A(
5590 article.getGroupId(), article.getArticleId(),
5591 QueryUtil.ALL_POS, QueryUtil.ALL_POS,
5592 new ArticleVersionComparator(true));
5593
5594 for (JournalArticle currentArticle : currentArticles) {
5595 currentArticle.setExpirationDate(
5596 article.getExpirationDate());
5597 currentArticle.setStatus(WorkflowConstants.STATUS_EXPIRED);
5598
5599 journalArticlePersistence.update(currentArticle);
5600 }
5601 }
5602 else {
5603 article.setStatus(WorkflowConstants.STATUS_EXPIRED);
5604
5605 journalArticlePersistence.update(article);
5606 }
5607
5608 updatePreviousApprovedArticle(article);
5609
5610 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5611 JournalArticle.class);
5612
5613 indexer.reindex(article);
5614
5615 JournalContentUtil.clearCache(
5616 article.getGroupId(), article.getArticleId(),
5617 article.getTemplateId());
5618
5619 companyIds.add(article.getCompanyId());
5620 }
5621
5622 for (long companyId : companyIds) {
5623 CacheUtil.clearCache(companyId);
5624 }
5625
5626 if (_previousCheckDate == null) {
5627 _previousCheckDate = new Date(
5628 expirationDate.getTime() - _JOURNAL_ARTICLE_CHECK_INTERVAL);
5629 }
5630 }
5631
5632 protected void checkArticlesByReviewDate(Date reviewDate)
5633 throws PortalException, SystemException {
5634
5635 List<JournalArticle> articles = journalArticleFinder.findByReviewDate(
5636 JournalArticleConstants.CLASSNAME_ID_DEFAULT, reviewDate,
5637 _previousCheckDate);
5638
5639 if (_log.isDebugEnabled()) {
5640 _log.debug(
5641 "Sending review notifications for " + articles.size() +
5642 " articles");
5643 }
5644
5645 for (JournalArticle article : articles) {
5646 String articleURL = StringPool.BLANK;
5647
5648 long ownerId = article.getGroupId();
5649 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
5650 long plid = PortletKeys.PREFS_PLID_SHARED;
5651 String portletId = PortletKeys.JOURNAL;
5652
5653 PortletPreferences preferences =
5654 portletPreferencesLocalService.getPreferences(
5655 article.getCompanyId(), ownerId, ownerType, plid,
5656 portletId);
5657
5658 sendEmail(
5659 article, articleURL, preferences, "review",
5660 new ServiceContext());
5661 }
5662 }
5663
5664 protected void checkStructure(Document contentDoc, Element root)
5665 throws PortalException {
5666
5667 for (Element el : root.elements()) {
5668 checkStructureField(el, contentDoc);
5669
5670 checkStructure(contentDoc, el);
5671 }
5672 }
5673
5674 protected void checkStructure(JournalArticle article)
5675 throws PortalException, SystemException {
5676
5677 Group companyGroup = groupLocalService.getCompanyGroup(
5678 article.getCompanyId());
5679
5680 DDMStructure structure = null;
5681
5682 try {
5683 structure = ddmStructurePersistence.findByG_C_S(
5684 PortalUtil.getSiteGroupId(article.getGroupId()),
5685 PortalUtil.getClassNameId(JournalArticle.class),
5686 article.getStructureId());
5687 }
5688 catch (NoSuchStructureException nsse) {
5689 structure = ddmStructurePersistence.findByG_C_S(
5690 companyGroup.getGroupId(),
5691 PortalUtil.getClassNameId(JournalArticle.class),
5692 article.getStructureId());
5693 }
5694
5695 String content = GetterUtil.getString(article.getContent());
5696
5697 try {
5698 Document contentDocument = SAXReaderUtil.read(content);
5699 Document xsdDocument = SAXReaderUtil.read(structure.getXsd());
5700
5701 checkStructure(contentDocument, xsdDocument.getRootElement());
5702 }
5703 catch (DocumentException de) {
5704 throw new SystemException(de);
5705 }
5706 catch (StructureXsdException sxsde) {
5707 long groupId = article.getGroupId();
5708 String articleId = article.getArticleId();
5709 double version = article.getVersion();
5710
5711 if (_log.isWarnEnabled()) {
5712 _log.warn(
5713 "Article {groupId=" + groupId + ", articleId=" +
5714 articleId + ", version=" + version +
5715 "} has content that does not match its " +
5716 "structure: " + sxsde.getMessage());
5717 }
5718 }
5719 }
5720
5721 protected void checkStructureField(Element el, Document contentDoc)
5722 throws PortalException {
5723
5724 StringBuilder elPath = new StringBuilder();
5725
5726 elPath.append(el.attributeValue("name"));
5727
5728 Element elParent = el.getParent();
5729
5730 while (true) {
5731 if ((elParent == null) || elParent.getName().equals("root")) {
5732 break;
5733 }
5734
5735 elPath.insert(
5736 0, elParent.attributeValue("name") + StringPool.COMMA);
5737
5738 elParent = elParent.getParent();
5739 }
5740
5741 String[] elPathNames = StringUtil.split(elPath.toString());
5742
5743 Element contentEl = contentDoc.getRootElement();
5744
5745 for (String _elPathName : elPathNames) {
5746 boolean foundEl = false;
5747
5748 for (Element tempEl : contentEl.elements()) {
5749 if (_elPathName.equals(
5750 tempEl.attributeValue("name", StringPool.BLANK))) {
5751
5752 contentEl = tempEl;
5753 foundEl = true;
5754
5755 break;
5756 }
5757 }
5758
5759 if (!foundEl) {
5760 String elType = contentEl.attributeValue(
5761 "type", StringPool.BLANK);
5762
5763 if (!elType.equals("list") && !elType.equals("multi-list")) {
5764 throw new StructureXsdException(elPath.toString());
5765 }
5766
5767 break;
5768 }
5769 }
5770 }
5771
5772 protected void copyArticleImages(
5773 JournalArticle oldArticle, JournalArticle newArticle)
5774 throws Exception {
5775
5776 Document contentDoc = SAXReaderUtil.read(oldArticle.getContent());
5777
5778 XPath xPathSelector = SAXReaderUtil.createXPath(
5779 "
5780
5781 List<Node> imageNodes = xPathSelector.selectNodes(contentDoc);
5782
5783 for (Node imageNode : imageNodes) {
5784 Element imageEl = (Element)imageNode;
5785
5786 String instanceId = imageEl.attributeValue("instance-id");
5787 String name = imageEl.attributeValue("name");
5788
5789 List<Element> dynamicContentEls = imageEl.elements(
5790 "dynamic-content");
5791
5792 for (Element dynamicContentEl : dynamicContentEls) {
5793 long imageId = GetterUtil.getLong(
5794 dynamicContentEl.attributeValue("id"));
5795 String languageId = dynamicContentEl.attributeValue(
5796 "language-id");
5797
5798 Image oldImage = null;
5799
5800 try {
5801 oldImage = imageLocalService.getImage(imageId);
5802 }
5803 catch (NoSuchImageException nsie) {
5804 continue;
5805 }
5806
5807 imageId = journalArticleImageLocalService.getArticleImageId(
5808 newArticle.getGroupId(), newArticle.getArticleId(),
5809 newArticle.getVersion(), instanceId, name, languageId);
5810
5811 imageLocalService.updateImage(imageId, oldImage.getTextObj());
5812
5813 String elContent =
5814 "/image/journal/article?img_id=" + imageId + "&t=" +
5815 WebServerServletTokenUtil.getToken(imageId);
5816
5817 dynamicContentEl.setText(elContent);
5818 dynamicContentEl.addAttribute("id", String.valueOf(imageId));
5819 }
5820 }
5821
5822 newArticle.setContent(contentDoc.formattedString());
5823 }
5824
5825 protected void format(
5826 User user, long groupId, String articleId, double version,
5827 boolean incrementVersion, Element root, Map<String, byte[]> images)
5828 throws PortalException, SystemException {
5829
5830 for (Element element : root.elements()) {
5831 String elInstanceId = element.attributeValue(
5832 "instance-id", StringPool.BLANK);
5833 String elType = element.attributeValue("type", StringPool.BLANK);
5834
5835 if (elType.equals("image")) {
5836 String elName = element.attributeValue(
5837 "name", StringPool.BLANK);
5838 String elIndex = element.attributeValue(
5839 "index", StringPool.BLANK);
5840
5841 String name = elName + "_" + elIndex;
5842
5843 formatImage(
5844 groupId, articleId, version, incrementVersion, element,
5845 elInstanceId, name, images);
5846 }
5847 else if (elType.equals("text_area") || elType.equals("text") ||
5848 elType.equals("text_box")) {
5849
5850 List<Element> dynamicContentElements = element.elements(
5851 "dynamic-content");
5852
5853 for (Element dynamicContentElement : dynamicContentElements) {
5854 String dynamicContent = dynamicContentElement.getText();
5855
5856 if (Validator.isNotNull(dynamicContent)) {
5857 String contentType = ContentTypes.TEXT_PLAIN;
5858
5859 if (elType.equals("text_area")) {
5860 contentType = ContentTypes.TEXT_HTML;
5861 }
5862
5863 dynamicContent = SanitizerUtil.sanitize(
5864 user.getCompanyId(), groupId, user.getUserId(),
5865 JournalArticle.class.getName(), 0, contentType,
5866 dynamicContent);
5867
5868 dynamicContentElement.clearContent();
5869
5870 dynamicContentElement.addCDATA(dynamicContent);
5871 }
5872 }
5873 }
5874
5875 format(
5876 user, groupId, articleId, version, incrementVersion, element,
5877 images);
5878 }
5879 }
5880
5881 protected String format(
5882 User user, long groupId, String articleId, double version,
5883 boolean incrementVersion, String content, String ddmStructureKey,
5884 Map<String, byte[]> images)
5885 throws PortalException, SystemException {
5886
5887 Document document = null;
5888
5889 try {
5890 document = SAXReaderUtil.read(content);
5891
5892 Element rootElement = document.getRootElement();
5893
5894 if (Validator.isNotNull(ddmStructureKey)) {
5895 format(
5896 user, groupId, articleId, version, incrementVersion,
5897 rootElement, images);
5898 }
5899 else {
5900 List<Element> staticContentElements = rootElement.elements(
5901 "static-content");
5902
5903 for (Element staticContentElement : staticContentElements) {
5904 String staticContent = staticContentElement.getText();
5905
5906 staticContent = SanitizerUtil.sanitize(
5907 user.getCompanyId(), groupId, user.getUserId(),
5908 JournalArticle.class.getName(), 0,
5909 ContentTypes.TEXT_HTML, staticContent);
5910
5911 staticContentElement.clearContent();
5912
5913 staticContentElement.addCDATA(staticContent);
5914 }
5915 }
5916
5917 content = DDMXMLUtil.formatXML(document);
5918 }
5919 catch (DocumentException de) {
5920 _log.error(de, de);
5921 }
5922
5923 return content;
5924 }
5925
5926 protected void formatImage(
5927 long groupId, String articleId, double version,
5928 boolean incrementVersion, Element el, String elInstanceId,
5929 String elName, Map<String, byte[]> images)
5930 throws PortalException, SystemException {
5931
5932 List<Element> imageContents = el.elements("dynamic-content");
5933
5934 for (Element dynamicContent : imageContents) {
5935 String elLanguage = dynamicContent.attributeValue(
5936 "language-id", StringPool.BLANK);
5937
5938 if (!elLanguage.equals(StringPool.BLANK)) {
5939 elLanguage = "_" + elLanguage;
5940 }
5941
5942 long imageId = journalArticleImageLocalService.getArticleImageId(
5943 groupId, articleId, version, elInstanceId, elName, elLanguage);
5944
5945 if (dynamicContent.getText().equals("delete") ||
5946 Validator.isNull(dynamicContent.getText())) {
5947
5948 dynamicContent.setText(StringPool.BLANK);
5949
5950 imageLocalService.deleteImage(imageId);
5951
5952 String defaultElLanguage = "";
5953
5954 if (Validator.isNull(elLanguage)) {
5955 defaultElLanguage =
5956 "_" +
5957 LocaleUtil.toLanguageId(
5958 LocaleUtil.getSiteDefault());
5959 }
5960
5961 long defaultImageId =
5962 journalArticleImageLocalService.getArticleImageId(
5963 groupId, articleId, version, elInstanceId, elName,
5964 defaultElLanguage);
5965
5966 imageLocalService.deleteImage(defaultImageId);
5967
5968 continue;
5969 }
5970
5971 String elContent =
5972 "/image/journal/article?img_id=" + imageId + "&t=" +
5973 WebServerServletTokenUtil.getToken(imageId);
5974
5975 byte[] bytes = images.get(elInstanceId + "_" + elName + elLanguage);
5976
5977 if (ArrayUtil.isNotEmpty(bytes)) {
5978 dynamicContent.setText(elContent);
5979 dynamicContent.addAttribute("id", String.valueOf(imageId));
5980
5981 imageLocalService.updateImage(imageId, bytes);
5982
5983 continue;
5984 }
5985
5986 if ((version > JournalArticleConstants.VERSION_DEFAULT) &&
5987 incrementVersion) {
5988
5989 double oldVersion = MathUtil.format(version - 0.1, 1, 1);
5990
5991 long oldImageId = 0;
5992
5993 if ((oldVersion >= 1) && incrementVersion) {
5994 oldImageId =
5995 journalArticleImageLocalService.getArticleImageId(
5996 groupId, articleId, oldVersion, elInstanceId,
5997 elName, elLanguage);
5998 }
5999
6000 Image oldImage = null;
6001
6002 if (oldImageId > 0) {
6003 oldImage = imageLocalService.getImage(oldImageId);
6004 }
6005
6006 if (oldImage != null) {
6007 dynamicContent.setText(elContent);
6008 dynamicContent.addAttribute("id", String.valueOf(imageId));
6009
6010 bytes = oldImage.getTextObj();
6011
6012 imageLocalService.updateImage(imageId, bytes);
6013 }
6014 else if (dynamicContent.getText().equals("update")) {
6015 dynamicContent.setText(StringPool.BLANK);
6016 }
6017
6018 continue;
6019 }
6020
6021 Image image = imageLocalService.getImage(imageId);
6022
6023 if (image != null) {
6024 dynamicContent.setText(elContent);
6025 dynamicContent.addAttribute("id", String.valueOf(imageId));
6026
6027 continue;
6028 }
6029 else if (dynamicContent.getText().equals("update")) {
6030 dynamicContent.setText(StringPool.BLANK);
6031
6032 continue;
6033 }
6034
6035 long contentImageId = GetterUtil.getLong(
6036 HttpUtil.getParameter(dynamicContent.getText(), "img_id"));
6037
6038 if (contentImageId <= 0) {
6039 contentImageId = GetterUtil.getLong(
6040 HttpUtil.getParameter(
6041 dynamicContent.getText(), "img_id", false));
6042 }
6043
6044 if (contentImageId > 0) {
6045 image = imageLocalService.getImage(contentImageId);
6046
6047 if (image != null) {
6048 dynamicContent.addAttribute(
6049 "id", String.valueOf(contentImageId));
6050
6051 continue;
6052 }
6053 }
6054
6055 String defaultElLanguage = "";
6056
6057 if (Validator.isNull(elLanguage)) {
6058 defaultElLanguage =
6059 "_" + LocaleUtil.toLanguageId(LocaleUtil.getSiteDefault());
6060 }
6061
6062 long defaultImageId =
6063 journalArticleImageLocalService.getArticleImageId(
6064 groupId, articleId, version, elInstanceId, elName,
6065 defaultElLanguage);
6066
6067 Image defaultImage = imageLocalService.getImage(defaultImageId);
6068
6069 if (defaultImage != null) {
6070 dynamicContent.setText(elContent);
6071 dynamicContent.addAttribute(
6072 "id", String.valueOf(defaultImageId));
6073
6074 bytes = defaultImage.getTextObj();
6075
6076 imageLocalService.updateImage(defaultImageId, bytes);
6077
6078 continue;
6079 }
6080
6081 if (Validator.isNotNull(elLanguage)) {
6082 dynamicContent.setText(StringPool.BLANK);
6083 }
6084 }
6085 }
6086
6087 protected Locale getArticleDefaultLocale(
6088 String content, ServiceContext serviceContext) {
6089
6090 String defaultLanguageId = ParamUtil.getString(
6091 serviceContext, "defaultLanguageId");
6092
6093 if (Validator.isNull(defaultLanguageId)) {
6094 defaultLanguageId = LocalizationUtil.getDefaultLanguageId(content);
6095 }
6096
6097 if (Validator.isNotNull(defaultLanguageId)) {
6098 return LocaleUtil.fromLanguageId(defaultLanguageId);
6099 }
6100
6101 return LocaleUtil.getSiteDefault();
6102 }
6103
6104 protected List<ObjectValuePair<Long, Integer>> getArticleVersionStatuses(
6105 List<JournalArticle> articles) {
6106
6107 List<ObjectValuePair<Long, Integer>> articleVersionStatusOVPs =
6108 new ArrayList<ObjectValuePair<Long, Integer>>(articles.size());
6109
6110 for (JournalArticle article : articles) {
6111 int status = article.getStatus();
6112
6113 if (status == WorkflowConstants.STATUS_PENDING) {
6114 status = WorkflowConstants.STATUS_DRAFT;
6115 }
6116
6117 ObjectValuePair<Long, Integer> articleVersionStatusOVP =
6118 new ObjectValuePair<Long, Integer>(article.getId(), status);
6119
6120 articleVersionStatusOVPs.add(articleVersionStatusOVP);
6121 }
6122
6123 return articleVersionStatusOVPs;
6124 }
6125
6126 protected long getClassTypeId(JournalArticle article) {
6127 long classTypeId = 0;
6128
6129 try {
6130 long classNameId = PortalUtil.getClassNameId(JournalArticle.class);
6131
6132 DDMStructure ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6133 article.getGroupId(), classNameId, article.getStructureId());
6134
6135 if (ddmStructure == null) {
6136 Group companyGroup = groupLocalService.getCompanyGroup(
6137 article.getCompanyId());
6138
6139 ddmStructure = ddmStructurePersistence.fetchByG_C_S(
6140 companyGroup.getGroupId(), classNameId,
6141 article.getStructureId());
6142 }
6143
6144 if (ddmStructure != null) {
6145 classTypeId = ddmStructure.getStructureId();
6146 }
6147 }
6148 catch (Exception e) {
6149 _log.error(e, e);
6150 }
6151
6152 return classTypeId;
6153 }
6154
6155 protected JournalArticle getFirstArticle(
6156 long groupId, String articleId, int status,
6157 OrderByComparator orderByComparator)
6158 throws PortalException, SystemException {
6159
6160 if (status == WorkflowConstants.STATUS_ANY) {
6161 return journalArticlePersistence.findByG_A_NotST_First(
6162 groupId, articleId, WorkflowConstants.STATUS_IN_TRASH,
6163 orderByComparator);
6164 }
6165 else {
6166 return journalArticlePersistence.findByG_A_ST_First(
6167 groupId, articleId, status, orderByComparator);
6168 }
6169 }
6170
6171 protected String getUniqueUrlTitle(
6172 long id, long groupId, String articleId, String title)
6173 throws PortalException, SystemException {
6174
6175 String urlTitle = JournalUtil.getUrlTitle(id, title);
6176
6177 return getUniqueUrlTitle(groupId, articleId, urlTitle);
6178 }
6179
6180 protected String getUniqueUrlTitle(
6181 long id, String articleId, String title, String oldUrlTitle,
6182 ServiceContext serviceContext)
6183 throws PortalException, SystemException {
6184
6185 String serviceContextUrlTitle = ParamUtil.getString(
6186 serviceContext, "urlTitle");
6187
6188 String urlTitle = null;
6189
6190 if (Validator.isNotNull(serviceContextUrlTitle)) {
6191 urlTitle = JournalUtil.getUrlTitle(id, serviceContextUrlTitle);
6192 }
6193 else if (Validator.isNotNull(oldUrlTitle)) {
6194 return oldUrlTitle;
6195 }
6196 else {
6197 urlTitle = getUniqueUrlTitle(
6198 id, serviceContext.getScopeGroupId(), articleId, title);
6199 }
6200
6201 JournalArticle urlTitleArticle = null;
6202
6203 try {
6204 urlTitleArticle = getArticleByUrlTitle(
6205 serviceContext.getScopeGroupId(), urlTitle);
6206 }
6207 catch (NoSuchArticleException nsae) {
6208 }
6209
6210 if ((urlTitleArticle != null) &&
6211 !Validator.equals(
6212 urlTitleArticle.getArticleId(), articleId)) {
6213
6214 urlTitle = getUniqueUrlTitle(
6215 id, serviceContext.getScopeGroupId(), articleId, urlTitle);
6216 }
6217
6218 return urlTitle;
6219 }
6220
6221 protected boolean hasModifiedLatestApprovedVersion(
6222 long groupId, String articleId, double version)
6223 throws PortalException, SystemException {
6224
6225 double latestApprovedVersion;
6226
6227 try {
6228 latestApprovedVersion = getLatestVersion(
6229 groupId, articleId, WorkflowConstants.STATUS_APPROVED);
6230
6231 if (version >= latestApprovedVersion) {
6232 return true;
6233 }
6234 else {
6235 return false;
6236 }
6237 }
6238 catch (NoSuchArticleException nsae) {
6239 return true;
6240 }
6241 }
6242
6243 protected void notifySubscribers(
6244 JournalArticle article, ServiceContext serviceContext)
6245 throws PortalException, SystemException {
6246
6247 if (!article.isApproved()) {
6248 return;
6249 }
6250
6251 String articleURL = PortalUtil.getControlPanelFullURL(
6252 serviceContext.getScopeGroupId(), PortletKeys.JOURNAL, null);
6253
6254 if (Validator.isNull(articleURL)) {
6255 return;
6256 }
6257
6258 articleURL = buildArticleURL(
6259 articleURL, article.getGroupId(), article.getFolderId(),
6260 article.getArticleId());
6261
6262 PortletPreferences preferences =
6263 ServiceContextUtil.getPortletPreferences(serviceContext);
6264
6265 if (preferences == null) {
6266 long ownerId = article.getGroupId();
6267 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
6268 long plid = PortletKeys.PREFS_PLID_SHARED;
6269 String portletId = PortletKeys.JOURNAL;
6270 String defaultPreferences = null;
6271
6272 preferences = portletPreferencesLocalService.getPreferences(
6273 article.getCompanyId(), ownerId, ownerType, plid, portletId,
6274 defaultPreferences);
6275 }
6276
6277 if ((article.getVersion() == 1.0) &&
6278 JournalUtil.getEmailArticleAddedEnabled(preferences)) {
6279 }
6280 else if ((article.getVersion() != 1.0) &&
6281 JournalUtil.getEmailArticleUpdatedEnabled(preferences)) {
6282 }
6283 else {
6284 return;
6285 }
6286
6287 String fromName = JournalUtil.getEmailFromName(
6288 preferences, article.getCompanyId());
6289 String fromAddress = JournalUtil.getEmailFromAddress(
6290 preferences, article.getCompanyId());
6291
6292 String subject = null;
6293 String body = null;
6294
6295 if (article.getVersion() == 1.0) {
6296 subject = JournalUtil.getEmailArticleAddedSubject(preferences);
6297 body = JournalUtil.getEmailArticleAddedBody(preferences);
6298 }
6299 else {
6300 subject = JournalUtil.getEmailArticleUpdatedSubject(preferences);
6301 body = JournalUtil.getEmailArticleUpdatedBody(preferences);
6302 }
6303
6304 SubscriptionSender subscriptionSender = new SubscriptionSender();
6305
6306 subscriptionSender.setBody(body);
6307 subscriptionSender.setCompanyId(article.getCompanyId());
6308 subscriptionSender.setContextAttributes(
6309 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6310 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6311 articleURL, "[$ARTICLE_VERSION$]", article.getVersion());
6312 subscriptionSender.setContextUserPrefix("ARTICLE");
6313 subscriptionSender.setFrom(fromAddress, fromName);
6314 subscriptionSender.setHtmlFormat(true);
6315 subscriptionSender.setMailId("journal_article", article.getId());
6316 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6317 subscriptionSender.setReplyToAddress(fromAddress);
6318 subscriptionSender.setScopeGroupId(article.getGroupId());
6319 subscriptionSender.setServiceContext(serviceContext);
6320 subscriptionSender.setSubject(subject);
6321 subscriptionSender.setUserId(article.getUserId());
6322
6323 subscriptionSender.addPersistedSubscribers(
6324 JournalArticle.class.getName(), article.getResourcePrimKey());
6325
6326 JournalFolder folder = article.getFolder();
6327
6328 List<Long> folderIds = new ArrayList<Long>();
6329
6330 if (folder != null) {
6331 folderIds.add(folder.getFolderId());
6332
6333 folderIds.addAll(folder.getAncestorFolderIds());
6334 }
6335
6336 for (long curFolderId : folderIds) {
6337 subscriptionSender.addPersistedSubscribers(
6338 JournalFolder.class.getName(), curFolderId);
6339 }
6340
6341 subscriptionSender.addPersistedSubscribers(
6342 JournalArticle.class.getName(), article.getGroupId());
6343
6344 subscriptionSender.flushNotificationsAsync();
6345 }
6346
6347 protected void saveImages(
6348 boolean smallImage, long smallImageId, File smallImageFile,
6349 byte[] smallImageBytes)
6350 throws PortalException, SystemException {
6351
6352 if (smallImage) {
6353 if ((smallImageFile != null) && (smallImageBytes != null)) {
6354 imageLocalService.updateImage(smallImageId, smallImageBytes);
6355 }
6356 }
6357 else {
6358 imageLocalService.deleteImage(smallImageId);
6359 }
6360 }
6361
6362 protected void sendEmail(
6363 JournalArticle article, String articleURL,
6364 PortletPreferences preferences, String emailType,
6365 ServiceContext serviceContext)
6366 throws PortalException, SystemException {
6367
6368 if (preferences == null) {
6369 return;
6370 }
6371 else if (emailType.equals("denied") &&
6372 JournalUtil.getEmailArticleApprovalDeniedEnabled(
6373 preferences)) {
6374 }
6375 else if (emailType.equals("granted") &&
6376 JournalUtil.getEmailArticleApprovalGrantedEnabled(
6377 preferences)) {
6378 }
6379 else if (emailType.equals("requested") &&
6380 JournalUtil.getEmailArticleApprovalRequestedEnabled(
6381 preferences)) {
6382 }
6383 else if (emailType.equals("review") &&
6384 JournalUtil.getEmailArticleReviewEnabled(preferences)) {
6385 }
6386 else {
6387 return;
6388 }
6389
6390 Company company = companyPersistence.findByPrimaryKey(
6391 article.getCompanyId());
6392
6393 User user = userPersistence.findByPrimaryKey(article.getUserId());
6394
6395 String fromName = JournalUtil.getEmailFromName(
6396 preferences, article.getCompanyId());
6397 String fromAddress = JournalUtil.getEmailFromAddress(
6398 preferences, article.getCompanyId());
6399
6400 String toName = user.getFullName();
6401 String toAddress = user.getEmailAddress();
6402
6403 if (emailType.equals("requested")) {
6404 String tempToName = fromName;
6405 String tempToAddress = fromAddress;
6406
6407 fromName = toName;
6408 fromAddress = toAddress;
6409
6410 toName = tempToName;
6411 toAddress = tempToAddress;
6412 }
6413
6414 String subject = null;
6415 String body = null;
6416
6417 if (emailType.equals("denied")) {
6418 subject = JournalUtil.getEmailArticleApprovalDeniedSubject(
6419 preferences);
6420 body = JournalUtil.getEmailArticleApprovalDeniedBody(preferences);
6421 }
6422 else if (emailType.equals("granted")) {
6423 subject = JournalUtil.getEmailArticleApprovalGrantedSubject(
6424 preferences);
6425 body = JournalUtil.getEmailArticleApprovalGrantedBody(preferences);
6426 }
6427 else if (emailType.equals("requested")) {
6428 subject = JournalUtil.getEmailArticleApprovalRequestedSubject(
6429 preferences);
6430 body = JournalUtil.getEmailArticleApprovalRequestedBody(
6431 preferences);
6432 }
6433 else if (emailType.equals("review")) {
6434 subject = JournalUtil.getEmailArticleReviewSubject(preferences);
6435 body = JournalUtil.getEmailArticleReviewBody(preferences);
6436 }
6437
6438 SubscriptionSender subscriptionSender = new SubscriptionSender();
6439
6440 subscriptionSender.setBody(body);
6441 subscriptionSender.setCompanyId(company.getCompanyId());
6442 subscriptionSender.setContextAttributes(
6443 "[$ARTICLE_ID$]", article.getArticleId(), "[$ARTICLE_TITLE$]",
6444 article.getTitle(serviceContext.getLanguageId()), "[$ARTICLE_URL$]",
6445 articleURL, "[$ARTICLE_USER_NAME$]", article.getUserName(),
6446 "[$ARTICLE_VERSION$]", article.getVersion());
6447 subscriptionSender.setContextUserPrefix("ARTICLE");
6448 subscriptionSender.setFrom(fromAddress, fromName);
6449 subscriptionSender.setHtmlFormat(true);
6450 subscriptionSender.setMailId("journal_article", article.getId());
6451 subscriptionSender.setPortletId(PortletKeys.JOURNAL);
6452 subscriptionSender.setScopeGroupId(article.getGroupId());
6453 subscriptionSender.setServiceContext(serviceContext);
6454 subscriptionSender.setSubject(subject);
6455 subscriptionSender.setUserId(article.getUserId());
6456
6457 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
6458
6459 subscriptionSender.flushNotificationsAsync();
6460 }
6461
6462 protected void updateDDMStructureXSD(
6463 long ddmStructureId, String content, ServiceContext serviceContext)
6464 throws PortalException, SystemException {
6465
6466 try {
6467 Document document = SAXReaderUtil.read(content);
6468
6469 Element rootElement = document.getRootElement();
6470
6471 List<Element> elements = rootElement.elements();
6472
6473 for (Element element : elements) {
6474 String fieldName = element.attributeValue(
6475 "name", StringPool.BLANK);
6476
6477 List<Element> dynamicContentElements = element.elements(
6478 "dynamic-content");
6479
6480 for (Element dynamicContentElement : dynamicContentElements) {
6481 String value = dynamicContentElement.getText();
6482
6483 ddmStructureLocalService.updateXSDFieldMetadata(
6484 ddmStructureId, fieldName,
6485 FieldConstants.PREDEFINED_VALUE, value, serviceContext);
6486 }
6487 }
6488 }
6489 catch (DocumentException de) {
6490 throw new SystemException(de);
6491 }
6492 }
6493
6494 protected void updatePreviousApprovedArticle(JournalArticle article)
6495 throws PortalException, SystemException {
6496
6497 List<JournalArticle> approvedArticles =
6498 journalArticlePersistence.findByG_A_ST(
6499 article.getGroupId(), article.getArticleId(),
6500 WorkflowConstants.STATUS_APPROVED, 0, 2);
6501
6502 if (approvedArticles.isEmpty() ||
6503 ((approvedArticles.size() == 1) &&
6504 (article.getStatus() == WorkflowConstants.STATUS_APPROVED))) {
6505
6506 assetEntryLocalService.updateVisible(
6507 JournalArticle.class.getName(), article.getResourcePrimKey(),
6508 false);
6509 }
6510 else {
6511 JournalArticle previousApprovedArticle = approvedArticles.get(0);
6512
6513 if (article.getStatus() == WorkflowConstants.STATUS_APPROVED) {
6514 previousApprovedArticle = approvedArticles.get(1);
6515 }
6516
6517 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
6518 JournalArticle.class.getName(), article.getResourcePrimKey(),
6519 previousApprovedArticle.getDisplayDate(),
6520 previousApprovedArticle.getExpirationDate(), true);
6521
6522 assetEntry.setModifiedDate(
6523 previousApprovedArticle.getModifiedDate());
6524 assetEntry.setTitle(previousApprovedArticle.getTitle());
6525
6526 assetEntryPersistence.update(assetEntry);
6527 }
6528 }
6529
6530 protected void updateUrlTitles(
6531 long groupId, String articleId, String urlTitle)
6532 throws PortalException, SystemException {
6533
6534 JournalArticle firstArticle = journalArticlePersistence.findByG_A_First(
6535 groupId, articleId, new ArticleVersionComparator(false));
6536
6537 if (firstArticle.getUrlTitle().equals(urlTitle)) {
6538 return;
6539 }
6540
6541 List<JournalArticle> articles = journalArticlePersistence.findByG_A(
6542 groupId, articleId);
6543
6544 for (JournalArticle article : articles) {
6545 if (!article.getUrlTitle().equals(urlTitle)) {
6546 article.setUrlTitle(urlTitle);
6547
6548 journalArticlePersistence.update(article);
6549 }
6550 }
6551 }
6552
6553 protected void validate(
6554 long companyId, long groupId, long classNameId,
6555 Map<Locale, String> titleMap, String content, String type,
6556 String ddmStructureKey, String ddmTemplateKey, Date expirationDate,
6557 boolean smallImage, String smallImageURL, File smallImageFile,
6558 byte[] smallImageBytes, ServiceContext serviceContext)
6559 throws PortalException, SystemException {
6560
6561 Locale articleDefaultLocale = LocaleUtil.fromLanguageId(
6562 LocalizationUtil.getDefaultLanguageId(content));
6563
6564 Locale[] availableLocales = LanguageUtil.getAvailableLocales(groupId);
6565
6566 if (!ArrayUtil.contains(availableLocales, articleDefaultLocale)) {
6567 LocaleException le = new LocaleException(
6568 LocaleException.TYPE_CONTENT,
6569 "The locale " + articleDefaultLocale +
6570 " is not available in site with groupId" + groupId);
6571
6572 Locale[] sourceAvailableLocales = {articleDefaultLocale};
6573
6574 le.setSourceAvailableLocales(sourceAvailableLocales);
6575 le.setTargetAvailableLocales(availableLocales);
6576
6577 throw le;
6578 }
6579
6580 if ((classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT) &&
6581 (titleMap.isEmpty() ||
6582 Validator.isNull(titleMap.get(articleDefaultLocale)))) {
6583
6584 throw new ArticleTitleException();
6585 }
6586 else if (Validator.isNull(type)) {
6587 throw new ArticleTypeException();
6588 }
6589
6590 validateContent(content);
6591
6592 if (Validator.isNotNull(ddmStructureKey)) {
6593 DDMStructure ddmStructure = ddmStructureLocalService.getStructure(
6594 PortalUtil.getSiteGroupId(groupId),
6595 PortalUtil.getClassNameId(JournalArticle.class),
6596 ddmStructureKey, true);
6597
6598 validateDDMStructureFields(
6599 ddmStructure, classNameId, serviceContext);
6600
6601 if (Validator.isNotNull(ddmTemplateKey)) {
6602 DDMTemplate ddmTemplate = ddmTemplateLocalService.getTemplate(
6603 PortalUtil.getSiteGroupId(groupId),
6604 PortalUtil.getClassNameId(DDMStructure.class),
6605 ddmTemplateKey, true);
6606
6607 if (ddmTemplate.getClassPK() != ddmStructure.getStructureId()) {
6608 throw new NoSuchTemplateException(
6609 "{templateKey=" + ddmTemplateKey + "}");
6610 }
6611 }
6612 else if (classNameId ==
6613 JournalArticleConstants.CLASSNAME_ID_DEFAULT) {
6614
6615 throw new NoSuchTemplateException();
6616 }
6617 }
6618
6619 if ((expirationDate != null) && expirationDate.before(new Date()) &&
6620 !ExportImportThreadLocal.isImportInProcess()) {
6621
6622 throw new ArticleExpirationDateException();
6623 }
6624
6625 String[] imageExtensions = PrefsPropsUtil.getStringArray(
6626 PropsKeys.JOURNAL_IMAGE_EXTENSIONS, StringPool.COMMA);
6627
6628 if (!smallImage || Validator.isNotNull(smallImageURL) ||
6629 (smallImageFile == null) || (smallImageBytes == null)) {
6630
6631 return;
6632 }
6633
6634 String smallImageName = smallImageFile.getName();
6635
6636 if (smallImageName != null) {
6637 boolean validSmallImageExtension = false;
6638
6639 for (String _imageExtension : imageExtensions) {
6640 if (StringPool.STAR.equals(_imageExtension) ||
6641 StringUtil.endsWith(smallImageName, _imageExtension)) {
6642
6643 validSmallImageExtension = true;
6644
6645 break;
6646 }
6647 }
6648
6649 if (!validSmallImageExtension) {
6650 throw new ArticleSmallImageNameException(smallImageName);
6651 }
6652 }
6653
6654 long smallImageMaxSize = PrefsPropsUtil.getLong(
6655 PropsKeys.JOURNAL_IMAGE_SMALL_MAX_SIZE);
6656
6657 if ((smallImageMaxSize > 0) &&
6658 ((smallImageBytes == null) ||
6659 (smallImageBytes.length > smallImageMaxSize))) {
6660
6661 throw new ArticleSmallImageSizeException();
6662 }
6663 }
6664
6665 protected void validate(
6666 long companyId, long groupId, long classNameId, String articleId,
6667 boolean autoArticleId, double version, Map<Locale, String> titleMap,
6668 String content, String type, String ddmStructureKey,
6669 String ddmTemplateKey, Date expirationDate, boolean smallImage,
6670 String smallImageURL, File smallImageFile, byte[] smallImageBytes,
6671 ServiceContext serviceContext)
6672 throws PortalException, SystemException {
6673
6674 if (!autoArticleId) {
6675 validate(articleId);
6676 }
6677
6678 JournalArticle article = journalArticlePersistence.fetchByG_A_V(
6679 groupId, articleId, version);
6680
6681 if (article != null) {
6682 StringBundler sb = new StringBundler(7);
6683
6684 sb.append("{groupId=");
6685 sb.append(groupId);
6686 sb.append(", articleId=");
6687 sb.append(articleId);
6688 sb.append(", version=");
6689 sb.append(version);
6690 sb.append("}");
6691
6692 throw new DuplicateArticleIdException(sb.toString());
6693 }
6694
6695 validate(
6696 companyId, groupId, classNameId, titleMap, content, type,
6697 ddmStructureKey, ddmTemplateKey, expirationDate, smallImage,
6698 smallImageURL, smallImageFile, smallImageBytes, serviceContext);
6699 }
6700
6701 protected void validate(String articleId) throws PortalException {
6702 if (Validator.isNull(articleId) ||
6703 (articleId.indexOf(CharPool.COMMA) != -1) ||
6704 (articleId.indexOf(CharPool.SPACE) != -1)) {
6705
6706 throw new ArticleIdException();
6707 }
6708 }
6709
6710 protected void validateContent(String content) throws PortalException {
6711 if (Validator.isNull(content)) {
6712 throw new ArticleContentException("Content is null");
6713 }
6714
6715 try {
6716 SAXReaderUtil.read(content);
6717 }
6718 catch (DocumentException de) {
6719 if (_log.isDebugEnabled()) {
6720 _log.debug("Invalid content:\n" + content);
6721 }
6722
6723 throw new ArticleContentException(
6724 "Unable to read content with an XML parser", de);
6725 }
6726 }
6727
6728 protected void validateDDMStructureFields(
6729 DDMStructure ddmStructure, long classNameId,
6730 ServiceContext serviceContext)
6731 throws PortalException, SystemException {
6732
6733 Fields fields = DDMUtil.getFields(
6734 ddmStructure.getStructureId(), serviceContext);
6735
6736 for (com.liferay.portlet.dynamicdatamapping.storage.Field field :
6737 fields) {
6738
6739 if (!ddmStructure.hasField(field.getName())) {
6740 throw new StorageFieldNameException();
6741 }
6742
6743 if (ddmStructure.getFieldRequired(field.getName()) &&
6744 Validator.isNull(field.getValue()) &&
6745 (classNameId == JournalArticleConstants.CLASSNAME_ID_DEFAULT)) {
6746
6747 throw new StorageFieldRequiredException();
6748 }
6749 }
6750 }
6751
6752 private static final long _JOURNAL_ARTICLE_CHECK_INTERVAL =
6753 PropsValues.JOURNAL_ARTICLE_CHECK_INTERVAL * Time.MINUTE;
6754
6755 private static Log _log = LogFactoryUtil.getLog(
6756 JournalArticleLocalServiceImpl.class);
6757
6758 private Date _previousCheckDate;
6759
6760 }