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